import { useCallback, useEffect, useRef, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useLocation, useNavigate, useParams } from 'react-router';

import Container from '@material-hu/mui/Container';
import Stack from '@material-hu/mui/Stack';

import TaskFocusHeader from '@material-hu/components/design-system/Header/TaskFocus';
import { Title } from '@material-hu/components/design-system/Title';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import {
  type FormAttributes,
  InputType,
  type Question,
  type Step,
} from 'src/types/forms';
import {
  buildCheckboxGridAnswer,
  getDayMonthYear,
  getMonthDayYear,
  getMonthYear,
  getQuestionName,
} from 'src/utils/form';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { FormFileUploadProvider } from '../forms/FormFileUploadContext';

import CompletedSurveyInfoSidebar from './components/CompletedSurveyInfoSidebar';
import Footer from './components/Footer';
import InputFieldWrapper from './components/inputs/InputFieldWrapper';
import SurveyCompletionSkeleton from './components/SurveyCompletionSkeleton';
import useSurveyCompletionAndEdit from './hooks/useSurveyCompletionAndEdit';
import { surveysRoutes } from './routes';

const buildDefaultValues = (steps: Step[]): Record<string, unknown> => {
  const defaults: Record<string, unknown> = {};

  steps.forEach((step, stepIndex) => {
    step.questions?.forEach((question: Question, questionIndex: number) => {
      const fieldName = `${stepIndex}-${questionIndex}-${getQuestionName(question)}-${step.id}`;
      const { answer } = question;

      if (answer == null || (Array.isArray(answer) && answer.length === 0)) {
        return;
      }

      defaults[fieldName] = resolveAnswerValue(question);
    });
  });

  return defaults;
};

const resolveAnswerValue = (question: Question): unknown => {
  const { answer, inputType } = question;
  const rawValue = Array.isArray(answer) ? answer[0] : answer;

  switch (inputType) {
    case InputType.TEXT:
    case InputType.TEXT_AREA:
    case InputType.INTEGER:
    case InputType.PHONE:
      return rawValue ?? '';

    case InputType.DECIMAL:
    case InputType.FLOAT:
      return rawValue?.toString() ?? '';

    case InputType.DATE:
      return rawValue ? getDayMonthYear(rawValue) : null;

    case InputType.DATE_MMAAAA:
      return rawValue ? getMonthYear(rawValue) : null;

    case InputType.DATE_MMDDYYYY:
      return rawValue ? getMonthDayYear(rawValue) : null;

    case InputType.TIME:
      return rawValue ? new Date(`1970-01-01 ${rawValue}`) : null;

    case InputType.STAR_RATING:
    case InputType.RATE:
      return rawValue ?? null;

    case InputType.DROPDOWN: {
      if (typeof rawValue === 'object' && rawValue?.description != null) {
        const idx = question.options?.findIndex(
          o => o.description === rawValue.description,
        );
        if (idx !== undefined && idx >= 0) {
          return { value: idx, label: rawValue.description };
        }
        return { value: rawValue.description, label: rawValue.description };
      }
      return null;
    }

    case InputType.CHECKBOX:
    case InputType.MULTIPLE_CHOICE: {
      if (!Array.isArray(answer)) return null;
      const checkedIndices = answer
        .filter(a => a.checked)
        .map(a => {
          const idx = question.options?.findIndex(
            o => o.description === a.description,
          );
          return idx !== undefined && idx >= 0 ? idx : null;
        })
        .filter((v): v is number => v !== null);
      if (!checkedIndices.length) return null;
      return question.multipleAnswer ? checkedIndices : checkedIndices[0];
    }

    case InputType.CHECKBOX_GRID:
      return buildCheckboxGridAnswer(question);

    case InputType.MEDIA: {
      const answerObj = question.answer as unknown as Record<string, unknown>;
      const mediaAttachments =
        (answerObj?.attachments as unknown[]) ?? (answer as unknown[]);
      if (!mediaAttachments) return null;
      const images: unknown[] = [];
      const videos: unknown[] = [];
      for (const media of mediaAttachments) {
        if ((media as { type: string }).type === 'IMAGE') {
          images.push(media);
        } else {
          videos.push(media);
        }
      }
      return { images, videos };
    }

    case InputType.FILE: {
      const fileObj = question.answer as unknown as Record<string, unknown>;
      return (fileObj?.attachments as unknown[]) ?? null;
    }

    case InputType.DIGITAL_SIGN: {
      const signObj = question.answer as unknown as Record<string, unknown>;
      const signAttachments = signObj?.attachments as
        | { url: string; type: string }[]
        | undefined;
      const firstSign = signAttachments?.[0];
      if (!firstSign) return null;
      return { url: firstSign.url, type: firstSign.type };
    }

    case InputType.AUTOCOMPLETE:
      return rawValue ?? '';

    default:
      return rawValue ?? null;
  }
};

