import { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { AppLayout } from '../../components/layout/AppLayout';
import { quickbooksApi, type TransactionsResponse } from '../../api/quickbooks';
import { LoadingSpinner } from '../../components/ui/LoadingSpinner';
import {
  Search,
  Filter,
  RefreshCw,
  AlertTriangle,
  ChevronDown,
  ChevronUp,
  ArrowUpCircle,
  ArrowDownCircle,
  FileText,
  CreditCard,
  ReceiptText,
} from 'lucide-react';

// ─── Helpers ──────────────────────────────────────────────────────────────

function formatCurrency(value: number | null | undefined): string {
  if (value == null || value === 0) return '$0.00';
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
  }).format(value);
}

function formatDate(dateStr: string | null): string {
  if (!dateStr) return '—';
  return new Date(dateStr).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
  });
}

function txTypeIcon(type: string) {
  const t = type.toLowerCase();
  if (t.includes('invoice')) return <ArrowUpCircle className="h-4 w-4 text-emerald-500" />;
  if (t.includes('payment') || t.includes('journal')) return <CreditCard className="h-4 w-4 text-blue-500" />;
  if (t.includes('credit') || t.includes('refund')) return <ArrowDownCircle className="h-4 w-4 text-amber-500" />;
  return <ReceiptText className="h-4 w-4 text-surface-400" />;
}

function txTypeLabel(type: string): string {
  return type || 'Unknown';
}

// ─── Main Page ────────────────────────────────────────────────────────────

