'use client';

import { useEffect, useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { format } from 'date-fns';
import { ExternalLink, FileText } from 'lucide-react';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Spinner } from '@/components/ui/spinners';
import { setCreatorVerificationStatus } from '@/network/apis/dashboard/marketplace/creator-verifications.apis';
import type {
  CreatorVerification,
  CreatorVerificationStatus,
} from '@/network/apis/dashboard/marketplace/creator-verifications.types';
import { StatusPill } from './StatusPill';
import { CopyButton } from './CopyButton';

/**
 * What each status is set for. The creator sees the Arabic equivalents:
 * قيد المراجعة, بحاجة إلى استكمال, تم التوثيق, تم الرفض.
 */
const STATUS_ACTIONS: {
  status: CreatorVerificationStatus;
  label: string;
  variant: 'primary' | 'outline' | 'destructive';
  /** Needs a note the creator reads. */
  note?: { title: string; description: string; placeholder: string; confirm: string };
}[] = [
  { status: 'approved', label: 'Verify account', variant: 'primary' },
  {
    status: 'needs_completion',
    label: 'Needs completion',
    variant: 'outline',
    note: {
      title: 'Ask the creator to complete this',
      description:
        'Shown to the creator. Say exactly which details or documents are missing.',
      placeholder: 'e.g. Please upload the back of your ID card and add your postal code.',
      confirm: 'Send to creator',
    },
  },
  {
    status: 'rejected',
    label: 'Reject',
    variant: 'destructive',
    note: {
      title: 'Reject this verification',
      description:
        'The reason is shown to the creator, so write what they need to fix rather than a code.',
      placeholder: 'e.g. The ID photo is blurred and the number cannot be read.',
      confirm: 'Reject',
    },
  },
  { status: 'pending', label: 'Back to review', variant: 'outline' },
];

const STATUS_DONE: Record<CreatorVerificationStatus, string> = {
  approved: 'Account verified.',
  needs_completion: 'Creator asked to complete the verification.',
  rejected: 'Verification rejected.',
  pending: 'Verification moved back to review.',
};

const safeFormat = (value: string | null | undefined) => {
  if (!value) return '—';
  const d = new Date(value);
  return Number.isNaN(d.getTime()) ? value : format(d, 'dd MMM yyyy, HH:mm');
};

/** Dates the creator typed are plain dates; showing a time beside them invents one. */
const dateOnly = (value: string | null | undefined) => {
  if (!value) return '—';
  const d = new Date(value);
  return Number.isNaN(d.getTime()) ? value : format(d, 'dd MMM yyyy');
};

function Field({
  label,
  value,
  copyable,
  mismatch,
}: {
  label: string;
  value: string | null | undefined;
  copyable?: boolean;
  /** Draws attention where two values that should agree do not. */
  mismatch?: boolean;
}) {
  return (
    <div className="space-y-1">
      <p className="text-xs font-medium text-muted-foreground">{label}</p>
      <div className="flex items-center gap-1.5">
        <p
          className={`text-sm ${mismatch ? 'text-amber-700 font-semibold' : ''}`}
        >
          {value || '—'}
        </p>
        {copyable && value ? <CopyButton value={value} /> : null}
      </div>
    </div>
  );
}

/**
 * One creator's identity submission, and the decision on it.
 *
 * Everything they typed is shown, because verifying is comparing a form to a
 * document and a field left out of the panel is a field nobody checked. The
 * account's own name sits beside the name on the form and is highlighted when
 * the two differ — that mismatch is the single thing this review exists to
 * catch, and asking a reviewer to spot it by eye across two panels is how it
 * gets missed.
 */
