import {ReactNode, useState} from 'react';
import {LayoutChangeEvent, ScrollView, View} from 'react-native';
import {useTranslation} from 'react-i18next';
import {
  HtmlRender,
  Accordion,
  Button,
  CardContainer,
  Divider,
  FileCard,
  Spinner,
  Title,
  Image,
  ButtonProps,
} from '@components';
import {Language} from '@config/i18n';
import {useSafeAreaBottomPadding} from '@hooks/useSafeAreaBottomPadding';
import {useHtmlTagStyles} from '@hooks/useHtmlTagStyles';
import {ProgressStatus} from '@modules/employeeLifecycle/interfaces';
import {useUser} from '@redux/selectors';
import {useTheme} from '@shared/theme';
import {getFormattedDate, getHtmlToRender, sizeToBytes} from '@shared/utils';

import {AccordionItem} from './components/AccordionItem';
import {MoreInfoDialog} from './components/MoreInfoDialog';
import {useBaseTaskDetailHeader} from './hooks/useBaseTaskDetailHeader';
import {styles} from './styles';
import {getExpiredPillProps} from './utils';
import {TaskDetailProps} from '../../interfaces';

export interface BaseTaskDetailProps extends Omit<TaskDetailProps, 'source'> {
  pendingAction: ButtonProps;
  completedAction?: ButtonProps;
  children?: ReactNode;
}

/**
 * This component is used to display the details of a task.
 * It is used as base for:
 * - CustomTaskDetail
 * - DocumentTaskDetail
 * - FormTaskDetail
 * - SurveyTaskDetail
 */
export function BaseTaskDetail({
  task: journeyTask,
  canShowMoreInfoDialog = false,
  pendingAction,
  completedAction,
  isUpdatingTask,
  children,
}: BaseTaskDetailProps) {
  const {theme, spacing} = useTheme();
  const {language} = useUser();
  const {t} = useTranslation();
  const [cardWidth, setCardWidth] = useState<number | undefined>(undefined);
  const [showDialog, setShowDialog] = useState(false);
  const paddingBottom = useSafeAreaBottomPadding();
  const isCompleted = journeyTask.status === ProgressStatus.DONE;
  const tagStyles = useHtmlTagStyles('webLike');

  const htmlContent = getHtmlToRender(journeyTask.task.description);

  const onCardContainerLayout = (e: LayoutChangeEvent) => {
    // Since react native uses box-sizing: border-box, we need to subtract the padding
    // from the width to get the actual width of the content
    const horizontalPadding = spacing.x2 * 2;
    setCardWidth(e.nativeEvent.layout.width - horizontalPadding);
  };

  const onOpenDialog = () => setShowDialog(true);
  const onCloseDialog = () => setShowDialog(false);

  useBaseTaskDetailHeader({
    task: journeyTask,
    canShowMoreInfoDialog,
    onOpenDialog,
  });

  const expiredPillProps = getExpiredPillProps(journeyTask, isCompleted, t);
  const action = isCompleted ? completedAction : pendingAction;

  return (
    <>
      <ScrollView
        showsVerticalScrollIndicator={false}
        bounces={false}
        contentContainerStyle={[
          styles.contentContainer,
          {backgroundColor: theme.background.layout.default},
        ]}>
        {journeyTask.task.coverImage && (
          <Image
            style={styles.coverImage}
            source={{uri: journeyTask.task.coverImage.url}}
            withAuthHeader
          />
        )}
        <View style={styles.container}>
          <Accordion initialCollapsed>
            <Accordion.Header>
              <Accordion.Title
                title={t('employee_lifecycle.custom_task_detail.details')}
              />
              <Accordion.Icon />
            </Accordion.Header>
            <Accordion.Content>
              <AccordionItem
                title={t('employee_lifecycle.custom_task_detail.status')}
                pill={{
                  text: t(
                    `employee_lifecycle.custom_task_detail.${
                      isCompleted ? 'completed' : 'pending'
                    }`,
                  ),
                  variant: isCompleted ? 'success' : 'warning',
                }}
              />
              {journeyTask.expiresAfter && (
                <>
                  <Divider />
                  <AccordionItem
                    title={t('employee_lifecycle.custom_task_detail.due_date')}
                    pill={expiredPillProps}
                    value={getFormattedDate(
                      journeyTask.expiresAfter,
                      language === Language.En ? 'MM/dd/yy' : 'dd/MM/yy',
                    )}
                  />
                </>
              )}
            </Accordion.Content>
          </Accordion>
          <Title
            title={t('employee_lifecycle.custom_task_detail.description')}
            style={styles.descriptionTitle}
          />
          <CardContainer onLayout={onCardContainerLayout}>
            <HtmlRender
              html={htmlContent}
              contentWidth={cardWidth}
              tagsStyles={tagStyles}
              hasCustomVideoControl
              resizeAndAlignMultimedia
            />
          </CardContainer>
          {!!journeyTask.task.attachments.length && (
            <>
              <Title
                title={t(
                  'employee_lifecycle.custom_task_detail.attached_files',
                )}
              />
              {journeyTask.task.attachments.map(file => (
                <FileCard
                  key={file.url}
                  id={file.url}
                  name={file.name}
                  size={sizeToBytes(file.size)}
                  url={file.url}
                  path={file.url}
                  downloadWithAuthHeader
                  hasAvatar={false}
                />
              ))}
            </>
          )}
        </View>
        {children}
        <View
          style={[
            styles.footer,
            {paddingBottom, backgroundColor: theme.background.layout.tertiary},
          ]}>
          {isUpdatingTask ? (
            <View style={styles.spinnerContainer}>
              <Spinner />
            </View>
          ) : (
            !!action && (
              <Button
                {...action}
                variant={
                  action.variant ?? (isCompleted ? 'secondary' : 'primary')
                }
              />
            )
          )}
        </View>
      </ScrollView>
      {canShowMoreInfoDialog && (
        <MoreInfoDialog
          isVisible={showDialog}
          onPressClose={onCloseDialog}
          assignedTo={journeyTask.taskAssignee.toString()}
          userJourney={journeyTask.actionId.toString()}
          // TODO: Get this data from the API
          stepName="Día 1 de onboarding"
          stepPosition={1}
          totalSteps={8}
        />
      )}
    </>
  );
}
