import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Modal,
  Stack,
  Select,
  Divider,
  Table,
  Text,
  Badge,
  NumberInput,
  Paper,
  SimpleGrid,
  Group,
  TextInput,
  Button,
  Alert,
} from '@mantine/core';
import { IconInfoCircle, IconCheck, IconX } from '@tabler/icons-react';
import { notify } from '@ema-platform/ui';
import { extractErrorMessage } from '@ema-platform/api';
import { useCreateResultMutation } from '../api/result-api';
import { useGetExamRegistrationsQuery } from '../../exam/api/exam-api';
import type { Exam } from '../../exam/types/exam';

function InfoRow({ label, value }: { label: string; value: string }) {
  return (
    <div>
      <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>{label}</Text>
      <Text fz="sm" fw={500}>{value || '—'}</Text>
    </div>
  );
}

export function RecordResultModal({
  exam,
  opened,
  onClose,
}: {
  exam: Exam;
  opened: boolean;
  onClose: () => void;
}) {
  const { t, i18n } = useTranslation();
  const locale = i18n.language as 'en' | 'am';
  const { handleError } = useErrorHandler();
  const [seafarerSearch, setSeafarerSearch] = useState('');
  const [selectedSeafarerId, setSelectedSeafarerId] = useState<string | null>(null);
  const [scores, setScores] = useState<Record<string, number>>({});
  const [questionRemarks, setQuestionRemarks] = useState<Record<string, string>>({});
  const [remark, setRemark] = useState('');

  // Only candidates who registered and actually sat the paper can be marked
  // (US-EXAM-009 feeding US-EXAM-011) — the API refuses anyone else, so the
  // picker is the session's own register rather than every seafarer profile.
  const { data: registrations } = useGetExamRegistrationsQuery(exam.id, {
    skip: !opened,
  });
  const [createResult, { isLoading: isSaving }] = useCreateResultMutation();

  const questions = exam.questions ?? [];

  const seafarerOptions = (registrations ?? [])
    .filter((registration) =>
      ['PRESENT', 'LATE'].includes(registration.attendanceStatus),
    )
    .map((registration) => ({
      value: registration.profileId,
      label: `${registration.admissionNumber} — ${[
        registration.profile?.firstName,
        registration.profile?.middleName,
        registration.profile?.lastName,
      ]
        .filter(Boolean)
        .join(' ')}`,
    }));

  const filteredOptions = seafarerSearch
    ? seafarerOptions.filter((o: any) => o.label.toLowerCase().includes(seafarerSearch.toLowerCase()))
    : seafarerOptions;

  const totalScore = questions.reduce((sum, q) => sum + (scores[q.id] ?? 0), 0);
  const maxScore = questions.reduce((sum, q) => sum + (q.points ?? 0), 0);
  // The cutting point is read per the exam's configured evaluation method —
  // an AVERAGE or PERCENTAGE exam must not be graded as a raw sum.
  const effectiveScore =
    exam.evaluationMethod === 'AVERAGE'
      ? questions.length > 0
        ? totalScore / questions.length
        : 0
      : exam.evaluationMethod === 'PERCENTAGE'
        ? maxScore > 0
          ? (totalScore / maxScore) * 100
          : 0
        : totalScore;
  const passed = effectiveScore >= exam.cuttingPoint;

  const handleScoreChange = (questionId: string, value: number) => {
    setScores((prev) => ({ ...prev, [questionId]: value }));
  };

  const handleQuestionRemarkChange = (questionId: string, value: string) => {
    setQuestionRemarks((prev) => ({ ...prev, [questionId]: value }));
  };

  const handleSave = async () => {
    if (!selectedSeafarerId) {
      notify.error(t('result.recordModal.seafarerRequired'));
      return;
    }
    try {
      const breakdowns = questions.map((q) => ({
        questionId: q.id,
        score: scores[q.id] ?? 0,
        remark: questionRemarks[q.id] ?? '',
      }));
      // The outcome is not sent: the API derives PASSED/FAILED from the
      // session's evaluation method and cutting point, and stamps the
      // examiner on the row (US-EXAM-011). The preview below shows what that
      // computation will produce.
      await createResult({
        seafarerId: selectedSeafarerId,
        examId: exam.id,
        resultBreakdowns: breakdowns,
        remark: remark ? { en: remark, am: '' } : undefined,
      }).unwrap();
      notify.success(t('result.recordModal.saveSuccess'));
      setSelectedSeafarerId(null);
      setScores({});
      setQuestionRemarks({});
      setRemark('');
      setSeafarerSearch('');
      onClose();
    } catch (error) {
      const key = extractErrorMessage(error, t('result.recordModal.saveError'));
      notify.error(
        key === 'candidate_not_registered'
          ? 'This candidate is not registered for the session.'
          : key.startsWith('candidate_not_present')
            ? `No paper to mark — the register says ${key.split(':')[1] ?? ''}.`
            : key === 'result_already_recorded'
              ? 'A result has already been recorded for this candidate.'
              : key,
      );
    }
  };

  return (
    <Modal opened={opened} onClose={onClose} title={`${t('result.recordModal.title')} — ${exam.title[locale]}`} size="lg" radius="lg">
      <Stack gap="md">
        <Select
          label={t('result.recordModal.seafarer')}
          placeholder={t('result.recordModal.seafarerPlaceholder')}
          data={filteredOptions}
          value={selectedSeafarerId}
          onChange={(v) => {
            setSelectedSeafarerId(v);
            setScores({});
            setQuestionRemarks({});
          }}
          searchable
          onSearchChange={setSeafarerSearch}
          size="sm"
          required
        />

        {selectedSeafarerId && questions.length > 0 && (
          <>
            <Divider label={t('result.recordModal.scorePerQuestion')} labelPosition="center" />
            <Table striped>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>{t('result.recordModal.question')}</Table.Th>
                  <Table.Th>{t('result.recordModal.maxPoints')}</Table.Th>
                  <Table.Th>{t('result.recordModal.score')}</Table.Th>
                  <Table.Th>{t('result.recordModal.remark')}</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {questions.map((q) => (
                  <Table.Tr key={q.id}>
                    <Table.Td><Text fz="sm" maw={250} lineClamp={2}>{q.title[locale]}</Text></Table.Td>
                    <Table.Td><Text fz="sm" fw={600}>{q.points}</Text></Table.Td>
                    <Table.Td>
                      <NumberInput
                        value={scores[q.id] ?? 0}
                        onChange={(v) => handleScoreChange(q.id, Number(v))}
                        min={0}
                        max={q.points}
                        size="xs"
                        style={{ width: 80 }}
                      />
                    </Table.Td>
                    <Table.Td>
                      <TextInput
                        placeholder={t('result.recordModal.remarkOptional')}
                        value={questionRemarks[q.id] ?? ''}
                        onChange={(e) => handleQuestionRemarkChange(q.id, e.currentTarget.value)}
                        size="xs"
                        style={{ minWidth: 160 }}
                      />
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>

            <Paper withBorder p="sm" radius="md" bg="gray.0">
              <SimpleGrid cols={3} spacing="sm">
                <InfoRow label={t('result.recordModal.totalScore')} value={String(totalScore)} />
                <InfoRow label={t('result.recordModal.passMark')} value={String(exam.cuttingPoint)} />
                <div>
                  <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>{t('result.recordModal.status')}</Text>
                  <Group gap={4} mt={2}>
                    {passed
                      ? <><IconCheck size={14} color="var(--mantine-color-teal-6)" /><Text fz="sm" fw={700} c="teal">{t('result.recordModal.passed')}</Text></>
                      : <><IconX size={14} color="var(--mantine-color-red-6)" /><Text fz="sm" fw={700} c="red">{t('result.recordModal.failed')}</Text></>}
                  </Group>
                </div>
              </SimpleGrid>
            </Paper>

            <TextInput
              label={t('result.recordModal.remarkOptional')}
              placeholder={t('result.recordModal.remarkPlaceholder')}
              value={remark}
              onChange={(e) => setRemark(e.currentTarget.value)}
              size="sm"
            />

            <ModalFooter>
              <Button variant="default" onClick={onClose} size="sm">{t('result.cancel')}</Button>
              <Button onClick={handleSave} size="sm" loading={isSaving}>
                {t('result.saveResult')}
              </Button>
            </ModalFooter>
          </>
        )}

        {selectedSeafarerId && questions.length === 0 && (
          <Alert color="yellow" icon={<IconInfoCircle size={15} />}>
            {t('result.recordModal.noQuestions')}
          </Alert>
        )}
      </Stack>
    </Modal>
  );
}