export function CreatorVerificationDetailSheet({
  verification,
  open,
  onClose,
}: {
  verification: CreatorVerification | null;
  open: boolean;
  onClose: () => void;
}) {
  const qc = useQueryClient();
  // The status waiting on a note, while its dialog is open.
  const [noteFor, setNoteFor] = useState<CreatorVerificationStatus | null>(null);
  const [reason, setReason] = useState('');

  useEffect(() => {
    if (!open) {
      setNoteFor(null);
      setReason('');
    }
  }, [open]);

  const done = (message: string) => {
    toast.success(message);
    qc.invalidateQueries({ queryKey: ['creator-verifications'] });
    onClose();
  };

  const fail = (e: any) =>
    toast.error(
      e?.response?.data?.message ?? 'Something went wrong. Please try again.',
    );

  const change = useMutation({
    mutationFn: ({
      status,
      note,
    }: {
      status: CreatorVerificationStatus;
      note?: string;
    }) => setCreatorVerificationStatus(verification!.id, status, note),
    onSuccess: (_data, vars) => {
      setNoteFor(null);
      setReason('');
      done(STATUS_DONE[vars.status]);
    },
    onError: fail,
  });

  if (!verification) return null;

  const v = verification;
  const pending = v.status === 'pending';
  const busy = change.isPending;
  const noteAction = STATUS_ACTIONS.find((a) => a.status === noteFor)?.note;

  // The name on the ID against the name on the account.
  const accountName = v.creator?.name ?? null;
  const nameMismatch =
    !!accountName &&
    !!v.full_name &&
    accountName.trim().toLowerCase() !== v.full_name.trim().toLowerCase();

  const address = v.address ?? ({} as CreatorVerification['address']);
  const addressLine = [
    address.city,
    address.district,
    address.street,
    address.building_number,
    address.postal_code,
  ]
    .filter(Boolean)
    .join(' · ');

  return (
    <>
      <Sheet open={open} onOpenChange={(o) => !o && onClose()}>
        <SheetContent className="w-full sm:max-w-xl overflow-y-auto">
          <SheetHeader>
            <SheetTitle className="flex items-center gap-2">
              {v.full_name || 'Verification'}
              <StatusPill status={v.status} />
            </SheetTitle>
            <SheetDescription>
              Submitted {safeFormat(v.submitted_at)}
            </SheetDescription>
          </SheetHeader>

          <div className="space-y-6 py-4">
            <section className="space-y-3">
              <h3 className="text-sm font-semibold">Account</h3>
              <div className="grid grid-cols-2 gap-4">
                <Field
                  label="Account name"
                  value={accountName}
                  mismatch={nameMismatch}
                />
                <Field label="Email" value={v.creator?.email} copyable />
                <Field label="Phone" value={v.creator?.phone} copyable />
                <Field
                  label="Creator ID"
                  value={v.creator_id ? String(v.creator_id) : null}
                />
              </div>
              {nameMismatch && (
                <p className="text-xs text-amber-700">
                  The account name and the name on the ID do not match. Confirm
                  against the document before verifying.
                </p>
              )}
            </section>

            <section className="space-y-3">
              <h3 className="text-sm font-semibold">Identity</h3>
              <div className="grid grid-cols-2 gap-4">
                <Field
                  label="Full name (as on ID)"
                  value={v.full_name}
                  mismatch={nameMismatch}
                />
                <Field label="Nationality" value={v.nationality} />
                <Field
                  label="Date of birth"
                  value={dateOnly(v.date_of_birth)}
                />
                {/* Derived, so it is right on the day it is read rather than
                    the day the form was filled in. */}
                <Field
                  label="Age"
                  value={v.age != null ? String(v.age) : null}
                />
                <Field label="ID type" value={v.id_type} />
                <Field label="ID number" value={v.id_number} copyable />
                <Field label="Issued" value={dateOnly(v.issuing_date)} />
                <Field label="Expires" value={dateOnly(v.expiration_date)} />
              </div>
            </section>

            <section className="space-y-3">
              <h3 className="text-sm font-semibold">National address</h3>
              <div className="grid grid-cols-2 gap-4">
                <Field label="City" value={address.city} />
                <Field label="District" value={address.district} />
                <Field label="Street" value={address.street} />
                <Field
                  label="Short address"
                  value={address.short_address}
                  copyable
                />
                <Field label="Building number" value={address.building_number} />
                <Field
                  label="Additional number"
                  value={address.additional_number}
                />
                <Field label="Postal code" value={address.postal_code} />
              </div>
              {addressLine && (
                <p className="text-xs text-muted-foreground">{addressLine}</p>
              )}
            </section>

            <section className="space-y-3">
              <h3 className="text-sm font-semibold">Documents</h3>
              {v.documents?.length ? (
                <div className="space-y-2">
                  {v.documents.map((url, i) => (
                    <a
                      key={url}
                      href={url}
                      target="_blank"
                      rel="noreferrer"
                      className="flex items-center gap-2 rounded-md border px-3 py-2 text-sm hover:bg-muted"
                    >
                      <FileText className="h-4 w-4 shrink-0" />
                      <span className="truncate flex-1">
                        Document {i + 1}
                      </span>
                      <ExternalLink className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                    </a>
                  ))}
                </div>
              ) : (
                // Worth saying plainly: there is nothing to check the form
                // against, which is a reason to reject rather than an oversight.
                <p className="text-sm text-amber-700">
                  No document was uploaded. There is nothing here to verify the
                  identity against.
                </p>
              )}
            </section>

            {!pending && (
              <section className="space-y-3 rounded-md border p-3">
                <h3 className="text-sm font-semibold">Review</h3>
                <div className="grid grid-cols-2 gap-4">
                  <Field label="Decided" value={safeFormat(v.reviewed_at)} />
                  <Field label="By" value={v.reviewer?.name ?? null} />
                </div>
                {v.rejection_reason && (
                  <div className="space-y-1">
                    <p className="text-xs font-medium text-muted-foreground">
                      Note shown to the creator
                    </p>
                    <p className="text-sm">{v.rejection_reason}</p>
                  </div>
                )}
              </section>
            )}
          </div>

          {/*
            The status is the admin's to control: every status other than the
            current one is offered, whenever the sheet is open. A verification
            used to be decided once and then locked, so a mistaken approval, or
            an ID that expired after it, could not be corrected.
          */}
          <div className="space-y-2 border-t pt-4">
            <p className="text-xs font-medium text-muted-foreground">
              Change status
            </p>
            <div className="grid grid-cols-2 gap-2">
              {STATUS_ACTIONS.filter((act) => act.status !== v.status).map((act) => (
                <Button
                  key={act.status}
                  variant={act.variant}
                  disabled={busy}
                  onClick={() =>
                    act.note ? setNoteFor(act.status) : change.mutate({ status: act.status })
                  }
                >
                  {change.isPending && change.variables?.status === act.status ? (
                    <Spinner className="h-4 w-4" />
                  ) : (
                    act.label
                  )}
                </Button>
              ))}
            </div>
          </div>
        </SheetContent>
      </Sheet>

      <Dialog open={!!noteFor} onOpenChange={(o) => !o && setNoteFor(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{noteAction?.title}</DialogTitle>
            <DialogDescription>{noteAction?.description}</DialogDescription>
          </DialogHeader>
          <div className="space-y-2">
            <Label htmlFor="cv-reason">Note to the creator</Label>
            <Textarea
              id="cv-reason"
              rows={4}
              value={reason}
              onChange={(e) => setReason(e.target.value)}
              placeholder={noteAction?.placeholder}
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setNoteFor(null)}>
              Cancel
            </Button>
            <Button
              variant={noteFor === 'rejected' ? 'destructive' : 'primary'}
              disabled={reason.trim().length < 3 || change.isPending}
              onClick={() =>
                noteFor && change.mutate({ status: noteFor, note: reason.trim() })
              }
            >
              {change.isPending ? <Spinner className="h-4 w-4" /> : noteAction?.confirm}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
