import { type BaseSyntheticEvent, useCallback, useMemo, useRef } from 'react';
import { type UseFormReturn, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';

import { zodResolver } from '@hookform/resolvers/zod';

import {
  type CalibrationReviewDetail,
  type ReviewDetailFormQuestions,
} from 'src/pages/dashboard/performance/types';
import { type LokaliseTFunction } from 'src/utils/i18n';

import { performanceRoutes } from '../../../routes';
import { splitReviewInputs } from '../../../utils';
import useFillCalibration from '../../hooks/useFillCalibration';
import { createCalibrationFormSchema } from '../schemas';
import { type CalibrationBuckets, type CalibrationFormValues } from '../types';
import {
  buildFillCalibrationAnswers,
  getDefaultValues,
  toReviewQuestion,
} from '../utils';

type CalibrationFormInfo = CalibrationReviewDetail['calibrationReview']['form'];

type UseCalibrationFormStateParams = {
  cycleId: string | number;
  formReviewId: number;
  form: CalibrationFormInfo;
  t: LokaliseTFunction;
};

type UseCalibrationFormStateResult = {
  methods: UseFormReturn<CalibrationFormValues>;
  onFormSubmit: (event?: BaseSyntheticEvent) => Promise<void>;
  isSubmitting: boolean;
  isValid: boolean;
  buckets: CalibrationBuckets;
};

/**
 * Owns the react-hook-form lifecycle for a calibration form: builds the schema
 * and default values from the API payload, wires up the fill mutation, and
 * exposes a memoized submit handler ready to plug into `<form onSubmit>`.
 */
export const useCalibrationFormState = ({
  cycleId,
  formReviewId,
  form,
  t,
}: UseCalibrationFormStateParams): UseCalibrationFormStateResult => {
  const navigate = useNavigate();
  const mountedAtRef = useRef(Date.now());

  const rawQuestions = useMemo(() => form?.questions ?? [], [form]);

  const reviewQuestions = useMemo<ReviewDetailFormQuestions[]>(
    () => rawQuestions.map(toReviewQuestion),
    [rawQuestions],
  );

  const buckets = useMemo(
    () => splitReviewInputs(reviewQuestions),
    [reviewQuestions],
  );

  const defaultValues = useMemo(
    () => getDefaultValues(rawQuestions),
    [rawQuestions],
  );

  const schema = useMemo(
    () => createCalibrationFormSchema(rawQuestions, t),
    [rawQuestions, t],
  );

  const methods = useForm<CalibrationFormValues>({
    defaultValues,
    resolver: zodResolver(schema),
    mode: 'onSubmit',
  });
  const {
    handleSubmit,
    formState: { isValid },
  } = methods;

  const handleSubmitSuccess = useCallback(
    () => navigate(performanceRoutes.review.detail(Number(cycleId))),
    [cycleId, navigate],
  );

  const { mutate: submit, isLoading: isSubmitting } = useFillCalibration({
    cycleId,
    formReviewId,
    onSuccess: handleSubmitSuccess,
  });

  const onSubmit = useCallback(
    (values: CalibrationFormValues) => {
      const questionAnswers = buildFillCalibrationAnswers(
        values,
        reviewQuestions,
      );
      const fillingTime = Date.now() - mountedAtRef.current;
      submit({ fillingTime, questionAnswers });
    },
    [reviewQuestions, submit],
  );

  const onFormSubmit = useMemo(
    () => handleSubmit(onSubmit),
    [handleSubmit, onSubmit],
  );

  return { methods, onFormSubmit, isSubmitting, isValid, buckets };
};
