'use client';

import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Copy, Plus, RefreshCw, Send, Undo2, X } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinners';
import { Textarea } from '@/components/ui/textarea';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import {
  createPayoutLink,
  fetchPayoutLinks,
  PayoutLink,
  payoutLinkAction,
} from '@/network/apis/dashboard/payoutLinks/payoutLinks.apis';
import PaginationComponent from '@/modules/client-management/components/paginationComponent/paginationComponent';
import { StatusPill } from '@/modules/marketplace-admin/components/StatusPill';

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

const when = (iso: string | null) => (iso ? new Date(iso).toLocaleString('en-GB', { dateStyle: 'medium', timeStyle: 'short' }) : '—');

/** What the status means for the admin, in one phrase. */
const statusLabel = (l: PayoutLink) =>
  l.expired
    ? 'expired'
    : ({
        awaiting_details: 'waiting for details',
        ready: 'ready to send',
        sending: 'sending',
        sent: l.moyasar_status === 'paid' ? 'paid' : 'sent',
        failed: 'failed',
        cancelled: 'cancelled',
      }[l.status] ?? l.status);

const errorOf = (e: unknown) =>
  (e as { response?: { data?: { message?: string } } })?.response?.data?.message || 'Something went wrong.';

/**
 * Payout links. The admin creates one for a recipient and an amount and
 * shares the link; the recipient enters their own bank details; the admin then
 * sends the payout from the platform's Moyasar account. Money only moves on
 * Send, and Send always asks first.
 */
