import { useCallback, useEffect, useMemo, useState } from 'react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { ArrowDownCircle, ArrowUpCircle, Eye, Loader2, Receipt, RefreshCw, Search, FileText, IndianRupee, CalendarClock } from 'lucide-react';
import { toast } from 'sonner';
import apiClient from '@/services/authApi';
import {
  getCreditNoteSapResponse,
  getDebitNoteSapResponse,
  listCreditNotes,
  listDebitNotes,
  type Form16CreditNoteItem,
  type Form16DebitNoteListItem,
  type Form16SapResponseRecord,
} from '@/services/form16Api';

type TransactionType = 'credit' | 'debit';

type TransactionRow = {
  id: number;
  type: TransactionType;
  referenceNumber: string;
  dealer: string;
  amount: number | null;
  issueDate: string | null;
  sapResponseAvailable: boolean;
  searchText: string;
};

type SapPreview = {
  type: TransactionType;
  referenceNumber: string;
  amountText: string;
  issuedAtText: string;
  row: Record<string, string>;
};

function formatDate(value: string | null | undefined): string {
  if (!value) return '–';
  try {
    const d = new Date(value);
    return Number.isNaN(d.getTime()) ? value : d.toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' });
  } catch {
    return value;
  }
}

function formatDateTime(value: string | null | undefined): string {
  if (!value) return '–';
  try {
    const d = new Date(value);
    return Number.isNaN(d.getTime())
      ? value
      : d.toLocaleString('en-IN', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' });
  } catch {
    return value;
  }
}

function formatAmount(value: number | null | undefined): string {
  if (value == null) return '–';
  return new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR', maximumFractionDigits: 0 }).format(value);
}

function mapSapResponseToPreviewRow(sap: Form16SapResponseRecord): Record<string, string> {
  return {
    TRNS_UNIQ_NO: sap.trnsUniqNo || '',
    TDS_TRNS_ID: sap.tdsTransId || '',
    DOC_NO: sap.sapDocumentNumber || '',
    MSG_TYP: sap.msgTyp || '',
    MESSAGE: sap.message || '',
  };
}

function toCreditTransaction(note: Form16CreditNoteItem): TransactionRow {
  return {
    id: Number(note.id),
    type: 'credit',
    referenceNumber: note.creditNoteNumber || '–',
    dealer: note.dealerName || note.dealerCode || '–',
    amount: note.amount,
    issueDate: note.issueDate,
    sapResponseAvailable: !!note.sapResponseAvailable,
    searchText: [
      note.creditNoteNumber,
      note.dealerName,
      note.dealerCode,
      note.submission?.form16aNumber,
      'credit',
      'cr',
    ]
      .filter(Boolean)
      .join(' ')
      .toLowerCase(),
  };
}

function toDebitTransaction(note: Form16DebitNoteListItem): TransactionRow {
  return {
    id: Number(note.id),
    type: 'debit',
    referenceNumber: note.debitNoteNumber || '–',
    dealer: note.dealerName || note.dealerCode || '–',
    amount: note.amount,
    issueDate: note.issueDate,
    sapResponseAvailable: !!note.sapResponseAvailable,
    searchText: [
      note.debitNoteNumber,
      note.dealerName,
      note.dealerCode,
      note.form16aNumber,
      'debit',
      'db',
    ]
      .filter(Boolean)
      .join(' ')
      .toLowerCase(),
  };
}

export function Form16Transactions() {
  const [loading, setLoading] = useState(true);
  const [pulling, setPulling] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [transactions, setTransactions] = useState<TransactionRow[]>([]);

  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [preview, setPreview] = useState<SapPreview | null>(null);

  const fetchTransactions = useCallback(async () => {
    try {
      setLoading(true);
      const [creditResult, debitResult] = await Promise.all([listCreditNotes(), listDebitNotes()]);

      const merged = [
        ...creditResult.creditNotes.map(toCreditTransaction),
        ...debitResult.debitNotes.map(toDebitTransaction),
      ].sort((a, b) => {
        const aTime = a.issueDate ? new Date(a.issueDate).getTime() : 0;
        const bTime = b.issueDate ? new Date(b.issueDate).getTime() : 0;
        return bTime - aTime;
      });

      setTransactions(merged);
    } catch (error: unknown) {
      console.error('[Form16Transactions] Failed to fetch:', error);
      toast.error(error instanceof Error ? error.message : 'Failed to load transactions');
      setTransactions([]);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchTransactions();
  }, [fetchTransactions]);

  const filteredTransactions = useMemo(() => {
    if (!searchQuery.trim()) return transactions;
    const q = searchQuery.trim().toLowerCase();
    return transactions.filter((t) => t.searchText.includes(q));
  }, [transactions, searchQuery]);

  const openSapPreview = useCallback(async (tx: TransactionRow) => {
    setPreviewOpen(true);
    setPreviewLoading(true);
    setPreview(null);
    try {
      const payload = tx.type === 'credit'
        ? await getCreditNoteSapResponse(tx.id)
        : await getDebitNoteSapResponse(tx.id);

      setPreview({
        type: tx.type,
        referenceNumber: tx.referenceNumber,
        amountText: formatAmount(tx.amount),
        issuedAtText: formatDateTime(tx.issueDate),
        row: mapSapResponseToPreviewRow(payload.sapResponse),
      });
    } catch (e: unknown) {
      const msg = e instanceof Error ? e.message : 'Failed to load SAP response';
      toast.error(msg);
      setPreviewOpen(false);
    } finally {
      setPreviewLoading(false);
    }
  }, []);

  const pullNow = useCallback(async () => {
    setPulling(true);
    toast.loading('Pulling SAP responses...', { id: 'pull-transactions' });
    try {
      await apiClient.post('/form16/sap/pull');
      await fetchTransactions();
      toast.success('Pulled and refreshed transactions.', { id: 'pull-transactions' });
    } catch {
      toast.error('Failed to pull SAP responses', { id: 'pull-transactions' });
    } finally {
      setPulling(false);
    }
  }, [fetchTransactions]);

  return (
    <div className="space-y-6 min-h-screen bg-gray-50 p-4 md:p-6 w-full">
      <Dialog
        open={previewOpen}
        onOpenChange={(open) => {
          setPreviewOpen(open);
          if (!open) setPreview(null);
        }}
      >
        <DialogContent className="sm:max-w-2xl">
          <DialogHeader>
            <DialogTitle>SAP Response</DialogTitle>
            <DialogDescription>
              {previewLoading ? 'Loading SAP response CSV...' : 'Review SAP response details.'}
            </DialogDescription>
          </DialogHeader>

          {previewLoading ? (
            <div className="py-8 flex items-center justify-center gap-2 text-gray-600">
              <Loader2 className="w-5 h-5 animate-spin" />
              Loading SAP response...
            </div>
          ) : preview ? (
            <div className="space-y-4">
              <div className="rounded-xl border border-emerald-200 bg-emerald-50/70 p-4">
                <div className="flex items-center gap-2">
                  <FileText className="w-4 h-4 text-emerald-700" />
                  <p className="text-xs font-semibold text-emerald-800 tracking-wide uppercase">SAP Response Identifiers</p>
                </div>
                <div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-3">
                  <div className="rounded-lg border border-emerald-200 bg-white/70 p-3">
                    <p className="text-xs text-emerald-700 uppercase tracking-wide">TRNS_UNIQ_NO</p>
                    <p className="text-sm font-semibold text-emerald-900 break-all mt-1">{preview.row.TRNS_UNIQ_NO || '–'}</p>
                  </div>
                  <div className="rounded-lg border border-emerald-200 bg-white/70 p-3">
                    <p className="text-xs text-emerald-700 uppercase tracking-wide">CLAIM_NUMBER</p>
                    <p className="text-sm font-semibold text-emerald-900 break-all mt-1">{preview.row.TDS_TRNS_ID || '–'}</p>
                  </div>
                </div>
              </div>

              <div className="rounded-xl border border-amber-200 bg-amber-50/70 p-4">
                <div className="flex items-center gap-2 mb-3">
                  <IndianRupee className="w-4 h-4 text-amber-700" />
                  <p className="text-xs font-semibold text-amber-800 tracking-wide uppercase">
                    {preview.type === 'credit' ? 'Credit Note Details' : 'Debit Note Details'}
                  </p>
                </div>

                <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                  <div className="rounded-lg border border-amber-200 bg-white/70 p-3">
                    <p className="text-xs text-amber-700 uppercase tracking-wide flex items-center gap-2">
                      <IndianRupee className="w-4 h-4" /> Amount
                    </p>
                    <p className="text-base font-semibold text-amber-900 mt-1">{preview.amountText}</p>
                  </div>
                  <div className="rounded-lg border border-amber-200 bg-white/70 p-3">
                    <p className="text-xs text-amber-700 uppercase tracking-wide flex items-center gap-2">
                      <CalendarClock className="w-4 h-4" /> Issued Date
                    </p>
                    <p className="text-base font-semibold text-amber-900 mt-1">{preview.issuedAtText}</p>
                  </div>
                  <div className="rounded-lg border border-amber-200 bg-white/70 p-3">
                    <p className="text-xs text-amber-700 uppercase tracking-wide">DOC_NO</p>
                    <p className="text-sm font-semibold text-amber-900 break-all mt-1">{preview.row.DOC_NO || '–'}</p>
                  </div>
                  <div className="rounded-lg border border-amber-200 bg-white/70 p-3">
                    <p className="text-xs text-amber-700 uppercase tracking-wide">MSG_TYP</p>
                    <p className="text-sm font-semibold text-amber-900 break-all mt-1">{preview.row.MSG_TYP || '–'}</p>
                  </div>
                </div>

                <div className="rounded-lg border border-amber-200 bg-white/70 p-3 mt-3">
                  <p className="text-xs text-amber-700 uppercase tracking-wide">MESSAGE</p>
                  <p className="text-sm font-medium text-amber-900 break-words mt-1">{preview.row.MESSAGE || '–'}</p>
                </div>
              </div>
            </div>
          ) : (
            <div className="py-8 text-sm text-gray-600">No preview available.</div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setPreviewOpen(false)}>Close</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <div className="w-full min-w-0">
        <div className="mb-6">
          <h1 className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">Transactions</h1>
          <p className="text-sm text-gray-600">Credit and debit notes in one place</p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>All Transactions</CardTitle>
            <CardDescription>CR/DB reference number, dealer, amount, issue date, and SAP status</CardDescription>
            <div className="flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between">
              <div className="relative max-w-md w-full">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
                <Input
                  type="search"
                  placeholder="Search transactions..."
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  className="pl-9"
                />
              </div>
              <Button variant="outline" onClick={pullNow} disabled={pulling}>
                {pulling ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <RefreshCw className="w-4 h-4 mr-2" />}
                Pull SAP Response
              </Button>
            </div>
          </CardHeader>
          <CardContent>
            <div className="rounded-lg border overflow-hidden">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>TDS_TRANS_ID</TableHead>
                    <TableHead>Dealer</TableHead>
                    <TableHead>Transaction Amount</TableHead>
                    <TableHead>Issued Date</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead className="text-right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {loading ? (
                    <TableRow>
                      <TableCell colSpan={6} className="text-center py-12">
                        <Loader2 className="w-6 h-6 animate-spin mx-auto mb-2 text-teal-600" />
                        <p className="text-gray-500">Loading transactions...</p>
                      </TableCell>
                    </TableRow>
                  ) : filteredTransactions.length === 0 ? (
                    <TableRow>
                      <TableCell colSpan={6} className="text-center py-12 text-gray-500">
                        <Receipt className="w-12 h-12 mx-auto mb-3 text-gray-400" />
                        <p>No transactions found</p>
                      </TableCell>
                    </TableRow>
                  ) : (
                    filteredTransactions.map((tx) => (
                      <TableRow key={`${tx.type}-${tx.id}`} className="hover:bg-gray-50 transition-colors">
                        <TableCell className="font-medium">{tx.referenceNumber}</TableCell>
                        <TableCell>{tx.dealer}</TableCell>
                        <TableCell>
                          <div className={`inline-flex items-center gap-1.5 font-semibold ${tx.type === 'credit' ? 'text-green-600' : 'text-red-600'}`}>
                            {tx.type === 'credit' ? <ArrowUpCircle className="w-4 h-4" /> : <ArrowDownCircle className="w-4 h-4" />}
                            <span>{tx.type === 'credit' ? '+ ' : '- '}{formatAmount(tx.amount)}</span>
                          </div>
                        </TableCell>
                        <TableCell>{formatDate(tx.issueDate)}</TableCell>
                        <TableCell>
                          {tx.sapResponseAvailable ? (
                            <Badge className="bg-green-100 text-green-800 border-green-200">Completed</Badge>
                          ) : (
                            <Badge className="bg-orange-100 text-orange-800 border-orange-200">OUTGOING</Badge>
                          )}
                        </TableCell>
                        <TableCell className="text-right">
                          {tx.sapResponseAvailable ? (
                            <Button variant="outline" size="sm" onClick={() => openSapPreview(tx)}>
                              <Eye className="w-4 h-4 mr-2" />
                              View
                            </Button>
                          ) : (
                            <Button variant="outline" size="sm" onClick={pullNow} disabled={pulling}>
                              {pulling ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <RefreshCw className="w-4 h-4 mr-2" />}
                              Pull
                            </Button>
                          )}
                        </TableCell>
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </div>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
