'use client';
import { useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import { useLocale, useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import {
  Box,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Skeleton,
  Stack,
  TextField,
  Typography,
} from '@mui/material';
import { AppButton, StatusChip } from '@/components';
import type { StatusKind } from '@/components';
import {
  AdminEmptyState,
  AdminErrorState,
  AdminPageHeader,
  ConfirmDialog,
  DocumentViewer,
} from '@/components/admin';
import { ROUTES } from '@/constants';
import { formatShamsiDate } from '@/utils';
import { useAdminCapabilities } from '@/hooks';
import {
  useApproveVerification,
  useDecideStep,
  useRejectVerification,
  useVerificationCase,
} from '@/services/verification';
import type { AdminVerificationStepDetail, VerificationStepStatus } from '@/services/verification/types';

/** The three credential-bearing step types — a Pass here opens the structured credential form. */
const CREDENTIAL_STEP_CODES: readonly string[] = ['moh_competency_license', 'ino_membership', 'criminal_record'];

/** Per-step status → chip kind. `expired`/`failed` read red; `in_review`/`pending` amber; `passed` green. */
const STEP_STATUS_KIND: Record<VerificationStepStatus, StatusKind> = {
  not_started: 'neutral',
  pending: 'pending',
  in_review: 'pending',
  passed: 'verified',
  failed: 'rejected',
  expired: 'rejected',
};

/**
 * Verification case (b6 `AdminVerificationsController`) — the trust desk works one nurse: the identity on
 * file for cross-check, every step with its status + documents (each `DocumentViewer` re-signs its own
 * short-lived URL on demand), and the manual-step decisions. A credential-bearing step records the
 * (encrypted) credential via a structured form; recorded credentials are listed by **type** only — the
 * number never crosses the wire. The whole verification is approvable only when every required step has
 * passed; a decision re-aggregates server-side (flipping `is_verified`) and removes the case from the queue.
 */
export default function AdminVerificationCasePage() {
  const t = useTranslations('admin');
  const locale = useLocale();
  const router = useRouter();
  const params = useParams<{ nurseId: string }>();
  const nurseVerificationId = Number(params?.nurseId);
  const caps = useAdminCapabilities();
  const { enqueueSnackbar } = useSnackbar();

  const { data, isLoading, isError, refetch } = useVerificationCase(
    Number.isFinite(nurseVerificationId) ? nurseVerificationId : null,
  );
  const approve = useApproveVerification();
  const reject = useRejectVerification();

  const [approveOpen, setApproveOpen] = useState(false);
  const [rejectOpen, setRejectOpen] = useState(false);

  const backToQueue = () => router.push(`/${locale}${ROUTES.ADMIN_VERIFICATION}`);

  const allPassed = !!data && data.steps.length > 0 && data.steps.every((step) => step.status === 'passed');

  const onApprove = () => {
    approve.mutate(nurseVerificationId, {
      onSuccess: () => {
        enqueueSnackbar(t('ver_decided'), { variant: 'success' });
        setApproveOpen(false);
        backToQueue();
      },
    });
  };

  const onReject = (reason?: string) => {
    reject.mutate(
      { nurseVerificationId, reason: reason ?? '' },
      {
        onSuccess: () => {
          enqueueSnackbar(t('ver_decided'), { variant: 'success' });
          setRejectOpen(false);
          backToQueue();
        },
      },
    );
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <Stack sx={{ gap: 1 }}>
        <AppButton variant="text" color="primary" onClick={backToQueue} sx={{ alignSelf: 'flex-start' }}>
          {t('back')}
        </AppButton>
        <AdminPageHeader title={t('ver_case_title')} />
      </Stack>

      {isLoading ? (
        <Stack sx={{ gap: 2 }}>
          <Skeleton variant="rounded" height={72} />
          <Skeleton variant="rounded" height={220} />
          <Skeleton variant="rounded" height={160} />
        </Stack>
      ) : isError ? (
        <AdminErrorState message={t('error_generic')} retryLabel={t('retry')} onRetry={() => refetch()} />
      ) : !data ? (
        <AdminEmptyState icon="verified" title={t('ver_empty')} />
      ) : (
        <>
          <Box sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, p: 2 }}>
            <Typography variant="body2" sx={{ color: 'text.secondary' }}>
              {t('ver_identity_name')}
            </Typography>
            <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
              {data.identityName}
            </Typography>
          </Box>

          <Stack sx={{ gap: 1.5 }}>
            <Typography variant="h6">{t('ver_steps_title')}</Typography>
            {data.steps.map((step) => (
              <StepCard
                key={step.id}
                step={step}
                nurseVerificationId={nurseVerificationId}
                canVerify={caps.canVerify}
              />
            ))}
          </Stack>

          {data.credentials.length > 0 ? (
            <Stack sx={{ gap: 1.5 }}>
              <Typography variant="h6">{t('ver_credentials_title')}</Typography>
              {data.credentials.map((cred) => (
                <Box key={cred.id} sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, p: 1.75 }}>
                  <Stack
                    direction="row"
                    sx={{ justifyContent: 'space-between', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}
                  >
                    <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
                      {t(`step_${cred.credentialType}`)}
                    </Typography>
                    {cred.expiresAt ? (
                      <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                        {t('ver_expires_at')}: {formatShamsiDate(cred.expiresAt, locale)}
                      </Typography>
                    ) : null}
                  </Stack>
                  <Typography variant="body2">{cred.holderNameSnapshot}</Typography>
                  <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                    {cred.issuingAuthority}
                  </Typography>
                </Box>
              ))}
            </Stack>
          ) : null}

          <Stack sx={{ gap: 0.5 }}>
            <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
              <AppButton
                variant="contained"
                color="primary"
                onClick={() => setApproveOpen(true)}
                disabled={!allPassed || !caps.canVerify}
              >
                {t('ver_approve')}
              </AppButton>
              <AppButton
                variant="outlined"
                color="error"
                onClick={() => setRejectOpen(true)}
                disabled={!caps.canVerify}
              >
                {t('ver_reject_all')}
              </AppButton>
            </Stack>
            <Typography variant="caption" sx={{ color: 'text.secondary' }}>
              {t('ver_approve_hint')}
            </Typography>
          </Stack>
        </>
      )}

      <ConfirmDialog
        open={approveOpen}
        title={t('ver_approve')}
        body={t('ver_approve_confirm')}
        confirmLabel={t('confirm')}
        cancelLabel={t('cancel')}
        onConfirm={onApprove}
        onClose={() => setApproveOpen(false)}
        loading={approve.isPending}
      />
      <ConfirmDialog
        open={rejectOpen}
        title={t('ver_reject_all')}
        body={t('ver_reject_confirm')}
        confirmLabel={t('ver_reject_all')}
        cancelLabel={t('cancel')}
        onConfirm={onReject}
        onClose={() => setRejectOpen(false)}
        loading={reject.isPending}
        requireReason
        reasonLabel={t('reason_label')}
        reasonPlaceholder={t('ver_reject_reason_ph')}
        confirmColor="error"
      />
    </Box>
  );
}