export function PayoutLinksList() {
  const qc = useQueryClient();
  const [page, setPage] = useState(1);
  const [creating, setCreating] = useState(false);
  const [form, setForm] = useState({ recipient_label: '', amount: '', comment: '' });
  const [confirmSend, setConfirmSend] = useState<PayoutLink | null>(null);

  const { data, isLoading, isFetching } = useQuery({
    queryKey: ['payout-links', page],
    queryFn: () => fetchPayoutLinks({ page, per_page: 25 }),
  });

  const refreshList = () => qc.invalidateQueries({ queryKey: ['payout-links'] });

  const copy = async (url: string) => {
    try {
      await navigator.clipboard.writeText(url);
      toast.success('Link copied — share it with the recipient.');
    } catch {
      toast.message(url);
    }
  };

  const create = useMutation({
    mutationFn: () =>
      createPayoutLink({
        recipient_label: form.recipient_label.trim(),
        amount: Number(form.amount),
        comment: form.comment.trim() || undefined,
      }),
    onSuccess: async (link) => {
      setCreating(false);
      setForm({ recipient_label: '', amount: '', comment: '' });
      refreshList();
      await copy(link.url);
    },
    onError: (e) => toast.error(errorOf(e)),
  });

  const act = useMutation({
    mutationFn: ({ id, action }: { id: number; action: 'send' | 'refresh' | 'reopen' | 'cancel' }) =>
      payoutLinkAction(id, action),
    onSuccess: (link, { action }) => {
      refreshList();
      if (action === 'send') toast.success(`Payout sent to Moyasar (${link.moyasar_status ?? 'initiated'}).`);
      if (action === 'refresh') toast.message(`Moyasar status: ${link.moyasar_status ?? '—'}`);
      if (action === 'reopen') toast.success('The recipient can enter their details again on the same link.');
      if (action === 'cancel') toast.success('Link cancelled.');
    },
    onError: (e) => {
      refreshList();
      toast.error(errorOf(e));
    },
  });

  const canCreate = form.recipient_label.trim().length > 0 && Number(form.amount) >= 1;

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <p className="text-sm text-muted-foreground">
          {data?.meta?.total ?? 0} links {isFetching && !isLoading ? '· updating…' : ''}
        </p>
        <Button onClick={() => setCreating(true)}>
          <Plus className="size-4" /> New payout link
        </Button>
      </div>

      <Card>
        <CardContent className="p-0">
          {isLoading ? (
            <div className="flex justify-center p-10">
              <Spinner />
            </div>
          ) : !data?.items?.length ? (
            <p className="p-10 text-center text-sm text-muted-foreground">
              No payout links yet. Create one, copy it, and send it to the person being paid.
            </p>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Recipient</TableHead>
                  <TableHead>Amount</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Bank details</TableHead>
                  <TableHead>Created</TableHead>
                  <TableHead className="text-end">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {data.items.map((l) => (
                  <TableRow key={l.id}>
                    <TableCell>
                      <div className="font-medium">{l.recipient_label}</div>
                      {l.comment && <div className="text-xs text-muted-foreground">{l.comment}</div>}
                    </TableCell>
                    <TableCell className="font-semibold">{money(l.amount, l.currency)}</TableCell>
                    <TableCell>
                      <StatusPill status={statusLabel(l)} />
                      {l.failure_message && (
                        <div className="mt-1 max-w-56 text-xs text-red-600">{l.failure_message}</div>
                      )}
                    </TableCell>
                    <TableCell className="text-xs">
                      {l.account_name ? (
                        <>
                          <div className="font-medium">{l.account_name}</div>
                          <div className="font-mono" dir="ltr">
                            {l.iban_masked}
                          </div>
                          <div className="text-muted-foreground">
                            {l.mobile} · {l.city}
                          </div>
                        </>
                      ) : (
                        <span className="text-muted-foreground">—</span>
                      )}
                    </TableCell>
                    <TableCell className="text-xs text-muted-foreground">
                      {when(l.created_at)}
                      <div>{l.created_by}</div>
                      {l.sent_at && <div>Sent {when(l.sent_at)}</div>}
                    </TableCell>
                    <TableCell>
                      <div className="flex flex-wrap justify-end gap-1.5">
                        {l.status === 'awaiting_details' && !l.expired && (
                          <Button size="sm" variant="outline" onClick={() => copy(l.url)}>
                            <Copy className="size-3.5" /> Copy link
                          </Button>
                        )}
                        {l.status === 'ready' && (
                          <Button size="sm" onClick={() => setConfirmSend(l)} disabled={act.isPending}>
                            <Send className="size-3.5" /> Send payout
                          </Button>
                        )}
                        {l.status === 'sent' && l.moyasar_status !== 'paid' && (
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => act.mutate({ id: l.id, action: 'refresh' })}
                            disabled={act.isPending}
                          >
                            <RefreshCw className="size-3.5" /> Check status
                          </Button>
                        )}
                        {(l.status === 'failed' || l.status === 'ready' || (l.status === 'awaiting_details' && l.expired)) && (
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => act.mutate({ id: l.id, action: 'reopen' })}
                            disabled={act.isPending}
                          >
                            <Undo2 className="size-3.5" /> Ask again
                          </Button>
                        )}
                        {['awaiting_details', 'ready', 'failed'].includes(l.status) && (
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={() => act.mutate({ id: l.id, action: 'cancel' })}
                            disabled={act.isPending}
                          >
                            <X className="size-3.5" /> Cancel
                          </Button>
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {(data?.meta?.last_page ?? 1) > 1 && (
        <PaginationComponent
          currentPage={page}
          totalPages={data?.meta?.last_page ?? 1}
          onPageChange={setPage}
        />
      )}

      <Dialog open={creating} onOpenChange={setCreating}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>New payout link</DialogTitle>
            <DialogDescription>
              The link opens a form where the recipient enters their own bank details. Nothing is paid
              until you press Send on this page.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="pl-label">Recipient (shown to them)</Label>
              <Input
                id="pl-label"
                placeholder="e.g. Ahmed — campaign October"
                value={form.recipient_label}
                onChange={(e) => setForm((f) => ({ ...f, recipient_label: e.target.value }))}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="pl-amount">Amount (SAR)</Label>
              <Input
                id="pl-amount"
                type="number"
                min={1}
                step="0.01"
                value={form.amount}
                onChange={(e) => setForm((f) => ({ ...f, amount: e.target.value }))}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="pl-comment">Note (optional, internal)</Label>
              <Textarea
                id="pl-comment"
                rows={2}
                value={form.comment}
                onChange={(e) => setForm((f) => ({ ...f, comment: e.target.value }))}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setCreating(false)}>
              Cancel
            </Button>
            <Button onClick={() => create.mutate()} disabled={!canCreate || create.isPending}>
              {create.isPending ? <Spinner /> : 'Create and copy link'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <AlertDialog open={Boolean(confirmSend)} onOpenChange={(o) => !o && setConfirmSend(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>
              Send {confirmSend ? money(confirmSend.amount, confirmSend.currency) : ''}?
            </AlertDialogTitle>
            <AlertDialogDescription asChild>
              <div className="space-y-1 text-sm">
                <div>
                  To <b>{confirmSend?.account_name}</b>
                </div>
                <div className="font-mono" dir="ltr">
                  {confirmSend?.iban_masked}
                </div>
                <div>
                  This moves real money from the Sanad Moyasar account and cannot be undone here.
                </div>
              </div>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Not now</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => {
                if (confirmSend) act.mutate({ id: confirmSend.id, action: 'send' });
                setConfirmSend(null);
              }}
            >
              Send payout
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
