import { ChevronDown, Plus, Settings, Trash2 } from 'lucide-react';
import { useMemo, useState } from 'react';

import { Button } from '@/components/ui/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { Input } from '@/components/ui/input';
import { NativeSelect } from '@/components/ui/native-select';
import { StatePanel } from '@/components/ui/state-panel';
import { Textarea } from '@/components/ui/textarea';
import {
  useDeleteManagedContentCatalog,
  useManagedContentCatalog,
  useSaveManagedContentCatalog,
} from '@/business/content-catalog/hooks';
import { CONTENT_CATALOG_TYPES } from '@/shared/constants/contentCatalog';
import { PERSONALITY_QUIZ_QUESTIONS } from '@/shared/constants/personalityStaticContent';
import type { QuizQuestion } from '@/shared/constants/personalityCatalog';
import type {
  EmotionalIntelligencePersonalityQuizContent,
  EmotionalIntelligenceQuestion,
} from '@/shared/types/emotionalIntelligence';

type Props = {
  readonly assessmentQuestions: readonly EmotionalIntelligenceQuestion[];
  readonly personalityQuiz: EmotionalIntelligencePersonalityQuizContent | null;
};

const inputClassName = 'border-slate-700/60 bg-slate-950/70 text-slate-100 placeholder:text-slate-500';
const sectionClassName = 'rounded-xl border border-slate-700/50 bg-slate-950/30 p-4 space-y-4';
const iconButtonClassName = 'h-9 w-9 border border-slate-700/60 text-slate-300 hover:bg-slate-700/40';

const blankAssessmentQuestion = (): EmotionalIntelligenceQuestion => ({
  q: '',
  options: ['', '', '', ''],
  scores: [1, 2, 3, 4],
});

const blankPersonalityQuestion = (id: number): QuizQuestion => ({
  id,
  dimension: 'EI',
  question: '',
  optionA: { text: '', value: 'E' },
  optionB: { text: '', value: 'I' },
});

const defaultPersonalityQuiz: EmotionalIntelligencePersonalityQuizContent = {
  id: 'personality-type',
  title: 'Personality Type Quiz',
  description: 'Discover your MBTI type and workplace communication style.',
  questions: PERSONALITY_QUIZ_QUESTIONS,
};

export function EmotionalIntelligenceQuizEditorPanel({
  assessmentQuestions,
  personalityQuiz,
}: Props) {
  const draftKey = useMemo(() => JSON.stringify({
    assessmentQuestions,
    personalityQuiz,
  }), [assessmentQuestions, personalityQuiz]);

  return (
    <EmotionalIntelligenceQuizEditorDraft
      key={draftKey}
      assessmentQuestions={assessmentQuestions}
      personalityQuiz={personalityQuiz}
    />
  );
}

