import { useMemo, useState } from 'react';
import { useContentCatalogPayload } from '@/business/content-catalog/hooks';
import {
  useCurrentPersonalityResult,
  usePersonalityCompletion,
  usePersonalityDistribution,
  useSaveCurrentPersonalityResult,
} from '@/business/personality/queryHooks';
import {
  getEmotionalIntelligenceLevel,
  getPersonalityGroup,
  groupPersonalityDistribution,
  totalPersonalityDistribution,
} from '@/business/personality/selectors';
import { canPersistPersonalScopeResults } from '@/business/scope/selectors';
import { CONTENT_CATALOG_TYPES } from '@/shared/constants/contentCatalog';
import { PERSONALITY_QUIZ_KINDS } from '@/shared/constants/personality';
import {
  PERSONALITY_TYPES,
  PERSONALITY_WORKPLACE_CONTENT,
} from '@/shared/constants/personalityStaticContent';
import type { UserRole } from '@/shared/types/app';
import type {
  EmotionalIntelligenceQuestion,
  EmotionalIntelligencePersonalityQuizContent,
  EmotionalIntelligenceTab,
  EmotionalIntelligenceTopic,
  EmotionalIntelligenceWeeklyFocus,
  TeamWellnessMetric,
} from '@/shared/types/emotionalIntelligence';
import type { PersonalityDistributionDto } from '@/shared/types/personality';
import { getOptionalErrorMessage } from '@/shared/errors/errorMessages';
import { getFirstQueryError, isAnyLoading } from '@/shared/business/queryState';
import { useScopeContext } from '@/shared/app/scope-context';
import { usePermissions } from '@/shared/app/usePermissions';

const EMPTY_PERSONALITY_DISTRIBUTION: readonly PersonalityDistributionDto[] = [];

