import { useState, useCallback, type ElementType } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Stack,
  Title,
  Group,
  Table,
  Badge,
  Modal,
  Text,
  Paper,
  Card,
  Loader,
  Center,
  Alert,
  Select,
  SimpleGrid,
  Divider,
  Button,
  ThemeIcon,
  Box,
  TextInput,
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import {
  IconInfoCircle,
  IconEye,
  IconTrash,
  IconUser,
  IconCertificate,
  IconDeviceFloppy,
  IconPlus,
  IconClipboardList,
  IconCircleCheck,
  IconCircleX,
  IconChartBar,
  IconSearch,
  IconSend,
} from '@tabler/icons-react';
import { notify, BilingualInput, useErrorHandler, AdvancedTable, useServerTable, ModalFooter, type AdvancedColumn } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import type { BilingualValue } from '@ema-platform/ui';
import { extractErrorMessage } from '@ema-platform/api';
import {
  useGetResultsQuery,
  useLazyGetResultQuery,
  useDeleteResultMutation,
  useUpdateResultMutation,
  useModerateResultMutation,
  useApproveResultMutation,
  useReturnResultMutation,
  usePublishExamResultsMutation,
} from '../api/result-api';
import { useGetExamsQuery } from '../../exam/api/exam-api';
import { RecordResultModal } from '../components/RecordResultModal';
import type { Result, ResultBreakdown, ResultReviewStatus } from '../types/result';
import type { Exam } from '../../exam/types/exam';

const STATUS_COLOR: Record<string, string> = {
  PASSED: 'teal',
  FAILED: 'red',
};

/** Where a mark sits in quality control (US-EXAM-011 → 014). */
const REVIEW_COLOR: Record<ResultReviewStatus, string> = {
  MARKED: 'gray',
  MODERATED: 'yellow',
  APPROVED: 'blue',
  PUBLISHED: 'teal',
};

type QcAction = 'moderate' | 'approve' | 'return';

