import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  ActionIcon,
  Button,
  Checkbox,
  Group,
  Modal,
  NumberInput,
  Select,
  Stack,
  Text,
  TextInput,
} from '@mantine/core';
import { IconPlus, IconTrash } from '@tabler/icons-react';
import { ModalFooter, notify } from '@ema-platform/ui';
import { extractErrorMessage } from '@ema-platform/api';
import { useCreateExamQuestionMutation } from '../../api/exam-api';
import type { Exam, QuestionForm } from '../../types/exam';
import { describeExamQuestionError } from './errors';

type DraftOption = { textEn: string; textAm: string; isCorrect: boolean };

const BLANK: DraftOption[] = [
  { textEn: '', textAm: '', isCorrect: false },
  { textEn: '', textAm: '', isCorrect: false },
];

/**
 * "Add new question from scratch": authored under this exam's subject and
 * put on its paper in one call — the officer never leaves the exam or copies
 * an id. The item is a real bank question (options, answer key), reusable on
 * a later paper.
 */
export function ExamQuestionCreateModal({
  exam,
  opened,
  onClose,
}: {
  exam: Exam;
  opened: boolean;
  onClose: () => void;
}) {
  const { t } = useTranslation();
  const [createQuestion, { isLoading }] = useCreateExamQuestionMutation();
  const [titleEn, setTitleEn] = useState('');
  const [titleAm, setTitleAm] = useState('');
  const [form, setForm] = useState<QuestionForm | null>(exam.form === 'ESSAY' ? 'ESSAY' : 'CHOICE');
  const [points, setPoints] = useState<number>(1);
  const [options, setOptions] = useState<DraftOption[]>(BLANK);

  const reset = () => {
    setTitleEn('');
    setTitleAm('');
    setForm(exam.form === 'ESSAY' ? 'ESSAY' : 'CHOICE');
    setPoints(1);
    setOptions(BLANK);
  };
  const close = () => {
    reset();
    onClose();
  };

  const updateOption = (index: number, patch: Partial<DraftOption>) =>
    setOptions((current) => current.map((o, i) => (i === index ? { ...o, ...patch } : o)));

  // A mixed (BOTH) paper takes either form; otherwise the question must match.
  const formOptions = (exam.form === 'BOTH' ? ['ESSAY', 'CHOICE'] : [exam.form]).map((value) => ({
    value,
    label: t(`exam.formType.${value}`),
  }));

  const submit = async () => {
    if (!titleEn.trim() || !form || !(points > 0)) {
      notify.error(t('exam.newQuestion.fillRequired'));
      return;
    }
    if (form === 'CHOICE') {
      if (options.length < 2) return void notify.error(t('exam.newQuestion.needTwo'));
      if (!options.some((o) => o.isCorrect)) return void notify.error(t('exam.newQuestion.needCorrect'));
      if (options.some((o) => !o.textEn.trim())) return void notify.error(t('exam.newQuestion.textRequired'));
    }
    try {
      await createQuestion({
        examId: exam.id,
        // The API requires Amharic; it falls back to the English text server-side
        // as well, but sending it explicitly keeps the request self-describing.
        title: { en: titleEn.trim(), am: titleAm.trim() || titleEn.trim() },
        form,
        points,
        options:
          form === 'CHOICE'
            ? options.map((o) => ({
                text: { en: o.textEn.trim(), am: o.textAm.trim() || o.textEn.trim() },
                isCorrect: o.isCorrect,
              }))
            : undefined,
      }).unwrap();
      notify.success(t('exam.newQuestion.created'));
      close();
    } catch (error) {
      notify.error(describeExamQuestionError(t, extractErrorMessage(error, t('exam.error'))));
    }
  };

  return (
    <Modal opened={opened} onClose={close} title={t('exam.newQuestion.title')} size="lg" radius="lg">
      <Stack gap="sm">
        <Text fz="sm" c="dimmed">{t('exam.newQuestion.hint')}</Text>
        <TextInput
          label={t('exam.newQuestion.titleEn')}
          value={titleEn}
          onChange={(e) => setTitleEn(e.currentTarget.value)}
          size="sm"
          required
        />
        <TextInput
          label={t('exam.newQuestion.titleAm')}
          value={titleAm}
          onChange={(e) => setTitleAm(e.currentTarget.value)}
          size="sm"
        />
        <Group grow>
          <Select
            label={t('exam.newQuestion.form')}
            data={formOptions}
            value={form}
            onChange={(v) => setForm((v as QuestionForm) ?? null)}
            size="sm"
            required
          />
          <NumberInput
            label={t('exam.newQuestion.points')}
            value={points}
            onChange={(v) => setPoints(Number(v))}
            min={1}
            size="sm"
            required
          />
        </Group>
        {form === 'CHOICE' && (
          <Stack gap="xs">
            <Text fz="sm" fw={500}>{t('exam.newQuestion.options')}</Text>
            {options.map((option, index) => (
              <Group key={index} gap="xs" wrap="nowrap" align="flex-end">
                <TextInput
                  label={t('exam.newQuestion.optionEn', { number: index + 1 })}
                  value={option.textEn}
                  onChange={(e) => updateOption(index, { textEn: e.currentTarget.value })}
                  size="sm"
                  style={{ flex: 1 }}
                  required
                />
                <TextInput
                  label={t('exam.newQuestion.optionAm', { number: index + 1 })}
                  value={option.textAm}
                  onChange={(e) => updateOption(index, { textAm: e.currentTarget.value })}
                  size="sm"
                  style={{ flex: 1 }}
                />
                <Checkbox
                  label={t('exam.newQuestion.correct')}
                  checked={option.isCorrect}
                  onChange={() => updateOption(index, { isCorrect: !option.isCorrect })}
                  mb={6}
                />
                <ActionIcon
                  variant="subtle"
                  color="red"
                  size="sm"
                  mb={8}
                  disabled={options.length <= 2}
                  onClick={() => setOptions((current) => current.filter((_, i) => i !== index))}
                >
                  <IconTrash size={14} />
                </ActionIcon>
              </Group>
            ))}
            <Button
              variant="subtle"
              size="xs"
              w="fit-content"
              leftSection={<IconPlus size={14} />}
              onClick={() => setOptions((current) => [...current, { textEn: '', textAm: '', isCorrect: false }])}
            >
              {t('exam.newQuestion.addOption')}
            </Button>
          </Stack>
        )}
        <ModalFooter>
          <Button variant="default" size="sm" onClick={close}>{t('exam.cancel')}</Button>
          <Button size="sm" loading={isLoading} onClick={submit}>{t('exam.newQuestion.create')}</Button>
        </ModalFooter>
      </Stack>
    </Modal>
  );
}