/** One step of the case: label + status chip (+ automated badge), its documents, and — for a decidable
 * manual step — Pass / Reject. A credential-bearing Pass opens the structured credential form. */
function StepCard({
  step,
  nurseVerificationId,
  canVerify,
}: {
  step: AdminVerificationStepDetail;
  nurseVerificationId: number;
  canVerify: boolean;
}) {
  const t = useTranslations('admin');
  const { enqueueSnackbar } = useSnackbar();
  const decide = useDecideStep();
  const [rejectOpen, setRejectOpen] = useState(false);
  const [credentialOpen, setCredentialOpen] = useState(false);

  const isManual = !step.isAutomated;
  const isCredentialStep = CREDENTIAL_STEP_CODES.includes(step.code);
  const isDecidable = isManual && (step.status === 'in_review' || step.status === 'pending');

  const onPass = () => {
    decide.mutate(
      { stepId: step.id, nurseVerificationId, input: { approve: true } },
      { onSuccess: () => enqueueSnackbar(t('ver_decided'), { variant: 'success' }) },
    );
  };

  const onReject = (reason?: string) => {
    decide.mutate(
      { stepId: step.id, nurseVerificationId, input: { approve: false, rejectionReason: reason ?? '' } },
      {
        onSuccess: () => {
          enqueueSnackbar(t('ver_decided'), { variant: 'success' });
          setRejectOpen(false);
        },
      },
    );
  };

  return (
    <Box sx={{ border: '1px solid', borderColor: 'divider', borderRadius: 2, p: 2 }}>
      <Stack direction="row" sx={{ gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
        <Typography variant="subtitle1" sx={{ fontWeight: 700, flexGrow: 1 }}>
          {t(`step_${step.code}`)}
        </Typography>
        <StatusChip status={STEP_STATUS_KIND[step.status]} label={t(`step_${step.status}`)} />
        {step.isAutomated ? (
          <Chip size="small" label={t('ver_automated_badge')} sx={{ bgcolor: 'action.hover', fontWeight: 500 }} />
        ) : null}
      </Stack>

      {step.documents.length > 0 ? (
        <Stack sx={{ gap: 1.5, mt: 1.5 }}>
          {step.documents.map((doc) => (
            <DocumentViewer key={doc.id} document={doc} />
          ))}
        </Stack>
      ) : isManual ? (
        <Typography variant="body2" sx={{ color: 'text.secondary', mt: 1 }}>
          {t('ver_no_documents')}
        </Typography>
      ) : null}

      {step.failureReason ? (
        <Typography variant="caption" sx={{ color: 'var(--bal-error)', mt: 1, display: 'block' }}>
          {step.failureReason}
        </Typography>
      ) : null}

      {isDecidable && canVerify ? (
        <Stack direction="row" sx={{ gap: 1, mt: 1.5, flexWrap: 'wrap' }}>
          <AppButton
            variant="contained"
            color="primary"
            onClick={() => (isCredentialStep ? setCredentialOpen(true) : onPass())}
            disabled={decide.isPending}
          >
            {t('ver_pass')}
          </AppButton>
          <AppButton
            variant="outlined"
            color="error"
            onClick={() => setRejectOpen(true)}
            disabled={decide.isPending}
          >
            {t('ver_reject')}
          </AppButton>
        </Stack>
      ) : null}

      <ConfirmDialog
        open={rejectOpen}
        title={t('ver_reject_step')}
        confirmLabel={t('ver_reject')}
        cancelLabel={t('cancel')}
        onConfirm={onReject}
        onClose={() => setRejectOpen(false)}
        loading={decide.isPending}
        requireReason
        reasonLabel={t('reason_label')}
        reasonPlaceholder={t('ver_reject_reason_ph')}
        confirmColor="error"
      />

      {isCredentialStep && credentialOpen ? (
        <CredentialDialog step={step} nurseVerificationId={nurseVerificationId} onClose={() => setCredentialOpen(false)} />
      ) : null}
    </Box>
  );
}

/** The structured credential form recorded on approving a credential-bearing step. `criminal_record`
 * requires an expiry date; `credentialNumber` is accepted as input and never echoed back. */
function CredentialDialog({
  step,
  nurseVerificationId,
  onClose,
}: {
  step: AdminVerificationStepDetail;
  nurseVerificationId: number;
  onClose: () => void;
}) {
  const t = useTranslations('admin');
  const { enqueueSnackbar } = useSnackbar();
  const decide = useDecideStep();
  const [credentialNumber, setCredentialNumber] = useState('');
  const [holderName, setHolderName] = useState('');
  const [issuingAuthority, setIssuingAuthority] = useState('');
  const [issuedAt, setIssuedAt] = useState('');
  const [expiresAt, setExpiresAt] = useState('');

  const expiryRequired = step.code === 'criminal_record';
  const expiryMissing = expiryRequired && expiresAt.trim().length === 0;

  const onSubmit = () => {
    if (expiryMissing) return;
    decide.mutate(
      {
        stepId: step.id,
        nurseVerificationId,
        input: {
          approve: true,
          credentialNumber: credentialNumber.trim() || undefined,
          holderName: holderName.trim() || undefined,
          issuingAuthority: issuingAuthority.trim() || undefined,
          issuedAt: issuedAt || undefined,
          expiresAt: expiresAt || undefined,
        },
      },
      {
        onSuccess: () => {
          enqueueSnackbar(t('ver_decided'), { variant: 'success' });
          onClose();
        },
      },
    );
  };

  return (
    <Dialog open onClose={decide.isPending ? undefined : onClose} fullWidth maxWidth="sm">
      <DialogTitle sx={{ fontWeight: 800 }}>{t('ver_credential_title')}</DialogTitle>
      <DialogContent>
        <Stack sx={{ gap: 2, mt: 1 }}>
          <TextField
            fullWidth
            autoFocus
            label={t('ver_credential_number')}
            value={credentialNumber}
            onChange={(e) => setCredentialNumber(e.target.value)}
          />
          <TextField
            fullWidth
            label={t('ver_holder_name')}
            helperText={t('ver_holder_hint')}
            value={holderName}
            onChange={(e) => setHolderName(e.target.value)}
          />
          <TextField
            fullWidth
            label={t('ver_issuing_authority')}
            value={issuingAuthority}
            onChange={(e) => setIssuingAuthority(e.target.value)}
          />
          <TextField
            fullWidth
            type="date"
            label={t('ver_issued_at')}
            value={issuedAt}
            onChange={(e) => setIssuedAt(e.target.value)}
            slotProps={{ inputLabel: { shrink: true } }}
          />
          <TextField
            fullWidth
            type="date"
            label={t('ver_expires_at')}
            value={expiresAt}
            onChange={(e) => setExpiresAt(e.target.value)}
            required={expiryRequired}
            error={expiryMissing}
            helperText={expiryMissing ? t('ver_expiry_required') : undefined}
            slotProps={{ inputLabel: { shrink: true } }}
          />
        </Stack>
      </DialogContent>
      <DialogActions sx={{ px: 3, pb: 2 }}>
        <AppButton variant="text" color="inherit" onClick={onClose} disabled={decide.isPending}>
          {t('cancel')}
        </AppButton>
        <AppButton
          variant="contained"
          color="primary"
          onClick={onSubmit}
          disabled={decide.isPending || expiryMissing}
        >
          {decide.isPending ? t('saving') : t('save')}
        </AppButton>
      </DialogActions>
    </Dialog>
  );
}