const CompletedSurveyDetail = () => {
  const { templateId, answerId } = useParams();
  const navigate = useNavigate();
  const location = useLocation();
  const HugoThemeProvider = useHuGoTheme();
  const { t } = useLokaliseTranslation(['forms', 'surveys']);

  const form = useForm({});

  const { isLoadingAnswer, answerInfo } = useSurveyCompletionAndEdit({
    id: undefined,
    templateId,
    answerId,
  });

  const [currentStep, setCurrentStep] = useState(0);
  const [isFormReady, setIsFormReady] = useState(false);
  const scrollableRef = useRef<HTMLDivElement>(null);

  const formDetailData = answerInfo?.data as FormAttributes | undefined;
  const stepsCount = formDetailData?.steps?.length ?? 0;

  useEffect(() => {
    if (formDetailData?.steps && !isFormReady) {
      const defaults = buildDefaultValues(formDetailData.steps);
      form.reset(defaults);
      setIsFormReady(true);
    }
  }, [formDetailData, form, isFormReady]);

  // biome-ignore lint/correctness/useExhaustiveDependencies: scroll on step change
  useEffect(() => {
    scrollableRef.current?.scrollTo({ top: 0, behavior: 'instant' });
  }, [currentStep]);

  const currentSection = formDetailData?.steps?.[currentStep];
  const isLastStep = currentStep + 1 === stepsCount;
  const isBackDisabled = currentStep === 0;
  const isNextDisabled = isLastStep;

  const handleNextSection = useCallback(() => {
    if (!isLastStep) setCurrentStep(prev => prev + 1);
  }, [isLastStep]);

  const handleBackSection = useCallback(() => {
    setCurrentStep(prev => prev - 1);
  }, []);

  const handleClose = useCallback(() => {
    if (location.key === 'default') {
      navigate(surveysRoutes.base(), { replace: true });
    } else {
      navigate(-1);
    }
  }, [navigate, location.key]);

  const showFooter = isFormReady && stepsCount > 1;

  return (
    <HugoThemeProvider>
      <FormFileUploadProvider>
        <FormProvider {...form}>
          <Stack sx={{ width: 1, height: '100vh' }}>
            <TaskFocusHeader
              title={formDetailData?.title ?? ''}
              onClose={handleClose}
              loading={isLoadingAnswer}
              pillLabel={t('surveys:survey_list_row.completed_pill')}
              slotProps={{
                root: { sx: { flexShrink: 0 } },
                pill: { type: 'highlight', hasIcon: false },
              }}
            />
            <Stack
              sx={{
                flex: 1,
                flexDirection: 'row',
                overflow: 'hidden',
              }}
            >
              <Stack
                ref={scrollableRef}
                sx={{
                  flex: 1,
                  overflow: 'auto',
                  backgroundColor: ({ palette }) =>
                    palette?.new.background.layout.default,
                }}
              >
                <Container
                  maxWidth="lg"
                  sx={{ pb: 4, pt: 8 }}
                >
                  {(isLoadingAnswer || !isFormReady) && (
                    <SurveyCompletionSkeleton />
                  )}
                  {isFormReady && currentSection && (
                    <Stack sx={{ gap: 3 }}>
                      <Title
                        variant="L"
                        title={currentSection.title}
                      />
                      {currentSection.questions?.map((question, index) => (
                        <InputFieldWrapper
                          key={`${currentStep}-${index}-${getQuestionName(question)}`}
                          name={`${currentStep}-${index}-${getQuestionName(question)}-${currentSection.id}`}
                          question={question}
                          formFilled
                        />
                      ))}
                    </Stack>
                  )}
                </Container>
              </Stack>
              {formDetailData && (
                <CompletedSurveyInfoSidebar formData={formDetailData} />
              )}
            </Stack>
            {showFooter && (
              <Footer
                isLastStep={isLastStep}
                onNextSection={handleNextSection}
                onGoBackSection={handleBackSection}
                isNextSectionDisabled={isNextDisabled}
                showBack={!isBackDisabled}
                showNext={!isLastStep}
                sidebarSpacer
              />
            )}
          </Stack>
        </FormProvider>
      </FormFileUploadProvider>
    </HugoThemeProvider>
  );
};

export default CompletedSurveyDetail;