export function useEmotionalIntelligencePage(_userRole: UserRole) {
  const permissions = usePermissions();
  const { ownTenant, selectedTenant } = useScopeContext();
  const activeTenant = selectedTenant ?? ownTenant;
  const canPersistPersonalResults = canPersistPersonalScopeResults(ownTenant, selectedTenant);
  const canManageQuizContent = permissions.has('MANAGE_CONTENT_CATALOG')
    && ownTenant?.level === 'organization'
    && activeTenant?.level === 'organization';
  const canViewPersonalityDistribution = permissions.has('READ_PERSONALITY_REPORTS');
  const assessmentQuestionsQuery = useContentCatalogPayload<readonly EmotionalIntelligenceQuestion[]>(
    CONTENT_CATALOG_TYPES.emotionalIntelligenceAssessmentQuestions,
    [],
  );
  const personalityQuizQuery = useContentCatalogPayload<EmotionalIntelligencePersonalityQuizContent | null>(
    CONTENT_CATALOG_TYPES.emotionalIntelligencePersonalityQuiz,
    null,
  );
  const weeklyTopicsQuery = useContentCatalogPayload<readonly EmotionalIntelligenceTopic[]>(
    CONTENT_CATALOG_TYPES.emotionalIntelligenceWeeklyTopics,
    [],
  );
  const growthTipsQuery = useContentCatalogPayload<readonly string[]>(
    CONTENT_CATALOG_TYPES.emotionalIntelligenceGrowthTips,
    [],
  );
  const teamWellnessMetricsQuery = useContentCatalogPayload<readonly TeamWellnessMetric[]>(
    CONTENT_CATALOG_TYPES.emotionalIntelligenceTeamWellnessMetrics,
    [],
  );
  const weeklyFocusQuery = useContentCatalogPayload<EmotionalIntelligenceWeeklyFocus | null>(
    CONTENT_CATALOG_TYPES.emotionalIntelligenceWeeklyFocus,
    null,
  );
  const [activeTab, setActiveTab] = useState<EmotionalIntelligenceTab>('assessment');
  const [assessmentStarted, setAssessmentStarted] = useState(false);
  const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
  const [answers, setAnswers] = useState<readonly number[]>([]);
  const [assessmentComplete, setAssessmentComplete] = useState(false);

  const currentSelfAssessmentQuery = useCurrentPersonalityResult(
    PERSONALITY_QUIZ_KINDS.selfAssessment,
    canPersistPersonalResults,
  );
  const currentPersonalityQuery = useCurrentPersonalityResult(
    PERSONALITY_QUIZ_KINDS.personalityType,
    canPersistPersonalResults,
  );
  const savePersonalityMutation = useSaveCurrentPersonalityResult();
  const personalityDistributionQuery = usePersonalityDistribution(undefined, canViewPersonalityDistribution);
  const personalityCompletionQuery = usePersonalityCompletion(canViewPersonalityDistribution);

  const savedSelfAssessment = currentSelfAssessmentQuery.data;
  const savedPersonality = currentPersonalityQuery.data;
  const personalityResult = savedPersonality?.personalityType ?? null;
  const savedAnswers = savedPersonality?.quizAnswers
    ? Object.entries(savedPersonality.quizAnswers).reduce<Record<number, string>>((result, [key, value]) => {
        if (typeof value === 'string') {
          result[Number(key)] = value;
        }
        return result;
      }, {})
    : null;
  const savedDate = savedPersonality?.updatedAt ?? null;
  const selfAssessmentResult = savedSelfAssessment
    ? {
        score: savedSelfAssessment.score,
        totalQuestions: savedSelfAssessment.totalQuestions,
        resultLabel: savedSelfAssessment.resultLabel,
        updatedAt: savedSelfAssessment.updatedAt,
      }
    : null;
  const distribution = personalityDistributionQuery.data ?? EMPTY_PERSONALITY_DISTRIBUTION;
  const distributionTotal = totalPersonalityDistribution(distribution);
  const groupDistribution = useMemo(
    () => groupPersonalityDistribution(distribution, getPersonalityGroup),
    [distribution],
  );
  const totalScore = answers.reduce((sum, score) => sum + score, 0);
  const assessmentQuestions = assessmentQuestionsQuery.payload;
  const maxScore = assessmentQuestions.length * 4;
  const percentage = maxScore > 0 ? Math.round((totalScore / maxScore) * 100) : 0;
  const assessmentLevel = getEmotionalIntelligenceLevel(percentage);
  const personalityError = currentSelfAssessmentQuery.error
    ?? currentPersonalityQuery.error
    ?? savePersonalityMutation.error;
  const distributionError = personalityDistributionQuery.error;
  const contentQueries = [
    assessmentQuestionsQuery,
    personalityQuizQuery,
    weeklyTopicsQuery,
    growthTipsQuery,
    teamWellnessMetricsQuery,
    weeklyFocusQuery,
  ];

  const handleAnswer = (scoreIndex: number) => {
    const question = assessmentQuestions[currentQuestionIndex];
    if (!question) {
      return;
    }
    const nextAnswers = [...answers, question.scores[scoreIndex]];
    setAnswers(nextAnswers);

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

    setAssessmentComplete(true);
    if (canPersistPersonalResults) {
      const nextTotalScore = nextAnswers.reduce((sum, score) => sum + score, 0);
      const nextMaxScore = assessmentQuestions.length * 4;
      const nextPercentage = nextMaxScore > 0 ? Math.round((nextTotalScore / nextMaxScore) * 100) : 0;
      const nextLevel = getEmotionalIntelligenceLevel(nextPercentage);
      const quizAnswers = nextAnswers.reduce<Record<number, number>>((result, score, index) => {
        result[index + 1] = score;
        return result;
      }, {});

      void savePersonalityMutation.mutateAsync({
        quizKind: PERSONALITY_QUIZ_KINDS.selfAssessment,
        quizId: 'ei-self-assessment',
        quizTitle: 'EI Self-Assessment',
        quizAnswers,
        score: nextTotalScore,
        totalQuestions: assessmentQuestions.length,
        resultLabel: nextLevel.label,
        resultPayload: {
          percentage: nextPercentage,
          maxScore: nextMaxScore,
        },
      });
    }
  };

  const resetAssessment = () => {
    setAssessmentStarted(false);
    setCurrentQuestionIndex(0);
    setAnswers([]);
    setAssessmentComplete(false);
  };

  const handlePersonalityResult = async (code: string, quizAnswers: Record<number, string>) => {
    if (!canPersistPersonalResults) {
      return;
    }

    await savePersonalityMutation.mutateAsync({
      quizKind: PERSONALITY_QUIZ_KINDS.personalityType,
      quizId: personalityQuizQuery.payload?.id ?? 'personality-type',
      quizTitle: personalityQuizQuery.payload?.title ?? 'Personality Type Quiz',
      personalityType: code,
      quizAnswers,
      totalQuestions: personalityQuizQuery.payload?.questions.length ?? Object.keys(quizAnswers).length,
      resultLabel: code,
      resultPayload: {
        dimensions: code.split(''),
      },
    });
  };

  return {
    state: {
      activeTab,
      assessmentStarted,
      currentQuestionIndex,
      answers,
      assessmentComplete,
      totalScore,
      maxScore,
      percentage,
      assessmentLevel,
      currentSelfAssessmentQuery,
      currentPersonalityQuery,
      personalityCompletionQuery,
      personalityDistributionQuery,
      canViewPersonalityDistribution,
      canManageQuizContent,
      savedPersonality,
      savedSelfAssessment,
      selfAssessmentResult,
      personalityResult,
      savedAnswers,
      savedDate,
      canPersistPersonalResults,
      isSaving: canPersistPersonalResults && savePersonalityMutation.isPending,
      isLoadingSaved: canPersistPersonalResults && (
        currentSelfAssessmentQuery.isLoading ||
        currentPersonalityQuery.isLoading
      ),
      distribution,
      personalityCompletion: personalityCompletionQuery.data ?? null,
      distributionLoading: personalityDistributionQuery.isLoading || personalityDistributionQuery.isFetching,
      distributionTotal,
      groupDistribution,
      errorMessage: getOptionalErrorMessage(personalityError),
      distributionErrorMessage: getOptionalErrorMessage(distributionError ?? personalityCompletionQuery.error),
      isDirector: canViewPersonalityDistribution,
      assessmentQuestions,
      personalityQuiz: personalityQuizQuery.payload,
      weeklyTopics: weeklyTopicsQuery.payload,
      growthTips: growthTipsQuery.payload,
      teamWellnessMetrics: teamWellnessMetricsQuery.payload,
      weeklyFocus: weeklyFocusQuery.payload,
      personalityWorkplaceContent: PERSONALITY_WORKPLACE_CONTENT,
      personalityTypes: PERSONALITY_TYPES,
      contentLoading: isAnyLoading(...contentQueries),
      contentError: getFirstQueryError(...contentQueries),
    },
    actions: {
      setActiveTab,
      setAssessmentStarted,
      handleAnswer,
      resetAssessment,
      handlePersonalityResult,
      refreshDistribution: () => personalityDistributionQuery.refetch(),
    },
  };
}