function EmotionalIntelligenceQuizEditorDraft({
  assessmentQuestions,
  personalityQuiz,
}: Props) {
  const [open, setOpen] = useState(false);
  const [savedMessage, setSavedMessage] = useState<string | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [assessmentDraft, setAssessmentDraft] = useState<readonly EmotionalIntelligenceQuestion[]>(
    assessmentQuestions.length > 0 ? assessmentQuestions : [blankAssessmentQuestion()],
  );
  const [personalityDraft, setPersonalityDraft] = useState<EmotionalIntelligencePersonalityQuizContent>(
    personalityQuiz ?? defaultPersonalityQuiz,
  );
  const assessmentType = CONTENT_CATALOG_TYPES.emotionalIntelligenceAssessmentQuestions;
  const personalityType = CONTENT_CATALOG_TYPES.emotionalIntelligencePersonalityQuiz;
  const assessmentManagedQuery = useManagedContentCatalog<readonly EmotionalIntelligenceQuestion[]>(assessmentType);
  const personalityManagedQuery = useManagedContentCatalog<EmotionalIntelligencePersonalityQuizContent>(personalityType);
  const isLoading = assessmentManagedQuery.isLoading || personalityManagedQuery.isLoading;

  const saveAssessmentMutation = useSaveManagedContentCatalog(
    assessmentType,
    Boolean(assessmentManagedQuery.data),
    () => assessmentDraft,
  );
  const savePersonalityMutation = useSaveManagedContentCatalog(
    personalityType,
    Boolean(personalityManagedQuery.data),
    () => personalityDraft,
  );
  const deleteAssessmentMutation = useDeleteManagedContentCatalog(assessmentType);
  const deletePersonalityMutation = useDeleteManagedContentCatalog(personalityType);
  const disabled = isLoading ||
    saveAssessmentMutation.isPending ||
    savePersonalityMutation.isPending ||
    deleteAssessmentMutation.isPending ||
    deletePersonalityMutation.isPending;

  const assessmentValid = useMemo(() => (
    assessmentDraft.length > 0 &&
    assessmentDraft.every((question) => (
      question.q.trim().length > 0 &&
      question.options.length === 4 &&
      question.scores.length === 4 &&
      question.options.every((option) => option.trim().length > 0) &&
      question.scores.every((score) => Number.isInteger(score))
    ))
  ), [assessmentDraft]);
  const personalityValid = useMemo(() => (
    personalityDraft.title.trim().length > 0 &&
    personalityDraft.description.trim().length > 0 &&
    personalityDraft.questions.length > 0 &&
    personalityDraft.questions.every((question) => (
      question.question.trim().length > 0 &&
      question.optionA.text.trim().length > 0 &&
      question.optionB.text.trim().length > 0
    ))
  ), [personalityDraft]);

  return (
    <Collapsible
      open={open}
      onOpenChange={setOpen}
      className="rounded-2xl border border-slate-700/40 bg-slate-800/40"
    >
      <div className="flex flex-col gap-3 border-b border-slate-700/40 p-4 sm:flex-row sm:items-center sm:justify-between">
        <CollapsibleTrigger asChild>
          <button
            type="button"
            className="flex min-w-0 flex-1 items-center gap-3 rounded-xl text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-400"
            aria-label={open ? 'Collapse EI quiz editor' : 'Expand EI quiz editor'}
          >
            <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-blue-500/15 text-blue-300">
              <Settings size={18} />
            </span>
            <span className="min-w-0">
              <span className="block text-sm font-semibold text-white">EI Quiz Content Editor</span>
              <span className="block text-xs text-slate-400">Edit self-assessment and personality quiz content.</span>
            </span>
            <ChevronDown
              size={18}
              className={`ml-auto text-slate-400 transition-transform ${open ? 'rotate-180' : ''}`}
            />
          </button>
        </CollapsibleTrigger>
      </div>

      <CollapsibleContent className="space-y-4 p-4">
        {errorMessage && (
          <StatePanel tone="red" role="alert" size="inline">{errorMessage}</StatePanel>
        )}
        {savedMessage && (
          <StatePanel tone="cyan" size="inline">{savedMessage}</StatePanel>
        )}

        <section className={sectionClassName}>
          <EditorSectionHeader
            title="EI Self-Assessment"
            description="Reflective scored questions for personal emotional intelligence results."
            onSave={() => {
              if (!assessmentValid) {
                setErrorMessage('Complete every EI assessment question, option, and score before saving.');
                return;
              }
              void saveAssessment();
            }}
            onDelete={() => void deleteAssessment()}
            disabled={disabled}
          />

          <div className="space-y-4">
            {assessmentDraft.map((question, questionIndex) => (
              <div key={questionIndex} className="rounded-xl border border-slate-700/50 bg-slate-900/50 p-4 space-y-3">
                <div className="flex items-center justify-between gap-3">
                  <h4 className="text-sm font-semibold text-slate-100">Question {questionIndex + 1}</h4>
                  <Button
                    type="button"
                    variant="ghost"
                    aria-label={`Remove EI question ${questionIndex + 1}`}
                    onClick={() => setAssessmentDraft((draft) => draft.filter((_, index) => index !== questionIndex))}
                    disabled={disabled || assessmentDraft.length <= 1}
                    className={iconButtonClassName}
                  >
                    <Trash2 size={15} />
                  </Button>
                </div>
                <Textarea
                  value={question.q}
                  onChange={(event) => updateAssessmentQuestion(questionIndex, { q: event.target.value })}
                  disabled={disabled}
                  className={`${inputClassName} min-h-20`}
                  placeholder="Question text"
                />
                <div className="grid gap-3 md:grid-cols-2">
                  {question.options.map((option, optionIndex) => (
                    <div key={optionIndex} className="grid grid-cols-[1fr_80px] gap-2">
                      <Input
                        value={option}
                        onChange={(event) => updateAssessmentOption(questionIndex, optionIndex, event.target.value)}
                        disabled={disabled}
                        className={inputClassName}
                        placeholder={`Option ${optionIndex + 1}`}
                      />
                      <Input
                        type="number"
                        min={0}
                        value={question.scores[optionIndex] ?? 0}
                        onChange={(event) => updateAssessmentScore(questionIndex, optionIndex, Number(event.target.value))}
                        disabled={disabled}
                        className={inputClassName}
                        aria-label={`Score for EI option ${optionIndex + 1}`}
                      />
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
          <Button
            type="button"
            variant="ghost"
            leadingIcon={<Plus size={14} />}
            onClick={() => setAssessmentDraft((draft) => [...draft, blankAssessmentQuestion()])}
            disabled={disabled}
            className="border border-slate-700/60 text-slate-200 hover:bg-slate-700/40"
          >
            Add EI Question
          </Button>
        </section>

        <section className={sectionClassName}>
          <EditorSectionHeader
            title="Personality Type Quiz"
            description="MBTI-style questions used to calculate personality type."
            onSave={() => {
              if (!personalityValid) {
                setErrorMessage('Complete the personality quiz title, description, and all question text before saving.');
                return;
              }
              void savePersonality();
            }}
            onDelete={() => void deletePersonality()}
            disabled={disabled}
          />
          <div className="grid gap-3 md:grid-cols-2">
            <Input
              value={personalityDraft.title}
              onChange={(event) => updatePersonalityDraft({ title: event.target.value })}
              disabled={disabled}
              className={inputClassName}
              placeholder="Quiz title"
            />
            <Input
              value={personalityDraft.id}
              onChange={(event) => updatePersonalityDraft({ id: event.target.value })}
              disabled={disabled}
              className={inputClassName}
              placeholder="Quiz id"
            />
          </div>
          <Textarea
            value={personalityDraft.description}
            onChange={(event) => updatePersonalityDraft({ description: event.target.value })}
            disabled={disabled}
            className={`${inputClassName} min-h-20`}
            placeholder="Quiz description"
          />

          <div className="space-y-4">
            {personalityDraft.questions.map((question, questionIndex) => (
              <div key={question.id} className="rounded-xl border border-slate-700/50 bg-slate-900/50 p-4 space-y-3">
                <div className="flex items-center justify-between gap-3">
                  <h4 className="text-sm font-semibold text-slate-100">Question {questionIndex + 1}</h4>
                  <Button
                    type="button"
                    variant="ghost"
                    aria-label={`Remove personality question ${questionIndex + 1}`}
                    onClick={() => removePersonalityQuestion(questionIndex)}
                    disabled={disabled || personalityDraft.questions.length <= 1}
                    className={iconButtonClassName}
                  >
                    <Trash2 size={15} />
                  </Button>
                </div>
                <div className="grid gap-3 md:grid-cols-[140px_1fr]">
                  <NativeSelect
                    value={question.dimension}
                    onChange={(event) => updatePersonalityQuestion(questionIndex, { dimension: event.target.value as QuizQuestion['dimension'] })}
                    disabled={disabled}
                    className={inputClassName}
                    aria-label={`Dimension for personality question ${questionIndex + 1}`}
                  >
                    <option value="EI">E / I</option>
                    <option value="SN">S / N</option>
                    <option value="TF">T / F</option>
                    <option value="JP">J / P</option>
                  </NativeSelect>
                  <Textarea
                    value={question.question}
                    onChange={(event) => updatePersonalityQuestion(questionIndex, { question: event.target.value })}
                    disabled={disabled}
                    className={`${inputClassName} min-h-20`}
                    placeholder="Question text"
                  />
                </div>
                <div className="grid gap-3 md:grid-cols-2">
                  <PersonalityOptionFields
                    label="Option A"
                    text={question.optionA.text}
                    value={question.optionA.value}
                    disabled={disabled}
                    onTextChange={(text) => updatePersonalityQuestion(questionIndex, { optionA: { ...question.optionA, text } })}
                    onValueChange={(value) => updatePersonalityQuestion(questionIndex, { optionA: { ...question.optionA, value } })}
                  />
                  <PersonalityOptionFields
                    label="Option B"
                    text={question.optionB.text}
                    value={question.optionB.value}
                    disabled={disabled}
                    onTextChange={(text) => updatePersonalityQuestion(questionIndex, { optionB: { ...question.optionB, text } })}
                    onValueChange={(value) => updatePersonalityQuestion(questionIndex, { optionB: { ...question.optionB, value } })}
                  />
                </div>
              </div>
            ))}
          </div>
          <Button
            type="button"
            variant="ghost"
            leadingIcon={<Plus size={14} />}
            onClick={() => addPersonalityQuestion()}
            disabled={disabled}
            className="border border-slate-700/60 text-slate-200 hover:bg-slate-700/40"
          >
            Add Personality Question
          </Button>
        </section>
      </CollapsibleContent>
    </Collapsible>
  );

  function updateAssessmentQuestion(index: number, patch: Partial<EmotionalIntelligenceQuestion>) {
    setAssessmentDraft((draft) => draft.map((question, questionIndex) => (
      questionIndex === index ? { ...question, ...patch } : question
    )));
  }

  async function saveAssessment() {
    try {
      await saveAssessmentMutation.mutateAsync();
      setSavedMessage('EI self-assessment saved.');
      setErrorMessage(null);
    } catch {
      setErrorMessage('EI self-assessment could not be saved.');
    }
  }

  async function savePersonality() {
    try {
      await savePersonalityMutation.mutateAsync();
      setSavedMessage('Personality quiz saved.');
      setErrorMessage(null);
    } catch {
      setErrorMessage('Personality quiz could not be saved.');
    }
  }

  async function deleteAssessment() {
    try {
      await deleteAssessmentMutation.mutateAsync();
      setAssessmentDraft([blankAssessmentQuestion()]);
      setSavedMessage('EI self-assessment deleted.');
      setErrorMessage(null);
    } catch {
      setErrorMessage('EI self-assessment could not be deleted.');
    }
  }

  async function deletePersonality() {
    try {
      await deletePersonalityMutation.mutateAsync();
      setPersonalityDraft(defaultPersonalityQuiz);
      setSavedMessage('Personality quiz deleted.');
      setErrorMessage(null);
    } catch {
      setErrorMessage('Personality quiz could not be deleted.');
    }
  }

  function updateAssessmentOption(questionIndex: number, optionIndex: number, value: string) {
    setAssessmentDraft((draft) => draft.map((question, index) => {
      if (index !== questionIndex) {
        return question;
      }
      const options = [...question.options];
      options[optionIndex] = value;
      return { ...question, options };
    }));
  }

  function updateAssessmentScore(questionIndex: number, optionIndex: number, value: number) {
    setAssessmentDraft((draft) => draft.map((question, index) => {
      if (index !== questionIndex) {
        return question;
      }
      const scores = [...question.scores];
      scores[optionIndex] = value;
      return { ...question, scores };
    }));
  }

  function updatePersonalityDraft(patch: Partial<EmotionalIntelligencePersonalityQuizContent>) {
    setPersonalityDraft((draft) => ({ ...draft, ...patch }));
  }

  function updatePersonalityQuestion(index: number, patch: Partial<QuizQuestion>) {
    setPersonalityDraft((draft) => ({
      ...draft,
      questions: draft.questions.map((question, questionIndex) => (
        questionIndex === index ? { ...question, ...patch } : question
      )),
    }));
  }

  function addPersonalityQuestion() {
    setPersonalityDraft((draft) => ({
      ...draft,
      questions: [...draft.questions, blankPersonalityQuestion(draft.questions.length + 1)],
    }));
  }

  function removePersonalityQuestion(index: number) {
    setPersonalityDraft((draft) => ({
      ...draft,
      questions: draft.questions.filter((_, questionIndex) => questionIndex !== index),
    }));
  }
}

function EditorSectionHeader({
  title,
  description,
  onSave,
  onDelete,
  disabled,
}: {
  readonly title: string;
  readonly description: string;
  readonly onSave: () => void;
  readonly onDelete: () => void;
  readonly disabled: boolean;
}) {
  return (
    <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
      <div>
        <h3 className="text-sm font-semibold text-white">{title}</h3>
        <p className="text-xs text-slate-400">{description}</p>
      </div>
      <div className="flex gap-2">
        <Button type="button" onClick={onSave} disabled={disabled} className="bg-blue-600 text-white hover:bg-blue-500">
          Save
        </Button>
        <Button
          type="button"
          variant="ghost"
          onClick={onDelete}
          disabled={disabled}
          className="border border-red-500/30 bg-red-500/10 text-red-200 hover:bg-red-500/20"
        >
          Delete
        </Button>
      </div>
    </div>
  );
}

function PersonalityOptionFields({
  label,
  text,
  value,
  disabled,
  onTextChange,
  onValueChange,
}: {
  readonly label: string;
  readonly text: string;
  readonly value: string;
  readonly disabled: boolean;
  readonly onTextChange: (value: string) => void;
  readonly onValueChange: (value: string) => void;
}) {
  return (
    <div className="grid grid-cols-[1fr_80px] gap-2">
      <Input
        value={text}
        onChange={(event) => onTextChange(event.target.value)}
        disabled={disabled}
        className={inputClassName}
        placeholder={label}
      />
      <NativeSelect
        value={value}
        onChange={(event) => onValueChange(event.target.value)}
        disabled={disabled}
        className={inputClassName}
        aria-label={`${label} value`}
      >
        {['E', 'I', 'S', 'N', 'T', 'F', 'J', 'P'].map((letter) => (
          <option key={letter} value={letter}>{letter}</option>
        ))}
      </NativeSelect>
    </div>
  );
}
