'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { format } from 'date-fns';
import { ExternalLink, CreditCard, Banknote } 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 {
  approveWalletCharge,
  rejectWalletCharge,
} from '@/network/apis/dashboard/marketplace/wallets.apis';
import {
  WalletCharge,
  WalletChargeStatus,
} from '@/network/apis/dashboard/marketplace/wallets.types';

const STATUS_PILL: Record<WalletChargeStatus, string> = {
  pending: 'bg-amber-100 text-amber-800 border-amber-200',
  approved: 'bg-emerald-100 text-emerald-700 border-emerald-200',
  rejected: 'bg-red-100 text-red-700 border-red-200',
};

const safeFormat = (value: string | null | undefined) => {
  if (!value) return '—';
  try {
    return format(new Date(value), 'PP p');
  } catch {
    return value;
  }
};

const formatMoney = (amount: number, currency: string) =>
  new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: currency || 'SAR',
    maximumFractionDigits: 2,
  }).format(amount);

export function WalletChargeDetailSheet({
  charge,
  open,
  onClose,
}: {
  charge: WalletCharge | null;
  open: boolean;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const [confirmKind, setConfirmKind] = useState<'approve' | 'reject' | null>(
    null,
  );
  const [rejectionReason, setRejectionReason] = useState('');
  const [adminNotes, setAdminNotes] = useState('');
  const [approveAdminNotes, setApproveAdminNotes] = useState('');
  const [reasonError, setReasonError] = useState<string | null>(null);

  useEffect(() => {
    setRejectionReason('');
    setAdminNotes('');
    setApproveAdminNotes('');
    setReasonError(null);
    setConfirmKind(null);
  }, [charge?.id]);

  const invalidate = () => {
    queryClient.invalidateQueries({ queryKey: ['wallet-charges'] });
    queryClient.invalidateQueries({ queryKey: ['wallet-charges-kpi'] });
    if (charge?.brand_id) {
      queryClient.invalidateQueries({
        queryKey: ['brand-wallet', charge.brand_id],
      });
      queryClient.invalidateQueries({
        queryKey: ['brand-wallet-tx', charge.brand_id],
      });
    }
  };

  const handleError = (error: unknown, fallback: string) => {
    const resp = (error as { response?: { data?: { message?: string; errors?: Record<string, string[]> } } })
      ?.response?.data;
    const fieldMsg =
      resp?.errors?.rejection_reason?.[0] ||
      resp?.errors?.admin_notes?.[0];
    if (fieldMsg) {
      setReasonError(fieldMsg);
      toast.error(fieldMsg);
      return;
    }
    toast.error(resp?.message || fallback);
  };

  const approveMutation = useMutation({
    mutationFn: (id: number) =>
      approveWalletCharge(id, {
        admin_notes: approveAdminNotes.trim() || undefined,
      }),
    onSuccess: (data) => {
      toast.success(
        `Charge approved. ${formatMoney(data.amount, data.currency)} credited.`,
      );
      invalidate();
      setConfirmKind(null);
      onClose();
    },
    onError: (e) => handleError(e, 'Failed to approve charge'),
  });

  const rejectMutation = useMutation({
    mutationFn: (id: number) =>
      rejectWalletCharge(id, {
        rejection_reason: rejectionReason.trim(),
        admin_notes: adminNotes.trim() || undefined,
      }),
    onSuccess: () => {
      toast.success('Charge rejected.');
      invalidate();
      setConfirmKind(null);
      onClose();
    },
    onError: (e) => handleError(e, 'Failed to reject charge'),
  });

  if (!charge) return null;

  const isBank = charge.payment_method === 'bank_transfer';
  const canAct = charge.status === 'pending';
  const submitting =
    approveMutation.isPending || rejectMutation.isPending;
  const reasonLen = rejectionReason.trim().length;
  const reasonValid = reasonLen >= 3 && reasonLen <= 1000;

  return (
    <>
      <Sheet open={open} onOpenChange={(o) => !o && onClose()}>
        <SheetContent
          side="right"
          className="w-full sm:max-w-xl overflow-y-auto"
        >
          <SheetHeader>
            <SheetTitle className="flex items-center gap-3">
              Top-up #{charge.id}
              <span
                className={`inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium capitalize ${STATUS_PILL[charge.status]}`}
              >
                {charge.status}
              </span>
            </SheetTitle>
            <SheetDescription>
              Submitted {safeFormat(charge.created_at)}
            </SheetDescription>
          </SheetHeader>

          <div className="space-y-6 px-4 pb-6">
            {/* Amount + brand */}
            <div className="rounded-lg border p-4 space-y-3">
              <div>
                <div className="text-xs uppercase text-muted-foreground">
                  Amount
                </div>
                <div className="text-2xl font-semibold">
                  {formatMoney(charge.amount, charge.currency)}
                </div>
              </div>
              <div className="flex items-start justify-between gap-3 pt-2 border-t">
                <div>
                  <div className="text-xs text-muted-foreground">Brand</div>
                  <div className="font-medium">
                    {charge.brand_name || `Brand #${charge.brand_id}`}
                  </div>
                  {charge.brand_email ? (
                    <div className="text-xs text-muted-foreground">
                      {charge.brand_email}
                    </div>
                  ) : null}
                </div>
                <Button variant="outline" size="sm" asChild>
                  <Link
                    href={`/marketplace-admin/money/brand-wallets/${charge.brand_id}`}
                  >
                    <ExternalLink className="size-4 mr-1" />
                    Wallet
                  </Link>
                </Button>
              </div>
              <div className="flex items-center gap-2 pt-2 border-t text-sm">
                {isBank ? (
                  <Banknote className="size-4 text-muted-foreground" />
                ) : (
                  <CreditCard className="size-4 text-muted-foreground" />
                )}
                <span className="capitalize">
                  {isBank ? 'Bank transfer' : 'Card (Moyasar)'}
                </span>
              </div>
            </div>

            {/* Bank-specific section */}
            {isBank ? (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold">Bank transfer details</h3>
                <div className="rounded-lg border p-3 text-sm space-y-2">
                  <div>
                    <div className="text-xs text-muted-foreground">
                      Sender bank
                    </div>
                    <div className="font-medium">
                      {charge.sender_bank_name || '—'}
                    </div>
                  </div>
                  <div>
                    <div className="text-xs text-muted-foreground">
                      Account holder
                    </div>
                    <div className="font-medium">
                      {charge.sender_account_holder || '—'}
                    </div>
                  </div>
                </div>

                {charge.proof_file_url ? (
                  <div className="space-y-2">
                    <div className="text-xs text-muted-foreground">
                      Proof of payment
                    </div>
                    <a
                      href={charge.proof_file_url}
                      target="_blank"
                      rel="noopener"
                      className="block rounded-lg border overflow-hidden hover:opacity-90 transition"
                    >
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img
                        src={charge.proof_file_url}
                        alt={`Proof for charge #${charge.id}`}
                        className="max-h-72 w-full object-contain bg-muted/30"
                      />
                      <div className="px-3 py-2 text-xs text-muted-foreground border-t flex items-center gap-1.5">
                        <ExternalLink className="size-3.5" />
                        Open full size
                      </div>
                    </a>
                  </div>
                ) : (
                  <div className="text-xs text-muted-foreground italic">
                    No proof file uploaded.
                  </div>
                )}
              </div>
            ) : (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold">Card payment</h3>
                <div className="rounded-lg border p-3 text-sm space-y-2">
                  <div>
                    <div className="text-xs text-muted-foreground">
                      Moyasar charge id
                    </div>
                    <div className="font-mono text-xs break-all">
                      {charge.external_payment_id || '—'}
                    </div>
                  </div>
                  <div>
                    <div className="text-xs text-muted-foreground">
                      Approved at
                    </div>
                    <div className="font-medium">
                      {safeFormat(charge.approved_at)}
                    </div>
                  </div>
                  <div className="rounded-md bg-muted/40 p-2 text-xs text-muted-foreground">
                    Auto-approved at payment time. No admin action available.
                  </div>
                </div>
              </div>
            )}

            {/* Status timeline / receipts */}
            <div className="space-y-2">
              <h3 className="text-sm font-semibold">Timeline</h3>
              <div className="rounded-lg border p-3 text-sm space-y-1">
                <div>
                  <span className="text-muted-foreground">Submitted:</span>{' '}
                  {safeFormat(charge.created_at)}
                </div>
                <div>
                  <span className="text-muted-foreground">Reviewed:</span>{' '}
                  {safeFormat(charge.reviewed_at)}
                </div>
                <div>
                  <span className="text-muted-foreground">Approved:</span>{' '}
                  {safeFormat(charge.approved_at)}
                </div>
                <div>
                  <span className="text-muted-foreground">Rejected:</span>{' '}
                  {safeFormat(charge.rejected_at)}
                </div>
              </div>
            </div>

            {charge.wallet_transaction_id ? (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold">Wallet ledger</h3>
                <Link
                  href={`/marketplace-admin/money/brand-wallets/${charge.brand_id}`}
                  className="inline-flex items-center gap-1.5 text-sm text-primary hover:underline"
                >
                  View ledger row #{charge.wallet_transaction_id}
                  <ExternalLink className="size-3.5" />
                </Link>
              </div>
            ) : null}

            {charge.rejection_reason ? (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold text-red-600">
                  Rejection reason
                </h3>
                <div className="rounded-lg border border-red-200 bg-red-50 p-3 text-sm whitespace-pre-wrap">
                  {charge.rejection_reason}
                </div>
              </div>
            ) : null}

            {charge.admin_notes ? (
              <div className="space-y-2">
                <h3 className="text-sm font-semibold">
                  Admin notes
                  <span className="ms-2 text-xs font-normal text-muted-foreground">
                    (internal)
                  </span>
                </h3>
                <div className="rounded-lg border p-3 text-sm whitespace-pre-wrap">
                  {charge.admin_notes}
                </div>
              </div>
            ) : null}

            {/* Action buttons */}
            {canAct ? (
              <div className="flex flex-wrap gap-2 pt-2 border-t">
                <Button
                  onClick={() => setConfirmKind('approve')}
                  disabled={submitting}
                  className="bg-green-600 hover:bg-green-700 text-white"
                >
                  Approve & Credit
                </Button>
                <Button
                  variant="outline"
                  onClick={() => setConfirmKind('reject')}
                  disabled={submitting}
                  className="text-red-600 border-red-200 hover:bg-red-50"
                >
                  Reject
                </Button>
              </div>
            ) : null}
          </div>
        </SheetContent>
      </Sheet>

      {/* Approve confirm */}
      <Dialog
        open={confirmKind === 'approve'}
        onOpenChange={(o) => {
          if (!o) {
            setConfirmKind(null);
            setApproveAdminNotes('');
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Approve top-up #{charge.id}?</DialogTitle>
            <DialogDescription>
              Approve top-up of{' '}
              <strong>{formatMoney(charge.amount, charge.currency)}</strong> for{' '}
              <strong>{charge.brand_name || `Brand #${charge.brand_id}`}</strong>
              ? This will credit their wallet immediately.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2 py-2">
            <label
              htmlFor="approve-admin-notes"
              className="text-sm font-medium text-zinc-700"
            >
              Internal notes <span className="text-zinc-400">(optional)</span>
            </label>
            <textarea
              id="approve-admin-notes"
              value={approveAdminNotes}
              onChange={(e) => setApproveAdminNotes(e.target.value.slice(0, 1000))}
              maxLength={1000}
              rows={3}
              placeholder="e.g., Verified via bank statement"
              className="w-full rounded-md border border-zinc-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500"
              disabled={approveMutation.isPending}
            />
            <div className="text-xs text-zinc-500 text-right">
              {approveAdminNotes.length}/1000
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => {
                setConfirmKind(null);
                setApproveAdminNotes('');
              }}
              disabled={approveMutation.isPending}
            >
              Cancel
            </Button>
            <Button
              className="bg-green-600 hover:bg-green-700 text-white"
              onClick={() => approveMutation.mutate(charge.id)}
              disabled={approveMutation.isPending}
            >
              {approveMutation.isPending ? (
                <Spinner className="size-4 animate-spin mr-2" />
              ) : null}
              Approve & Credit
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Reject confirm */}
      <Dialog
        open={confirmKind === 'reject'}
        onOpenChange={(o) => {
          if (!o) {
            setConfirmKind(null);
            setReasonError(null);
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Reject top-up #{charge.id}?</DialogTitle>
            <DialogDescription>
              No money moves. The brand will see the rejection reason on their
              top-up requests tab.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <div>
              <Label>
                Reason for rejection{' '}
                <span className="text-red-500">*</span>
              </Label>
              <Textarea
                value={rejectionReason}
                onChange={(e) => {
                  setRejectionReason(e.target.value);
                  setReasonError(null);
                }}
                placeholder="Required, 3–1000 characters. Visible to the brand."
                rows={4}
                maxLength={1000}
              />
              <div className="flex justify-between mt-1">
                <p
                  className={`text-xs ${reasonError ? 'text-red-600' : 'text-muted-foreground'}`}
                >
                  {reasonError ?? 'Visible to the brand.'}
                </p>
                <p className="text-xs text-muted-foreground">
                  {reasonLen} / 1000
                </p>
              </div>
            </div>
            <div>
              <Label>
                Internal notes
                <span className="ms-1 text-xs font-normal text-muted-foreground">
                  (admin team only, optional)
                </span>
              </Label>
              <Textarea
                value={adminNotes}
                onChange={(e) => setAdminNotes(e.target.value)}
                placeholder="Notes visible only to admins."
                rows={3}
                maxLength={1000}
              />
              <p className="text-xs text-muted-foreground mt-1 text-right">
                {adminNotes.length} / 1000
              </p>
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setConfirmKind(null)}
              disabled={rejectMutation.isPending}
            >
              Cancel
            </Button>
            <Button
              variant="outline"
              className="text-red-600 border-red-300 hover:bg-red-50"
              onClick={() => rejectMutation.mutate(charge.id)}
              disabled={!reasonValid || rejectMutation.isPending}
            >
              {rejectMutation.isPending ? (
                <Spinner className="size-4 animate-spin mr-2" />
              ) : null}
              Confirm reject
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