export function QuickBooksTransactionsPage() {
  const [search, setSearch] = useState('');
  const [typeFilter, setTypeFilter] = useState('');
  const [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const [sortBy, setSortBy] = useState<'tx_date' | 'amount'>('tx_date');
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');

  const { data, isLoading, error, refetch } = useQuery<TransactionsResponse>({
    queryKey: ['quickbooks-transactions', search, typeFilter, dateFrom, dateTo],
    queryFn: () =>
      quickbooksApi.getTransactions({
        tx_type: typeFilter || undefined,
        date_from: dateFrom || undefined,
        date_to: dateTo || undefined,
        search: search || undefined,
      }),
    staleTime: 1 * 60 * 1000,
  });

  const transactions = useMemo(() => {
    let items = data?.transactions || [];
    return [...items].sort((a, b) => {
      let cmp = 0;
      if (sortBy === 'amount') {
        cmp = (a.amount ?? 0) - (b.amount ?? 0);
      } else {
        cmp = (a.tx_date || '').localeCompare(b.tx_date || '');
      }
      return sortDir === 'desc' ? -cmp : cmp;
    });
  }, [data, sortBy, sortDir]);

  // Collect unique transaction types from data
  const txTypes = useMemo(() => {
    const types = new Set<string>();
    (data?.transactions || []).forEach((tx) => {
      if (tx.tx_type) types.add(tx.tx_type);
    });
    return Array.from(types).sort();
  }, [data]);

  const totalCredits = transactions
    .filter((tx) => (tx.amount ?? 0) > 0)
    .reduce((sum, tx) => sum + (tx.amount ?? 0), 0);
  const totalDebits = Math.abs(
    transactions
      .filter((tx) => (tx.amount ?? 0) < 0)
      .reduce((sum, tx) => sum + (tx.amount ?? 0), 0)
  );

  const handleSort = (field: typeof sortBy) => {
    if (sortBy === field) {
      setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));
    } else {
      setSortBy(field);
      setSortDir('desc');
    }
  };

  const SortIcon = ({ field }: { field: typeof sortBy }) => {
    if (sortBy !== field) return <ChevronDown className="h-3 w-3 text-surface-300" />;
    return sortDir === 'desc' ? <ChevronDown className="h-3 w-3" /> : <ChevronUp className="h-3 w-3" />;
  };

  if (isLoading) {
    return (
      <AppLayout title="QuickBooks Transactions">
        <div className="flex items-center justify-center py-20">
          <LoadingSpinner size="lg" />
        </div>
      </AppLayout>
    );
  }

  if (error) {
    return (
      <AppLayout title="QuickBooks Transactions">
        <div className="flex flex-col items-center justify-center py-20 text-center">
          <AlertTriangle className="h-12 w-12 text-amber-400" />
          <h3 className="mt-4 text-lg font-semibold text-surface-900">Failed to Load Transactions</h3>
          <p className="mt-1 text-sm text-surface-500">
            {error instanceof Error ? error.message : 'Could not load transaction data.'}
          </p>
          <button
            onClick={() => refetch()}
            className="mt-4 flex items-center gap-2 rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-medium text-white hover:bg-brand-700 min-h-[44px]"
          >
            <RefreshCw className="h-4 w-4" />
            Try Again
          </button>
        </div>
      </AppLayout>
    );
  }

  return (
    <AppLayout title="QuickBooks Transactions">
      <div className="space-y-6">
        {/* Header */}
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className="text-xl font-bold text-surface-900">Transactions</h1>
            <p className="text-sm text-surface-500">
              {transactions.length} transactions
            </p>
          </div>
          <button
            onClick={() => refetch()}
            className="flex items-center gap-1.5 rounded-lg border border-surface-200 bg-white px-3 py-2 text-sm font-medium text-surface-700 hover:bg-surface-50 min-h-[44px]"
          >
            <RefreshCw className="h-4 w-4" />
            Refresh
          </button>
        </div>

        {/* Summary */}
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
          <div className="rounded-xl border border-surface-200 bg-white p-4">
            <div className="flex items-center gap-2">
              <FileText className="h-5 w-5 text-blue-500" />
              <span className="text-sm font-medium text-surface-600">Total Transactions</span>
            </div>
            <p className="mt-1 text-2xl font-bold text-surface-900">{transactions.length}</p>
          </div>
          <div className="rounded-xl border border-surface-200 bg-white p-4">
            <div className="flex items-center gap-2">
              <ArrowUpCircle className="h-5 w-5 text-emerald-500" />
              <span className="text-sm font-medium text-surface-600">Credits</span>
            </div>
            <p className="mt-1 text-2xl font-bold text-emerald-600">{formatCurrency(totalCredits)}</p>
          </div>
          <div className="rounded-xl border border-surface-200 bg-white p-4">
            <div className="flex items-center gap-2">
              <ArrowDownCircle className="h-5 w-5 text-red-500" />
              <span className="text-sm font-medium text-surface-600">Debits</span>
            </div>
            <p className="mt-1 text-2xl font-bold text-red-600">{formatCurrency(-totalDebits)}</p>
          </div>
        </div>

        {/* Filters */}
        <div className="rounded-xl border border-surface-200 bg-white p-4">
          <div className="flex items-center gap-2 mb-3">
            <Filter className="h-4 w-4 text-surface-400" />
            <span className="text-sm font-medium text-surface-700">Filters</span>
          </div>
          <div className="flex flex-wrap gap-3">
            <div className="flex-1 min-w-[200px]">
              <div className="relative">
                <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-surface-400" />
                <input
                  type="text"
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  placeholder="Search by ID, account, memo..."
                  className="w-full rounded-lg border border-surface-200 bg-white pl-9 pr-3 py-2 text-sm outline-none focus:border-brand-500 min-h-[44px]"
                />
              </div>
            </div>
            <select
              value={typeFilter}
              onChange={(e) => setTypeFilter(e.target.value)}
              className="rounded-lg border border-surface-200 bg-white px-3 py-2 text-sm font-medium text-surface-700 min-h-[44px]"
            >
              <option value="">All Types</option>
              {txTypes.map((t) => (
                <option key={t} value={t}>{t}</option>
              ))}
            </select>
            <input
              type="date"
              value={dateFrom}
              onChange={(e) => setDateFrom(e.target.value)}
              className="rounded-lg border border-surface-200 bg-white px-3 py-2 text-sm font-medium text-surface-700 min-h-[44px]"
            />
            <input
              type="date"
              value={dateTo}
              onChange={(e) => setDateTo(e.target.value)}
              className="rounded-lg border border-surface-200 bg-white px-3 py-2 text-sm font-medium text-surface-700 min-h-[44px]"
            />
          </div>
        </div>

        {/* Table */}
        <div className="overflow-x-auto rounded-xl border border-surface-200 bg-white">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-surface-200 bg-surface-50">
                <th className="px-4 py-3 text-left text-xs font-medium text-surface-500">Type</th>
                <th className="px-4 py-3 text-left text-xs font-medium text-surface-500">Account</th>
                <th className="px-4 py-3 text-left text-xs font-medium text-surface-500">Memo</th>
                <th
                  className="cursor-pointer px-4 py-3 text-right text-xs font-medium text-surface-500 hover:text-surface-700"
                  onClick={() => handleSort('amount')}
                >
                  <div className="flex items-center justify-end gap-1">
                    Amount
                    <SortIcon field="amount" />
                  </div>
                </th>
                <th
                  className="cursor-pointer px-4 py-3 text-right text-xs font-medium text-surface-500 hover:text-surface-700"
                  onClick={() => handleSort('tx_date')}
                >
                  <div className="flex items-center justify-end gap-1">
                    Date
                    <SortIcon field="tx_date" />
                  </div>
                </th>
              </tr>
            </thead>
            <tbody>
              {transactions.length === 0 ? (
                <tr>
                  <td colSpan={5} className="px-4 py-12 text-center text-surface-400">
                    No transactions found
                  </td>
                </tr>
              ) : (
                transactions.map((tx) => (
                  <tr
                    key={tx.id}
                    className="border-b border-surface-100 hover:bg-surface-50 last:border-b-0"
                  >
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-2">
                        {txTypeIcon(tx.tx_type)}
                        <span className="font-medium text-surface-700">{txTypeLabel(tx.tx_type)}</span>
                      </div>
                    </td>
                    <td className="px-4 py-3 text-surface-600">{tx.account_name || '—'}</td>
                    <td className="px-4 py-3 max-w-[200px] truncate text-surface-500">{tx.memo || '—'}</td>
                    <td className={`px-4 py-3 text-right font-medium ${
                      (tx.amount ?? 0) >= 0 ? 'text-emerald-600' : 'text-red-600'
                    }`}>
                      {formatCurrency(tx.amount)}
                    </td>
                    <td className="px-4 py-3 text-right text-surface-600">{formatDate(tx.tx_date)}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </div>
    </AppLayout>
  );
}
