import { useMemo, useState } from 'react';
import { useContentCatalogPayload } from '@/business/content-catalog/hooks';
import type {
  PersonalityQuizFeature,
  PersonalityQuizResultTab,
  PersonalityQuizWorkflowInput,
} from '@/business/personality/types';
import {
  calculatePersonalityQuizProgress,
  formatPersonalitySavedDate,
  getPersonalityCommunicationGrowthArea,
  getPersonalityCommunicationStrengths,
  getPersonalityDimensionProgress,
  getPersonalityRelationshipTips,
  getPersonalityTypeBreakdown,
} from '@/business/personality/selectors';
import {
  calculateMBTI,
  getPersonalityType,
} from '@/shared/constants/personalityCatalog';
import type { PersonalityType, QuizQuestion } from '@/shared/constants/personalityCatalog';
import { CONTENT_CATALOG_TYPES } from '@/shared/constants/contentCatalog';
import { getFirstQueryError, isAnyLoading } from '@/shared/business/queryState';

export function usePersonalityQuizWorkflow({
  onResult,
  savedType,
  savedAnswers,
}: PersonalityQuizWorkflowInput) {
  const questionsQuery = useContentCatalogPayload<readonly QuizQuestion[]>(
    CONTENT_CATALOG_TYPES.personalityQuizQuestions,
    [],
  );
  const personalityTypesQuery = useContentCatalogPayload<readonly PersonalityType[]>(
    CONTENT_CATALOG_TYPES.personalityTypes,
    [],
  );
  const featuresQuery = useContentCatalogPayload<readonly PersonalityQuizFeature[]>(
    CONTENT_CATALOG_TYPES.personalityQuizFeatures,
    [],
  );
  const [started, setStarted] = useState(false);
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const [answers, setAnswers] = useState<Record<number, string>>({});
  const [resultCode, setResultCode] = useState<string | null>(null);
  const [showResult, setShowResult] = useState(false);
  const [selectedAnswer, setSelectedAnswer] = useState<string | null>(null);
  const [activeResultTab, setActiveResultTab] = useState<PersonalityQuizResultTab>('overview');
  const [showSavedResult, setShowSavedResult] = useState(false);

  const questions = questionsQuery.payload;
  const personalityTypes = personalityTypesQuery.payload;
  const totalQuestions = questions.length;
  const currentQuestion = questions[currentQuestionIndex];
  const savedResult = savedType ? getPersonalityType(savedType, personalityTypes) ?? null : null;
  const effectiveResultCode = resultCode ?? (!started ? savedResult?.code ?? null : null);
  const effectiveAnswers = useMemo(
    () => (Object.keys(answers).length > 0 ? answers : savedAnswers ?? {}),
    [answers, savedAnswers],
  );
  const effectiveShowSavedResult = showSavedResult || (!started && Boolean(savedResult));
  const effectiveShowResult = showResult || (!started && Boolean(savedResult));
  const result = effectiveResultCode ? getPersonalityType(effectiveResultCode, personalityTypes) ?? null : null;
  const progress = totalQuestions > 0 ? calculatePersonalityQuizProgress(currentQuestionIndex, totalQuestions) : 0;
  const features = featuresQuery.payload;
  const dimensionProgress = useMemo(
    () => currentQuestion ? getPersonalityDimensionProgress(currentQuestion, effectiveAnswers, questions) : [],
    [effectiveAnswers, currentQuestion, questions],
  );
  const typeBreakdown = useMemo(
    () => (result ? getPersonalityTypeBreakdown(result) : []),
    [result],
  );
  const relationshipTips = useMemo(
    () => (result ? getPersonalityRelationshipTips(result) : []),
    [result],
  );
  const communicationStrengths = useMemo(
    () => (result ? getPersonalityCommunicationStrengths(result) : []),
    [result],
  );
  const communicationGrowthArea = result ? getPersonalityCommunicationGrowthArea(result) : '';
  const contentQueries = [questionsQuery, personalityTypesQuery, featuresQuery];

  const handleSelectAnswer = (value: string) => {
    setSelectedAnswer(value);
  };

  const handleNext = () => {
    if (!selectedAnswer || !currentQuestion) {
      return;
    }

    const nextAnswers = { ...answers, [currentQuestion.id]: selectedAnswer };
    setAnswers(nextAnswers);
    setSelectedAnswer(null);

    if (currentQuestionIndex < totalQuestions - 1) {
      setCurrentQuestionIndex((index) => index + 1);
      return;
    }

    const code = calculateMBTI(nextAnswers, questions);
    setResultCode(code);
    setShowResult(true);
    setShowSavedResult(false);
    void onResult?.(code, nextAnswers);
  };

  const handleBack = () => {
    if (currentQuestionIndex === 0) {
      return;
    }

    const previousQuestion = questions[currentQuestionIndex - 1];
    setCurrentQuestionIndex((index) => index - 1);
    setSelectedAnswer(answers[previousQuestion.id] || null);
  };

  const resetQuiz = () => {
    setStarted(true);
    setCurrentQuestionIndex(0);
    setAnswers({});
    setResultCode(null);
    setShowResult(false);
    setSelectedAnswer(null);
    setActiveResultTab('overview');
    setShowSavedResult(false);
  };

  return {
    started,
    currentQuestionIndex,
    answers: effectiveAnswers,
    result,
    showResult: effectiveShowResult,
    selectedAnswer,
    activeResultTab,
    showSavedResult: effectiveShowSavedResult,
    questions,
    personalityTypes,
    totalQuestions,
    currentQuestion,
    isContentLoading: isAnyLoading(...contentQueries),
    contentError: getFirstQueryError(...contentQueries),
    progress,
    features,
    dimensionProgress,
    typeBreakdown,
    relationshipTips,
    communicationStrengths,
    communicationGrowthArea,
    formatSavedDate: formatPersonalitySavedDate,
    setStarted,
    setActiveResultTab,
    handleSelectAnswer,
    handleNext,
    handleBack,
    resetQuiz,
  };
}
