import { useState, useCallback, type ElementType } from 'react';
import { useTranslation } from 'react-i18next';
import {Stack, Group, Table, Badge, Modal, Text, Paper, Loader, Center, Select, SimpleGrid, Divider, Button, ThemeIcon, TextInput} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import {IconUser, IconCertificate, IconDeviceFloppy, IconPlus, IconClipboardList, IconCircleCheck, IconCircleX, IconChartBar, IconSearch, IconSend} from '@tabler/icons-react';
import { AdvancedTable, BilingualInput, ErrorState, ModalFooter, notify, PageHeader, StatusBadge, useErrorHandler, useServerTable } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import type { BilingualValue } from '@ema-platform/ui';
import { extractErrorMessage, useLocalized } from '@ema-platform/api';
import { LICENSE_PERMISSIONS, RequirePermission } from '@ema-platform/auth';
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 } from '../../types/result';
import type { Exam } from '../../../exam/types/exam';
import { resultColumns, STATUS_TONE, REVIEW_COLOR } from './columns';
import { resultActionsColumn, type QcAction } from './actions';

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 localized = useLocalized();
  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 [publishTarget, setPublishTarget] = useState<Result | null>(null);
  const [publishOpened, { open: openPublish, close: closePublish }] = 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: `${localized(e.title)} (${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')));
    }
  };

  /** Same publish call as handlePublish, but scoped to one row's exam — no page filter needed. */
  const handleConfirmPublish = async () => {
    if (!publishTarget) return;
    try {
      const outcome = await publishResults(publishTarget.examId).unwrap();
      notify.success(t('result.review.publishedCount', outcome));
      closePublish();
      setPublishTarget(null);
    } 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 <ErrorState title={t('result.loadError')} onRetry={refetch} />;

  const columns = [
    ...resultColumns(t, locale, showDate, getExamTitle),
    resultActionsColumn(t, {
      onQc: openQc,
      onViewDetail: viewDetail,
      onDelete: (r) => { setDeleteTarget(r); openDelete(); },
      onPublish: (r) => { setPublishTarget(r); openPublish(); },
    }),
  ];

  const page = paginate(filtered);

  return (
    <Stack gap="lg">
      <PageHeader
        title={t('result.title')}
        subtitle={t('result.subtitle')}
        noMargin
        action={
          <Group gap="sm">
          <RequirePermission anyOf={[LICENSE_PERMISSIONS.PUBLISH_EXAM_RESULT]} hideOnly>
            <Button
              variant="light"
              color="teal"
              size="sm"
              loading={isPublishing}
              disabled={!examFilter}
              leftSection={<IconSend size={15} />}
              onClick={handlePublish}
            >
              {t('result.review.publish')}
            </Button>
          </RequirePermission>
          <RequirePermission anyOf={[LICENSE_PERMISSIONS.RECORD_EXAM_RESULT]} hideOnly>
            <Button leftSection={<IconPlus size={15} />} onClick={openPicker} size="sm">
              {t('result.record')}
            </Button>
          </RequirePermission>
          </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>

      <AdvancedTable
        columns={columns}
        data={page.rows}
        title={t('result.section')}
        tableName={t('result.title')}
        toolbar={
          <>
            <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
            />
          </>
        }
        itemCount={page.itemCount}
        pageIndex={page.pageIndex}
        onPageChange={setPageIndex}
        pageSize={pageSize}
        onPageSizeChange={setPageSize}
        refresh={refetch}
        isLoading={isFetching}
        emptyText={t('result.noItems')}
      />

      <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}>
                <StatusBadge
                  tone={STATUS_TONE[detailResult.status]}
                  label={t(`result.status.${detailResult.status}`)}
                />
                <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>
              <RequirePermission
                anyOf={[
                  LICENSE_PERMISSIONS.RECORD_EXAM_RESULT,
                  LICENSE_PERMISSIONS.MODERATE_EXAM_RESULT,
                ]}
                hideOnly
              >
                <Button
                  onClick={handleDetailSave}
                  size="sm"
                  loading={detailSaving}
                  leftSection={<IconDeviceFloppy size={15} />}
                >
                  {t('result.save')}
                </Button>
              </RequirePermission>
            </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>

      <Modal opened={publishOpened} onClose={closePublish} title={t('result.review.publish')} size="sm">
        <Text mb="md">
          {t('result.review.publishConfirmText', {
            exam: publishTarget ? getExamTitle(publishTarget.examId) : '',
          })}
        </Text>
        <ModalFooter>
          <Button variant="default" onClick={closePublish} size="sm">{t('result.cancel')}</Button>
          <Button color="teal" loading={isPublishing} onClick={handleConfirmPublish} size="sm">
            {t('result.review.publish')}
          </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>
  );
}