function ResultStat({
  label,
  value,
  sub,
  icon: Icon,
  color,
}: {
  label: string;
  value: string;
  sub?: string;
  icon: ElementType;
  color: string;
}) {
  return (
    <Paper p="lg" radius="lg" withBorder>
      <Group justify="space-between" align="flex-start">
        <ThemeIcon size={46} radius="md" variant="light" color={color}>
          <Icon size={22} />
        </ThemeIcon>
        {sub && (
          <Badge variant="light" color={color} radius="sm">
            {sub}
          </Badge>
        )}
      </Group>
      <Text fz={30} fw={800} mt="md" lh={1.1}>
        {value}
      </Text>
      <Text size="sm" c="dimmed" mt={4}>
        {label}
      </Text>
    </Paper>
  );
}

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 ResultPage() {
  const { t, i18n } = useTranslation();
  const showDate = useDateDisplayer();
  const locale = i18n.language as 'en' | 'am';
  const { handleError } = useErrorHandler();
  const { data: examRes } = useGetExamsQuery();
  const { data, isFetching, isError, refetch } = useGetResultsQuery();
  const { setPageIndex, pageSize, setPageSize, paginate } = useServerTable();
  const [fetchDetail, { data: detailResult, isFetching: isDetailLoading }] = useLazyGetResultQuery();

  const exams = examRes?.items ?? [];
  const results = data?.items ?? [];

  const [deleteResult] = useDeleteResultMutation();
  const [updateResult] = useUpdateResultMutation();
  const [moderateResult, { isLoading: isModerating }] = useModerateResultMutation();
  const [approveResult, { isLoading: isApproving }] = useApproveResultMutation();
  const [returnResult, { isLoading: isReturning }] = useReturnResultMutation();
  const [publishResults, { isLoading: isPublishing }] = usePublishExamResultsMutation();

  const [searchQuery, setSearchQuery] = useState('');
  const [examFilter, setExamFilter] = useState<string | null>(null);
  const [detailOpened, { open: openDetail, close: closeDetail }] = useDisclosure(false);
  const [deleteTarget, setDeleteTarget] = useState<Result | null>(null);
  const [deleteOpened, { open: openDelete, close: closeDelete }] = useDisclosure(false);
  const [detailRemark, setDetailRemark] = useState<BilingualValue>({ en: '', am: '' });
  const [detailBreakdowns, setDetailBreakdowns] = useState<ResultBreakdown[]>([]);
  const [detailSaving, setDetailSaving] = useState(false);
  const [pickerExamId, setPickerExamId] = useState<string | null>(null);
  const [pickerOpened, { open: openPicker, close: closePicker }] = useDisclosure(false);
  const [recordExam, setRecordExam] = useState<Exam | null>(null);
  const [recordOpened, { open: openRecord, close: closeRecord }] = useDisclosure(false);
  const [qcTarget, setQcTarget] = useState<Result | null>(null);
  const [qcAction, setQcAction] = useState<QcAction>('approve');
  const [qcRemark, setQcRemark] = useState('');
  const [qcAdjustment, setQcAdjustment] = useState(0);

  const examOptions = exams.map((e) => ({ value: e.id, label: `${e.title.en} (${e.date})` }));

  const startRecord = () => {
    const ex = exams.find((e) => e.id === pickerExamId);
    if (!ex) {
      notify.error(t('result.selectExamError'));
      return;
    }
    setRecordExam(ex);
    closePicker();
    openRecord();
  };

  const handleRecordClose = () => {
    closeRecord();
    setRecordExam(null);
    setPickerExamId(null);
  };

  const filtered = results.filter((r) => {
    if (examFilter && r.examId !== examFilter) return false;
    if (!searchQuery) return true;
    const q = searchQuery.toLowerCase();
    if (r.seafarerId.toLowerCase().includes(q)) return true;
    if (r.seafarer) {
      const name = `${r.seafarer.firstName} ${r.seafarer.middleName ?? ''} ${r.seafarer.lastName}`.toLowerCase();
      if (name.includes(q)) return true;
    }
    return false;
  });

  const total = results.length;
  const passedCount = results.filter((r) => r.status === 'PASSED').length;
  const failedCount = total - passedCount;
  const passRate = total ? Math.round((passedCount / total) * 100) : 0;
  const avgScore = total
    ? (results.reduce((s, r) => s + Number(r.totalScore || 0), 0) / total).toFixed(1)
    : '0';

  const getExamTitle = (id: string) => exams.find((e) => e.id === id)?.title?.[locale] ?? '-';

  const viewDetail = useCallback((result: Result) => {
    fetchDetail(result.id);
    setDetailRemark({ en: result.remark?.en ?? '', am: result.remark?.am ?? '' });
    setDetailBreakdowns(result.resultBreakdowns.map((b) => ({ ...b })));
    openDetail();
  }, [fetchDetail, openDetail]);

  const handleDetailSave = async () => {
    if (!detailResult) return;
    setDetailSaving(true);
    try {
      // No `status`: re-marking recomputes the outcome on the server, and an
      // approved result is refused until it is returned to the examiner.
      await updateResult({
        id: detailResult.id,
        remark: detailRemark.en || detailRemark.am ? detailRemark : undefined,
        resultBreakdowns: detailBreakdowns,
      }).unwrap();
      notify.success(t('result.updated'));
      closeDetail();
    } catch (error) {
      const key = extractErrorMessage(error, t('result.error'));
      notify.error(
        key === 'result_locked_after_approval'
          ? t('result.review.lockedAfterApproval')
          : key,
      );
    } finally {
      setDetailSaving(false);
    }
  };

  const openQc = (result: Result, action: QcAction) => {
    setQcTarget(result);
    setQcAction(action);
    setQcRemark('');
    setQcAdjustment(0);
  };

  const runQc = async () => {
    if (!qcTarget) return;
    if (!qcRemark.trim()) {
      notify.error(t('result.review.remarkRequired'));
      return;
    }
    try {
      if (qcAction === 'moderate') {
        await moderateResult({
          id: qcTarget.id,
          adjustment: qcAdjustment,
          remark: qcRemark.trim(),
        }).unwrap();
        notify.success(t('result.review.moderated'));
      } else if (qcAction === 'approve') {
        await approveResult({ id: qcTarget.id, remark: qcRemark.trim() }).unwrap();
        notify.success(t('result.review.approved'));
      } else {
        await returnResult({ id: qcTarget.id, remark: qcRemark.trim() }).unwrap();
        notify.success(t('result.review.returned'));
      }
      setQcTarget(null);
    } catch (error) {
      notify.error(extractErrorMessage(error, t('result.review.error')));
    }
  };

  /**
   * Publication is per session (US-EXAM-014) — a cohort sees its results
   * together — so it needs an exam in the filter to know which one.
   */
  const handlePublish = async () => {
    if (!examFilter) {
      notify.error(t('result.review.publishNeedsExam'));
      return;
    }
    try {
      const outcome = await publishResults(examFilter).unwrap();
      notify.success(t('result.review.publishedCount', outcome));
    } catch (error) {
      notify.error(extractErrorMessage(error, t('result.review.error')));
    }
  };

  const handleDetailClose = () => {
    closeDetail();
    setDetailBreakdowns([]);
    setDetailRemark({ en: '', am: '' });
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      await deleteResult(deleteTarget.id).unwrap();
      notify.success(t('result.deleted'));
      closeDelete();
      setDeleteTarget(null);
    } catch (e) {
      handleError(e);
    }
  };

  if (isError) return <Alert icon={<IconInfoCircle size={16} />} color="red" title={t('result.loadError')} />;

  const columns: AdvancedColumn<Result>[] = [
    {
      header: t('result.columns.seafarer'),
      cell: ({ row }) => (
        <Text fz="sm" fw={500}>
          {row.original.seafarer
            ? `${row.original.seafarer.firstName} ${row.original.seafarer.lastName}`
            : row.original.seafarerId.slice(0, 8)}
        </Text>
      ),
    },
    {
      header: t('result.columns.exam'),
      cell: ({ row }) => (
        <Text fz="sm">{row.original.exam ? row.original.exam.title[locale] : getExamTitle(row.original.examId)}</Text>
      ),
    },
    {
      header: t('result.columns.totalScore'),
      cell: ({ row }) => <Text fz="sm" fw={600}>{row.original.totalScore}</Text>,
    },
    {
      header: t('result.columns.status'),
      cell: ({ row }) => (
        <Badge
          size="sm"
          variant="light"
          color={STATUS_COLOR[row.original.status]}
          leftSection={
            <Box
              w={6}
              h={6}
              style={{ borderRadius: 999, background: `var(--mantine-color-${STATUS_COLOR[row.original.status]}-6)` }}
            />
          }
        >
          {t(`result.status.${row.original.status}`)}
        </Badge>
      ),
    },
    {
      header: t('result.review.column'),
      cell: ({ row }) => (
        <Badge size="sm" variant="light" color={REVIEW_COLOR[row.original.reviewStatus] ?? 'gray'}>
          {t(`result.review.${row.original.reviewStatus}`)}
        </Badge>
      ),
    },
    {
      header: t('result.columns.date'),
      cell: ({ row }) => <Text fz="sm">{showDate(row.original.createdAt)}</Text>,
    },
    {
      header: '',
      label: t('result.columns.actions', 'Actions'),
      cell: ({ row }) => {
        const r = row.original;
        return (
          <Group gap="xs">
            {(r.reviewStatus === 'MARKED' || r.reviewStatus === 'MODERATED') && (
              <>
                <Button size="compact-xs" variant="light" color="yellow" onClick={() => openQc(r, 'moderate')}>
                  {t('result.review.moderate')}
                </Button>
                <Button size="compact-xs" variant="light" color="blue" onClick={() => openQc(r, 'approve')}>
                  {t('result.review.approve')}
                </Button>
              </>
            )}
            {(r.reviewStatus === 'APPROVED' || r.reviewStatus === 'MODERATED') && (
              <Button size="compact-xs" variant="subtle" color="orange" onClick={() => openQc(r, 'return')}>
                {t('result.review.return')}
              </Button>
            )}
            <Button size="xs" variant="subtle" leftSection={<IconEye size={13} />} onClick={() => viewDetail(r)}>
              {t('result.action.viewEdit')}
            </Button>
            <Button
              size="xs"
              variant="subtle"
              color="red"
              leftSection={<IconTrash size={13} />}
              onClick={() => { setDeleteTarget(r); openDelete(); }}
            >
              {t('result.action.delete')}
            </Button>
          </Group>
        );
      },
    },
  ];

  const page = paginate(filtered);

  return (
    <Stack gap="lg">
      <Group justify="space-between" align="flex-end">
        <div>
          <Title order={2}>{t('result.title')}</Title>
          <Text fz="sm" c="dimmed">{t('result.subtitle')}</Text>
        </div>
        <Group gap="sm">
          <Button
            variant="light"
            color="teal"
            size="sm"
            loading={isPublishing}
            disabled={!examFilter}
            leftSection={<IconSend size={15} />}
            onClick={handlePublish}
          >
            {t('result.review.publish')}
          </Button>
          <Button leftSection={<IconPlus size={15} />} onClick={openPicker} size="sm">
            {t('result.record')}
          </Button>
        </Group>
      </Group>

      <SimpleGrid cols={{ base: 2, lg: 4 }} spacing="lg">
        <ResultStat label={t('result.stats.totalResults')} value={String(total)} icon={IconClipboardList} color="blue" />
        <ResultStat label={t('result.stats.passed')} value={String(passedCount)} sub={`${passRate}%`} icon={IconCircleCheck} color="teal" />
        <ResultStat label={t('result.stats.failed')} value={String(failedCount)} sub={`${total ? 100 - passRate : 0}%`} icon={IconCircleX} color="red" />
        <ResultStat label={t('result.stats.avgScore')} value={avgScore} icon={IconChartBar} color="indigo" />
      </SimpleGrid>

      <Card withBorder padding={0}>
        <Group p="md" justify="space-between" wrap="wrap" gap="sm">
          <Text fw={600}>{t('result.section')}</Text>
          <Group gap="sm" wrap="wrap">
            <TextInput
              placeholder={t('result.search.seafarer')}
              leftSection={<IconSearch size={15} />}
              value={searchQuery}
              onChange={(e) => { setSearchQuery(e.currentTarget.value); setPageIndex(0); }}
              size="sm"
              style={{ width: 240 }}
            />
            <Select
              placeholder={t('result.search.filterByExam')}
              data={[{ value: '', label: t('result.search.allExams') }, ...examOptions]}
              value={examFilter}
              onChange={(v) => { setExamFilter(v ?? null); setPageIndex(0); }}
              size="sm"
              style={{ width: 280 }}
              clearable
            />
          </Group>
        </Group>

        <AdvancedTable
          columns={columns}
          data={page.rows}
          tableName={t('result.title')}
          itemCount={page.itemCount}
          pageIndex={page.pageIndex}
          onPageChange={setPageIndex}
          pageSize={pageSize}
          onPageSizeChange={setPageSize}
          refresh={refetch}
          isLoading={isFetching}
          emptyText={t('result.noItems')}
        />
      </Card>

      <Modal
        opened={detailOpened}
        onClose={handleDetailClose}
        title={t('result.detail.title')}
        size="xl"
        radius="lg"
      >
        {isDetailLoading ? (
          <Center py="xl"><Loader /></Center>
        ) : detailResult ? (
          <Stack gap="md">
            {/* Seafarer Profile */}
            <Paper withBorder p="md" radius="md">
              <Group gap="sm" mb="sm">
                <ThemeIcon size="sm" variant="light" color="blue" radius="xl">
                  <IconUser size={14} />
                </ThemeIcon>
                <Text fw={600} fz="sm">{t('result.detail.seafarerProfile')}</Text>
              </Group>
              <SimpleGrid cols={{ base: 2, sm: 4 }} spacing="sm">
                <InfoRow label={t('result.detail.fullName')} value={detailResult.profile ? `${detailResult.profile.firstName} ${detailResult.profile.middleName ?? ''} ${detailResult.profile.lastName}` : detailResult.seafarerId} />
                <InfoRow label={t('result.detail.gender')} value={detailResult.profile?.gender ?? '—'} />
                <InfoRow label={t('result.detail.dateOfBirth')} value={showDate(detailResult.profile?.dob)} />
                <InfoRow label={t('result.detail.maritalStatus')} value={detailResult.profile?.maritalStatus ?? '—'} />
              </SimpleGrid>
            </Paper>

            {/* Exam Details */}
            {detailResult.exam && (
              <Paper withBorder p="md" radius="md">
                <Group gap="sm" mb="sm">
                  <ThemeIcon size="sm" variant="light" color="violet" radius="xl">
                    <IconCertificate size={14} />
                  </ThemeIcon>
                  <Text fw={600} fz="sm">{t('result.detail.examDetails')}</Text>
                </Group>
                <SimpleGrid cols={{ base: 2, sm: 4 }} spacing="sm">
                  <InfoRow label={t('result.detail.examTitle')} value={detailResult.exam.title?.[locale] ?? '—'} />
                  <InfoRow label={t('result.detail.type')} value={detailResult.exam.type ?? '—'} />
                  <InfoRow label={t('result.detail.venue')} value={detailResult.exam.venue ?? '—'} />
                  <InfoRow label={t('result.detail.date')} value={showDate(detailResult.exam.date)} />
                  <InfoRow label={t('result.detail.passMark')} value={String(detailResult.exam.cuttingPoint ?? 0)} />
                </SimpleGrid>
              </Paper>
            )}

            <Divider />

            {/* Editable fields */}
            {/* Read-only: the outcome follows the pass mark, not the officer. */}
            <div>
              <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>
                {t('result.review.derivedStatus')}
              </Text>
              <Group gap="xs" mt={4}>
                <Badge variant="light" color={STATUS_COLOR[detailResult.status]}>
                  {t(`result.status.${detailResult.status}`)}
                </Badge>
                <Badge variant="light" color={REVIEW_COLOR[detailResult.reviewStatus] ?? 'gray'}>
                  {t(`result.review.${detailResult.reviewStatus}`)}
                </Badge>
                {detailResult.preModerationScore != null && (
                  <Text fz="xs" c="dimmed">
                    {t('result.review.originalScore')}: {detailResult.preModerationScore}
                    {detailResult.moderationRemark ? ` — ${detailResult.moderationRemark}` : ''}
                  </Text>
                )}
              </Group>
            </div>

            <BilingualInput
              label={t('result.detail.remark')}
              placeholder={{ en: 'Officer remark in English', am: 'የኃላፊ አስተያየት በአማርኛ' }}
              value={detailRemark}
              onChange={setDetailRemark}
              size="sm"
            />

            {detailBreakdowns.length > 0 && (
              <>
                <Text fw={600} fz="sm" tt="uppercase" c="gray.6">{t('result.detail.scoreBreakdown')}</Text>
                <Table striped>
                  <Table.Thead>
                    <Table.Tr>
                      <Table.Th>#</Table.Th>
                      <Table.Th>{t('result.detail.question')}</Table.Th>
                      <Table.Th>{t('result.detail.max')}</Table.Th>
                      <Table.Th>{t('result.detail.score')}</Table.Th>
                      <Table.Th>{t('result.detail.remarkShort')}</Table.Th>
                    </Table.Tr>
                  </Table.Thead>
                  <Table.Tbody>
                    {detailBreakdowns.map((b, i) => {
                      const examDetail = exams.find((e) => e.id === detailResult.examId);
                      const q = examDetail?.questions?.find((eq) => eq.id === b.questionId);
                      return (
                      <Table.Tr key={b.questionId}>
                        <Table.Td><Text fz="xs">{i + 1}</Text></Table.Td>
                        <Table.Td>
                          <Text fz="xs" lineClamp={2} maw={200}>
                            {q?.title?.[locale] ?? b.questionId.slice(0, 8)}
                          </Text>
                        </Table.Td>
                        <Table.Td><Text fz="sm" fw={600}>{q?.points ?? '—'}</Text></Table.Td>
                        <Table.Td>
                          <TextInput
                            size="xs"
                            type="number"
                            style={{ width: 80 }}
                            value={b.score}
                            onChange={(e) => {
                              const updated = [...detailBreakdowns];
                              updated[i] = { ...updated[i], score: Number(e.currentTarget.value) };
                              setDetailBreakdowns(updated);
                            }}
                          />
                        </Table.Td>
                        <Table.Td>
                          <TextInput
                            size="xs"
                            placeholder="Optional"
                            value={b.remark ?? ''}
                            onChange={(e) => {
                              const updated = [...detailBreakdowns];
                              updated[i] = { ...updated[i], remark: e.currentTarget.value || undefined };
                              setDetailBreakdowns(updated);
                            }}
                          />
                        </Table.Td>
                      </Table.Tr>
                    );})}
                  </Table.Tbody>
                </Table>
              </>
            )}

            <ModalFooter>
              <Button variant="default" onClick={handleDetailClose} size="sm">{t('result.close')}</Button>
              <Button
                onClick={handleDetailSave}
                size="sm"
                loading={detailSaving}
                leftSection={<IconDeviceFloppy size={15} />}
              >
                {t('result.save')}
              </Button>
            </ModalFooter>
          </Stack>
        ) : (
          <Text c="dimmed" ta="center" py="xl">{t('result.noData')}</Text>
        )}
      </Modal>

      {/* Moderation, approval and return — the quality-control chain */}
      <Modal
        opened={Boolean(qcTarget)}
        onClose={() => setQcTarget(null)}
        title={t(`result.review.${qcAction}`)}
        size="md"
        radius="lg"
      >
        <Stack gap="sm">
          <Text fz="sm">
            {qcTarget?.seafarer
              ? `${qcTarget.seafarer.firstName} ${qcTarget.seafarer.lastName}`
              : qcTarget?.seafarerId.slice(0, 8)}{' '}
            · {qcTarget ? getExamTitle(qcTarget.examId) : ''} · {qcTarget?.totalScore}
          </Text>
          {qcAction === 'moderate' && (
            <TextInput
              label={t('result.review.adjustment')}
              description={t('result.review.adjustmentHint')}
              type="number"
              value={qcAdjustment}
              onChange={(e) => setQcAdjustment(Number(e.currentTarget.value))}
              size="sm"
            />
          )}
          <TextInput
            label={t('result.review.remark')}
            value={qcRemark}
            onChange={(e) => setQcRemark(e.currentTarget.value)}
            size="sm"
            required
          />
          <Group justify="flex-end">
            <Button variant="default" size="sm" onClick={() => setQcTarget(null)}>
              {t('result.cancel')}
            </Button>
            <Button
              size="sm"
              loading={isModerating || isApproving || isReturning}
              onClick={runQc}
            >
              {t(`result.review.${qcAction}`)}
            </Button>
          </Group>
        </Stack>
      </Modal>

      <Modal opened={deleteOpened} onClose={closeDelete} title={t('result.confirmDelete')} size="sm">
        <Text mb="md">{t('result.deleteConfirmText')}</Text>
        <ModalFooter>
          <Button variant="default" onClick={closeDelete} size="sm">{t('result.cancel')}</Button>
          <Button color="red" onClick={handleDelete} size="sm">{t('result.delete')}</Button>
        </ModalFooter>
      </Modal>

      {/* Choose exam, then record */}
      <Modal opened={pickerOpened} onClose={closePicker} title={t('result.record')} size="md" radius="lg">
        <Stack gap="md">
          <Text fz="sm" c="dimmed">{t('result.detail.selectExam')}</Text>
          <Select
            label={t('result.detail.exam')}
            placeholder={t('result.detail.selectExamPlaceholder')}
            data={examOptions}
            value={pickerExamId}
            onChange={setPickerExamId}
            size="sm"
            searchable
            required
          />
          <ModalFooter>
            <Button variant="default" onClick={closePicker} size="sm">{t('result.cancel')}</Button>
            <Button onClick={startRecord} size="sm" disabled={!pickerExamId}>{t('result.continue')}</Button>
          </ModalFooter>
        </Stack>
      </Modal>

      {recordExam && (
        <RecordResultModal exam={recordExam} opened={recordOpened} onClose={handleRecordClose} />
      )}
    </Stack>
  );
}
