import { useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router';
import { useQuery } from '@tanstack/react-query';
import { Filter, Download, Search, MoreHorizontal, ChevronLeft, ChevronRight, ArrowUp, ArrowDown, ArrowUpDown, Loader2, X } from 'lucide-react';
import * as XLSX from 'xlsx';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import StatusBadge from './StatusBadge';
import { cn } from '@/lib/utils';
import { useTransactions } from '@/hooks/useTransactions';
import { useTransactionStore } from '@/stores/transactionStore';
import { api } from '@/services/api';

const BRANCH_COLORS = [
  'bg-blue-500', 'bg-purple-500', 'bg-orange-500', 'bg-teal-500',
  'bg-indigo-500', 'bg-pink-500', 'bg-emerald-500', 'bg-amber-500',
];

function getBranchColor(branch: string): string {
  let hash = 0;
  for (let i = 0; i < branch.length; i++) {
    hash = branch.charCodeAt(i) + ((hash << 5) - hash);
  }
  return BRANCH_COLORS[Math.abs(hash) % BRANCH_COLORS.length];
}

function formatAmount(amount: number): string {
  return new Intl.NumberFormat('fr-CA', {
    style: 'currency',
    currency: 'CAD',
    minimumFractionDigits: 2,
  }).format(amount);
}

/** Extract the dollar amount from the raw Interac email text */
function extractEmailAmount(rawEmail?: string | null): number | null {
  if (!rawEmail) return null;
  // Match patterns like "$40.00", "$215.00 (CAD)", "Amount: $50.00"
  const match = rawEmail.match(/\$\s*([0-9,]+(?:\.\d{1,2})?)/);
  if (match) {
    return parseFloat(match[1].replace(/,/g, ''));
  }
  return null;
}

/** Compute match accuracy between AI-parsed amount and raw email amount */
function getMatchAccuracy(aiAmount: number, rawEmail?: string | null): { percent: number; emailAmount: number | null } {
  const emailAmount = extractEmailAmount(rawEmail);
  if (emailAmount === null || emailAmount === 0) return { percent: -1, emailAmount: null };
  if (aiAmount === emailAmount) return { percent: 100, emailAmount };
  const diff = Math.abs(aiAmount - emailAmount);
  const percent = Math.max(0, Math.round((1 - diff / emailAmount) * 100));
  return { percent, emailAmount };
}

function formatDate(dateStr: string): { date: string; time: string } {
  try {
    const d = new Date(dateStr);
    return {
      date: d.toLocaleDateString('fr-CA', { day: 'numeric', month: 'short', year: 'numeric', timeZone: 'America/Toronto' }),
      time: d.toLocaleTimeString('fr-CA', { hour: '2-digit', minute: '2-digit', timeZone: 'America/Toronto' }),
    };
  } catch {
    return { date: dateStr, time: '' };
  }
}

export default function TransactionTable() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const { filters, setFilter, setFilters } = useTransactionStore();
  const [searchInput, setSearchInput] = useState(filters.search);
  const [forceRescan, setForceRescan] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [showFilters, setShowFilters] = useState(false);

  // Fetch branches for filter dropdown
  const { data: branchData } = useQuery<{ branches: { id: number; branch: string }[] }>({
    queryKey: ['branches'],
    queryFn: () => api.get('/settings/branches'),
  });
  const branchNames = [...new Set((branchData?.branches ?? []).map(b => b.branch))].sort();

  const activeFilterCount = [filters.branch, filters.status, filters.reviewed, filters.from, filters.to].filter(Boolean).length;

  const handleClearFilters = useCallback(() => {
    setFilters({ branch: '', status: '', reviewed: '', from: '', to: '' });
  }, [setFilters]);

  const handleSort = useCallback((column: string) => {
    if (filters.sortBy === column) {
      setFilters({ sortBy: column, sortOrder: filters.sortOrder === 'asc' ? 'desc' : 'asc' });
    } else {
      setFilters({ sortBy: column, sortOrder: column === 'amount' ? 'desc' : 'asc' });
    }
  }, [filters.sortBy, filters.sortOrder, setFilters]);

  const SortIcon = ({ column }: { column: string }) => {
    if (filters.sortBy !== column) return <ArrowUpDown className="h-3 w-3 ml-1 opacity-0 group-hover/sort:opacity-50" />;
    return filters.sortOrder === 'asc'
      ? <ArrowUp className="h-3 w-3 ml-1 text-primary" />
      : <ArrowDown className="h-3 w-3 ml-1 text-primary" />;
  };

  const { data, isLoading } = useTransactions(filters);
  const transactions = data?.transactions ?? [];
  const total = data?.total ?? 0;
  const totalPages = data?.totalPages ?? 1;
  const page = data?.page ?? 1;

  const handleSearch = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchInput(e.target.value);
    // Debounce
    const timer = setTimeout(() => setFilter('search', e.target.value), 300);
    return () => clearTimeout(timer);
  }, [setFilter]);

  const handleExport = useCallback(async () => {
    setExporting(true);
    try {
      // Use fast export endpoint with current filters
      const params = new URLSearchParams();
      if (filters.branch) params.set('branch', filters.branch);
      if (filters.from) params.set('from', filters.from);
      if (filters.to) params.set('to', filters.to);

      const result = await api.get<{ transactions: any[] }>(`/transactions/export?${params}`);
      const rows = result.transactions;

      if (rows.length === 0) return;

      // Build worksheet data
      const wsData = rows.map((tx: any) => ({
        [t('table.date')]: tx.date ? new Date(tx.date).toLocaleDateString('fr-CA', { timeZone: 'America/Toronto' }) : '',
        [t('table.sender')]: tx.sender || '',
        [t('table.envelopeNumber')]: tx.envelopeNumber || '',
        [t('table.amount')]: tx.amount,
        'Currency': tx.currency || 'CAD',
        [t('table.reference')]: tx.reference || '',
        [t('table.branch')]: tx.branch || 'Montreal',
        [t('table.status')]: tx.reviewed ? t('status.verified') : t('status.notVerified'),
        'Email': tx.recipientEmail || '',
        'Message': tx.message || '',
      }));

      const ws = XLSX.utils.json_to_sheet(wsData);
      // Fixed column widths for speed
      ws['!cols'] = [
        { wch: 12 },  // Date
        { wch: 25 },  // Sender
        { wch: 16 },  // Envelope Number
        { wch: 12 },  // Amount
        { wch: 6 },   // Currency
        { wch: 20 },  // Reference
        { wch: 20 },  // Branch
        { wch: 12 },  // Status
        { wch: 35 },  // Email
        { wch: 30 },  // Message
      ];

      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws, 'Transactions');

      const dateStr = new Date().toISOString().split('T')[0];
      XLSX.writeFile(wb, `ICC_Transactions_${dateStr}.xlsx`);
    } catch (err) {
      console.error('Export failed:', err);
    } finally {
      setExporting(false);
    }
  }, [filters, t]);

  return (
    <div className="flex flex-col rounded-xl border border-border bg-card shadow-sm overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between border-b border-border p-6 bg-white">
        <div className="flex flex-col gap-1">
          <div className="flex items-center gap-3">
            <h3 className="text-lg font-bold text-slate-900">
              {t('transactions.title')}
            </h3>
            <span className="inline-flex items-center rounded-full bg-green-50 px-2.5 py-0.5 text-xs font-bold text-green-700 border border-green-200">
              Live
            </span>
          </div>
          <p className="text-sm text-slate-500">{t('transactions.subtitle')}</p>
        </div>
        <div className="flex items-center gap-4">
          {/* Force Rescan toggle */}
          <div className="flex items-center gap-3 px-3 py-2 bg-slate-50 rounded-lg border border-border/50">
            <span className="text-xs font-semibold text-slate-600">Force Rescan</span>
            <button
              type="button"
              onClick={() => setForceRescan(!forceRescan)}
              className={cn(
                'relative inline-flex h-5 w-9 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2',
                forceRescan ? 'bg-primary' : 'bg-slate-200'
              )}
            >
              <span
                className={cn(
                  'inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
                  forceRescan ? 'translate-x-4' : 'translate-x-1'
                )}
              />
            </button>
          </div>

          <div className="h-8 w-px bg-slate-100" />

          {/* Search */}
          <div className="relative hidden sm:block">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-[18px] w-[18px] text-slate-400 pointer-events-none" />
            <Input
              className="h-9 w-64 bg-white pl-9 text-sm placeholder-slate-400 shadow-sm"
              placeholder={t('header.searchPlaceholder')}
              value={searchInput}
              onChange={handleSearch}
            />
          </div>

          <Button
            variant={activeFilterCount > 0 ? 'default' : 'outline'}
            size="sm"
            className="gap-2 text-sm font-medium"
            onClick={() => setShowFilters(!showFilters)}
          >
            <Filter className="h-[18px] w-[18px]" />
            {t('transactions.filters')}
            {activeFilterCount > 0 && (
              <span className="ml-1 inline-flex h-5 w-5 items-center justify-center rounded-full bg-white/20 text-[10px] font-bold">
                {activeFilterCount}
              </span>
            )}
          </Button>
          <Button variant="outline" size="sm" className="gap-2 text-sm font-medium" onClick={handleExport} disabled={exporting}>
            {exporting ? <Loader2 className="h-[18px] w-[18px] animate-spin" /> : <Download className="h-[18px] w-[18px]" />}
            {t('transactions.export')}
          </Button>
        </div>
      </div>

      {/* Filter Panel */}
      {showFilters && (
        <div className="border-b border-border bg-slate-50/80 px-6 py-4">
          <div className="flex flex-wrap items-end gap-4">
            {/* Branch filter */}
            <div className="flex flex-col gap-1.5 min-w-[180px]">
              <label className="text-[11px] font-semibold uppercase tracking-wider text-slate-500">
                {t('transactions.filterByBranch')}
              </label>
              <select
                value={filters.branch}
                onChange={(e) => setFilter('branch', e.target.value)}
                className="h-9 rounded-md border border-border bg-white px-3 text-sm text-slate-700 shadow-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
              >
                <option value="">{t('transactions.allBranches')}</option>
                {branchNames.map((name) => (
                  <option key={name} value={name}>{name}</option>
                ))}
              </select>
            </div>

            {/* Status filter */}
            <div className="flex flex-col gap-1.5 min-w-[160px]">
              <label className="text-[11px] font-semibold uppercase tracking-wider text-slate-500">
                {t('transactions.filterByStatus')}
              </label>
              <select
                value={filters.status}
                onChange={(e) => setFilter('status', e.target.value)}
                className="h-9 rounded-md border border-border bg-white px-3 text-sm text-slate-700 shadow-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
              >
                <option value="">{t('transactions.allStatuses')}</option>
                <option value="deposited">{t('status.deposited')}</option>
                <option value="pending">{t('status.pending')}</option>
                <option value="expired">{t('status.expired')}</option>
                <option value="cancelled">{t('status.cancelled')}</option>
              </select>
            </div>

            {/* Reviewed filter */}
            <div className="flex flex-col gap-1.5 min-w-[150px]">
              <label className="text-[11px] font-semibold uppercase tracking-wider text-slate-500">
                {t('transactions.filterByReviewed')}
              </label>
              <select
                value={filters.reviewed}
                onChange={(e) => setFilter('reviewed', e.target.value)}
                className="h-9 rounded-md border border-border bg-white px-3 text-sm text-slate-700 shadow-sm focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
              >
                <option value="">{t('transactions.allReviewed')}</option>
                <option value="true">{t('transactions.reviewedOnly')}</option>
                <option value="false">{t('transactions.notReviewedOnly')}</option>
              </select>
            </div>

            {/* Date from */}
            <div className="flex flex-col gap-1.5 min-w-[150px]">
              <label className="text-[11px] font-semibold uppercase tracking-wider text-slate-500">
                {t('transactions.filterDateFrom')}
              </label>
              <Input
                type="date"
                value={filters.from}
                onChange={(e) => setFilter('from', e.target.value)}
                className="h-9 bg-white text-sm shadow-sm"
              />
            </div>

            {/* Date to */}
            <div className="flex flex-col gap-1.5 min-w-[150px]">
              <label className="text-[11px] font-semibold uppercase tracking-wider text-slate-500">
                {t('transactions.filterDateTo')}
              </label>
              <Input
                type="date"
                value={filters.to}
                onChange={(e) => setFilter('to', e.target.value)}
                className="h-9 bg-white text-sm shadow-sm"
              />
            </div>

            {/* Clear filters */}
            {activeFilterCount > 0 && (
              <Button
                variant="ghost"
                size="sm"
                className="gap-1.5 text-xs text-red-600 hover:text-red-700 hover:bg-red-50 self-end"
                onClick={handleClearFilters}
              >
                <X className="h-3.5 w-3.5" />
                {t('transactions.clearFilters')}
              </Button>
            )}
          </div>
        </div>
      )}

      {/* Table */}
      <div className="w-full">
        <Table className="table-fixed w-full">
          <TableHeader>
            <TableRow className="bg-slate-50/50 border-b border-border hover:bg-slate-50/50">
              <TableHead
                className="w-[12%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('date')}
              >
                <span className="flex items-center">{t('table.date')}<SortIcon column="date" /></span>
              </TableHead>
              <TableHead
                className="w-[14%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('sender')}
              >
                <span className="flex items-center">{t('table.sender')}<SortIcon column="sender" /></span>
              </TableHead>
              <TableHead
                className="w-[8%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('envelopeNumber')}
              >
                <span className="flex items-center">{t('table.envelopeNumber')}<SortIcon column="envelopeNumber" /></span>
              </TableHead>
              <TableHead
                className="w-[9%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('amount')}
              >
                <span className="flex items-center">{t('table.amount')}<SortIcon column="amount" /></span>
              </TableHead>
              <TableHead
                className="w-[12%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('reference')}
              >
                <span className="flex items-center">{t('table.reference')}<SortIcon column="reference" /></span>
              </TableHead>
              <TableHead
                className="w-[14%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('branch')}
              >
                <span className="flex items-center">{t('table.branch')}<SortIcon column="branch" /></span>
              </TableHead>
              <TableHead className="w-[7%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 text-center">
                {t('table.accuracy')}
              </TableHead>
              <TableHead
                className="w-[9%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 cursor-pointer select-none group/sort"
                onClick={() => handleSort('reviewed')}
              >
                <span className="flex items-center">{t('table.status')}<SortIcon column="reviewed" /></span>
              </TableHead>
              <TableHead className="w-[6%] px-3 py-4 font-semibold text-xs uppercase tracking-wider text-slate-500 text-right">
                Action
              </TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {isLoading ? (
              Array.from({ length: 5 }).map((_, i) => (
                <TableRow key={i} className="animate-pulse">
                  {Array.from({ length: 9 }).map((_, j) => (
                    <TableCell key={j} className="px-3 py-4">
                      <div className="h-4 bg-slate-100 rounded w-20" />
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : transactions.length === 0 ? (
              <TableRow>
                <TableCell colSpan={9} className="px-3 py-12 text-center text-slate-500">
                  {t('transactions.noResults')}
                </TableCell>
              </TableRow>
            ) : (
              transactions.map((tx: any) => {
                const { date, time } = formatDate(tx.date);
                const { percent: accuracy } = getMatchAccuracy(tx.amount, tx.rawEmail);
                return (
                  <TableRow
                    key={tx.id}
                    className="group hover:bg-slate-50 transition-colors"
                  >
                    <TableCell className="px-3 py-4">
                      <div className="text-slate-900 font-medium text-sm">{date}</div>
                      <div className="text-slate-500 text-xs">{time}</div>
                    </TableCell>
                    <TableCell className="px-3 py-4 font-semibold text-slate-900 truncate" title={tx.sender}>
                      {tx.sender}
                    </TableCell>
                    <TableCell className="px-3 py-4">
                      {tx.envelopeNumber ? (
                        <span className="text-slate-700 font-mono text-xs bg-blue-50 text-blue-700 rounded px-1.5 py-0.5 font-bold">
                          #{tx.envelopeNumber}
                        </span>
                      ) : (
                        <span className="text-slate-300 text-xs">—</span>
                      )}
                    </TableCell>
                    <TableCell className="px-3 py-4 font-mono font-medium text-slate-700 whitespace-nowrap">
                      {formatAmount(tx.amount)}
                    </TableCell>
                    <TableCell className="px-3 py-4">
                      <span className="text-slate-600 font-mono text-xs bg-slate-100 rounded px-1.5 py-0.5 truncate block max-w-full" title={tx.reference || '—'}>
                        {tx.reference || '—'}
                      </span>
                    </TableCell>
                    <TableCell className="px-3 py-4 text-slate-600 truncate" title={tx.branch || 'Montreal'}>
                      <div className="flex items-center gap-2 min-w-0">
                        <span className={cn('h-2 w-2 rounded-full flex-shrink-0', getBranchColor(tx.branch || ''))} />
                        <span className="truncate">{tx.branch || 'Montreal'}</span>
                      </div>
                    </TableCell>
                    <TableCell className="px-3 py-4 text-center">
                      {accuracy === -1 ? (
                        <span className="text-slate-300 text-xs">—</span>
                      ) : (
                        <span
                          className={cn(
                            'inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-bold',
                            accuracy === 100
                              ? 'bg-emerald-50 text-emerald-700 ring-1 ring-emerald-200'
                              : accuracy >= 80
                                ? 'bg-amber-50 text-amber-700 ring-1 ring-amber-200'
                                : 'bg-red-50 text-red-700 ring-1 ring-red-200'
                          )}
                        >
                          {accuracy}%
                        </span>
                      )}
                    </TableCell>
                    <TableCell className="px-3 py-4">
                      <StatusBadge reviewed={tx.reviewed} />
                    </TableCell>
                    <TableCell className="px-3 py-4 text-right">
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <button className="text-slate-400 hover:text-slate-600 hover:bg-slate-100 p-1 rounded-md transition-all">
                            <MoreHorizontal className="h-5 w-5" />
                          </button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onSelect={() => navigate(`/transactions/${tx.id}/review`)}>
                            {t('transactions.viewDetails')}
                          </DropdownMenuItem>
                          <DropdownMenuItem onSelect={() => window.open(`/api/receipts/${tx.id}/pdf`, '_blank')}>
                            {t('transactions.downloadReceipt')}
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                );
              })
            )}
          </TableBody>
        </Table>
      </div>

      {/* Pagination */}
      <div className="flex items-center justify-between border-t border-border px-6 py-4 bg-white">
        <div className="text-sm text-slate-500">
          {t('transactions.showing')}{' '}
          <span className="font-semibold text-slate-900">{((page - 1) * (data?.limit ?? 500)) + 1}</span>{' '}
          {t('transactions.to')}{' '}
          <span className="font-semibold text-slate-900">{Math.min(page * (data?.limit ?? 500), total)}</span>{' '}
          {t('transactions.of')}{' '}
          <span className="font-semibold text-slate-900">{total.toLocaleString('fr-CA')}</span>{' '}
          {t('transactions.results')}
        </div>
        <div className="flex gap-2">
          <button
            disabled={page <= 1}
            onClick={() => setFilter('page', page - 1)}
            className="flex h-9 w-9 items-center justify-center rounded-lg border border-border bg-white text-slate-500 hover:bg-slate-50 hover:text-slate-900 disabled:opacity-50 transition-colors shadow-sm"
          >
            <ChevronLeft className="h-4 w-4" />
          </button>
          {Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
            const pageNum = i + 1;
            return (
              <button
                key={pageNum}
                onClick={() => setFilter('page', pageNum)}
                className={cn(
                  'flex h-9 w-9 items-center justify-center rounded-lg text-sm font-semibold transition-colors shadow-sm',
                  pageNum === page
                    ? 'bg-primary text-white shadow-md shadow-primary/20'
                    : 'border border-border bg-white text-slate-600 hover:bg-slate-50 hover:text-slate-900'
                )}
              >
                {pageNum}
              </button>
            );
          })}
          <button
            disabled={page >= totalPages}
            onClick={() => setFilter('page', page + 1)}
            className="flex h-9 w-9 items-center justify-center rounded-lg border border-border bg-white text-slate-500 hover:bg-slate-50 hover:text-slate-900 disabled:opacity-50 transition-colors shadow-sm"
          >
            <ChevronRight className="h-4 w-4" />
          </button>
        </div>
      </div>
    </div>
  );
}
