'use client';

import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import {
  AlertTriangle, CheckCircle2, Download, Search,
  Loader2, PhoneCall, RefreshCw, X, Users, ChevronDown, ChevronUp,
} from 'lucide-react';
import { apiClient } from '@/lib/api-client';
import DatePicker from '@/components/ui/DatePicker';
import { parse, isValid } from 'date-fns';
import Pagination from '@/components/ui/Pagination';
import { usePagination } from '@/lib/use-pagination';

// ── Types ─────────────────────────────────────────────────────────────────────

interface Station {
  name: string;
  code: string;
  city: string;
}

interface PassengerDetail {
  name: string;
  category: string;
  seatNumber: string | null;
  coachNumber: string | null;
  seatType: string | null;
  fareMinor: number | null;
  fareCurrency: string;
}

interface DiscrepancyRow {
  pnr: string;
  passengerName: string;
  phone: string;
  bookingDate: string;
  origin: Station;
  destination: Station;
  departureAt: string;
  seatType: string;
  coachNumber: string | null;
  actualMinor: number;
  actualCurrency: string;
  paidMinor: number;
  paidCurrency: string;
  balanceMinor: number;
  balanceCurrency: string;
  passengerCount: number;
  passengers: PassengerDetail[];
  bookingStatus?: string;
  paymentStatus?: string | null;
}

interface DiscrepancyReport {
  total: number;
  totalBalanceEtbMinor: number;
  rows: DiscrepancyRow[];
  notFound?: boolean;
}

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

function fmtStation(name: string) {
  return name.replace(/\s+Station$/i, '');
}

function fmtMoney(amount: number, currency: string) {
  return `${currency} ${amount.toLocaleString('en-US', { minimumFractionDigits: 2 })}`;
}

function exportCsv(rows: DiscrepancyRow[]) {
  const headers = [
    'PNR', 'Passenger Name', 'Phone', 'Booking Date', 'Route',
    'Departure Time', 'Seat Type', 'Coach', 'Actual Price', 'Paid Amount', 'Balance',
  ];
  const lines = rows.map(r => [
    r.pnr,
    r.passengerName,
    r.phone,
    new Date(r.bookingDate).toLocaleDateString('en-GB'),
    `${fmtStation(r.origin.name)} → ${fmtStation(r.destination.name)}`,
    new Date(r.departureAt).toLocaleString('en-GB', { dateStyle: 'medium', timeStyle: 'short' }),
    r.seatType,
    r.coachNumber ?? '—',
    `${r.actualCurrency} ${(r.actualMinor / 100).toFixed(2)}`,
    `${r.paidCurrency} ${r.paidMinor.toFixed(2)}`,
    `${r.balanceCurrency} ${r.balanceMinor.toFixed(2)}`,
  ].map(v => `"${String(v).replace(/"/g, '""')}"`).join(','));

  const csv = [headers.join(','), ...lines].join('\n');
  const blob = new Blob([csv], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `payment-discrepancy-${new Date().toISOString().slice(0, 10)}.csv`;
  a.click();
  URL.revokeObjectURL(url);
}

// ── Balance badge ─────────────────────────────────────────────────────────────

function BalanceBadge({ row }: { row: DiscrepancyRow }) {
  if (row.balanceMinor <= 0) {
    return (
      <span className="inline-flex items-center gap-1 font-medium text-green-700 dark:text-green-400 bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 px-2 py-0.5 rounded-md text-xs">
        <CheckCircle2 className="w-3 h-3 shrink-0" />
        Fully paid
      </span>
    );
  }
  return (
    <span className="inline-flex items-center gap-1 font-bold text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 px-2 py-0.5 rounded-md text-xs">
      <AlertTriangle className="w-3 h-3 shrink-0" />
      {fmtMoney(row.balanceMinor, row.balanceCurrency)}
    </span>
  );
}

// ── Main page ─────────────────────────────────────────────────────────────────

type Applied = { from: string; to: string; sortBy: string; search: string };

export default function PaymentDiscrepancyPage() {
  const [from, setFrom] = useState('');
  const [to, setTo] = useState('');
  const [sortBy, setSortBy] = useState<'balance' | 'departure'>('balance');
  const [search, setSearch] = useState('');
  const [applied, setApplied] = useState<Applied | null>(null);
  const [expandedPnr, setExpandedPnr] = useState<string | null>(null);

  const isSearchMode = !!(applied?.search);

  const { data, isLoading, isError, refetch } = useQuery<DiscrepancyReport>({
    queryKey: ['payment-discrepancy', applied],
    queryFn: () =>
      apiClient.get('/reports/payment-discrepancy', {
        params: {
          from: applied?.search ? undefined : (applied?.from || undefined),
          to: applied?.search ? undefined : (applied?.to || undefined),
          sortBy: applied?.search ? undefined : applied?.sortBy,
          search: applied?.search || undefined,
        },
      }),
    enabled: applied !== null,
  });

  function handleSearch() {
    setApplied({ from, to, sortBy, search: search.trim() });
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === 'Enter') handleSearch();
  }

  function clearSearch() {
    setSearch('');
    setApplied(prev => prev ? { ...prev, search: '' } : null);
  }

  const rows = data?.rows ?? [];

  const { paged: pagedRows, page: discPage, totalPages: discTotalPages, setPage: setDiscPage } = usePagination(rows.filter(r => r.balanceMinor > 0), 20);

  const parsedFrom = from ? parse(from, 'yyyy-MM-dd', new Date()) : undefined;
  const fromDate = parsedFrom && isValid(parsedFrom) ? parsedFrom : undefined;

  return (
    <div className="p-6 space-y-6 max-w-7xl mx-auto">

      {/* Page header */}
      <div className="flex items-center gap-3">
        <div className="p-2 rounded-lg bg-red-100 dark:bg-red-950/40">
          <AlertTriangle className="w-6 h-6 text-red-600 dark:text-red-400" />
        </div>
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Payment Discrepancy Report</h1>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Bookings where the amount paid is less than the actual fare — flagged for follow-up
          </p>
        </div>
      </div>

      {/* Filters — single row */}
      <div className="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl px-5 py-3">
        <div className="flex items-center gap-2 min-w-0">

          {/* PNR / Ticket search — grows to fill available space */}
          <div className="relative flex-1 min-w-0">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" />
            <input
              type="text"
              value={search}
              onChange={e => setSearch(e.target.value.toUpperCase())}
              onKeyDown={handleKeyDown}
              placeholder="PNR or ticket number…"
              className="w-full pl-9 pr-8 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
            {search && (
              <button
                onClick={() => setSearch('')}
                className="absolute right-2.5 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200"
              >
                <X className="w-3.5 h-3.5" />
              </button>
            )}
          </div>

          <span className="text-xs text-gray-400 dark:text-gray-500 select-none shrink-0">or</span>

          {/* Date range */}
          <DatePicker
            value={from}
            onChange={setFrom}
            placeholder="From"
            disabled={!!search}
          />
          <span className="text-xs text-gray-400 dark:text-gray-500 select-none shrink-0">–</span>
          <DatePicker
            value={to}
            onChange={setTo}
            placeholder="To"
            disabled={!!search}
            minDate={fromDate}
          />

          {/* Sort */}
          <select
            value={sortBy}
            onChange={e => setSortBy(e.target.value as any)}
            disabled={!!search}
            className="shrink-0 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-40 disabled:cursor-not-allowed"
          >
            <option value="balance">Highest balance first</option>
            <option value="departure">Earliest departure first</option>
          </select>

          {/* Actions */}
          <div className="flex items-center gap-2 shrink-0">
            {applied && (
              <button
                onClick={() => refetch()}
                title="Refresh"
                className="p-2 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
              >
                <RefreshCw className="w-4 h-4" />
              </button>
            )}
            {rows.length > 0 && !isSearchMode && (
              <button
                onClick={() => exportCsv(rows)}
                className="flex items-center gap-2 px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
              >
                <Download className="w-4 h-4" />
                Export CSV
              </button>
            )}
            <button
              onClick={handleSearch}
              disabled={isLoading}
              className="flex items-center gap-2 px-4 py-2 rounded-lg bg-blue-600 text-white text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              {isLoading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Search className="w-4 h-4" />}
              Search
            </button>
          </div>
        </div>
      </div>

      {/* Error */}
      {isError && (
        <div className="flex items-center gap-2 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 px-4 py-3 text-sm text-red-700 dark:text-red-400">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          Failed to load discrepancy data. Please try again.
        </div>
      )}

      {/* Not found */}
      {data?.notFound && (
        <div className="flex items-center gap-2 rounded-lg bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-800 px-4 py-3 text-sm text-amber-700 dark:text-amber-400">
          <AlertTriangle className="w-4 h-4 shrink-0" />
          No booking found for <span className="font-mono font-bold mx-1">{applied?.search}</span> — check the PNR or ticket number and try again.
        </div>
      )}

      {/* Table */}
      {rows.length > 0 && (
        <div className="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden">
          {isSearchMode && (
            <div className="px-5 py-3 border-b border-gray-100 dark:border-gray-800 flex items-center gap-2">
              <span className="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide">
                Lookup result for
              </span>
              <span className="font-mono text-sm font-bold text-gray-900 dark:text-white bg-gray-100 dark:bg-gray-800 px-2 py-0.5 rounded">
                {applied?.search}
              </span>
              <button
                onClick={clearSearch}
                className="ml-auto text-xs text-blue-600 dark:text-blue-400 hover:underline"
              >
                Clear lookup
              </button>
            </div>
          )}
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/60">
                  {[
                    'Passenger', 'PNR', 'Booking Date', 'Route', 'Departure',
                    'Seat Type', 'Actual Price', 'Paid', 'Balance', 'Passengers', 'Phone',
                  ].map(h => (
                    <th
                      key={h}
                      className="px-4 py-3 text-left text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider whitespace-nowrap"
                    >
                      {h}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-100 dark:divide-gray-800">
                {pagedRows.map((row, i) => {
                  const isExpanded = expandedPnr === row.pnr;
                  const hasMultiple = row.passengerCount > 1;
                  return (
                    <>
                      <tr
                        key={row.pnr + i}
                        className="hover:bg-gray-50 dark:hover:bg-gray-800/40 transition-colors"
                      >
                        <td className="px-4 py-3 font-medium text-gray-900 dark:text-white whitespace-nowrap">
                          {row.passengerName}
                        </td>
                        <td className="px-4 py-3">
                          <span className="font-mono text-xs bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 px-1.5 py-0.5 rounded">
                            {row.pnr}
                          </span>
                        </td>
                        <td className="px-4 py-3 text-gray-600 dark:text-gray-400 whitespace-nowrap">
                          {new Date(row.bookingDate).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })}
                        </td>
                        <td className="px-4 py-3 whitespace-nowrap">
                          <span className="text-gray-900 dark:text-white font-medium">
                            {fmtStation(row.origin.name)}
                          </span>
                          <span className="text-gray-400 dark:text-gray-500 mx-1">→</span>
                          <span className="text-gray-900 dark:text-white font-medium">
                            {fmtStation(row.destination.name)}
                          </span>
                        </td>
                        <td className="px-4 py-3 text-gray-600 dark:text-gray-400 whitespace-nowrap">
                          {new Date(row.departureAt).toLocaleString('en-US', {
                            month: 'short', day: 'numeric',
                            hour: 'numeric', minute: '2-digit', hour12: true,
                            timeZone: 'Africa/Addis_Ababa',
                          })}
                        </td>
                        <td className="px-4 py-3">
                          <div className="text-gray-900 dark:text-white">{row.seatType}</div>
                          {row.coachNumber && (
                            <div className="text-xs text-gray-400 dark:text-gray-500">Coach {row.coachNumber}</div>
                          )}
                        </td>
                        <td className="px-4 py-3 text-gray-700 dark:text-gray-300 whitespace-nowrap font-medium">
                          {fmtMoney(row.actualMinor / 100, row.actualCurrency)}
                        </td>
                        <td className="px-4 py-3 text-gray-700 dark:text-gray-300 whitespace-nowrap">
                          {fmtMoney(row.paidMinor, row.paidCurrency)}
                        </td>
                        <td className="px-4 py-3 whitespace-nowrap text-red-600 dark:text-red-400 font-semibold">
                          <BalanceBadge row={row} />
                        </td>
                        {/* Passengers column */}
                        <td className="px-4 py-3 whitespace-nowrap">
                          {hasMultiple ? (
                            <button
                              onClick={() => setExpandedPnr(isExpanded ? null : row.pnr)}
                              className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md text-xs font-medium bg-blue-50 dark:bg-blue-950/30 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-800 hover:bg-blue-100 dark:hover:bg-blue-950/50 transition-colors"
                            >
                              <Users className="w-3 h-3" />
                              {row.passengerCount}
                              {isExpanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
                            </button>
                          ) : (
                            <span className="text-xs text-gray-400 dark:text-gray-500 flex items-center gap-1">
                              <Users className="w-3 h-3" />1
                            </span>
                          )}
                        </td>
                        <td className="px-4 py-3 whitespace-nowrap">
                          {row.phone && row.phone !== '—' ? (
                            <a
                              href={`tel:${row.phone}`}
                              className="flex items-center gap-1.5 text-blue-600 dark:text-blue-400 hover:underline"
                            >
                              <PhoneCall className="w-3.5 h-3.5 shrink-0" />
                              {row.phone}
                            </a>
                          ) : (
                            <span className="text-gray-400 dark:text-gray-500">—</span>
                          )}
                        </td>
                      </tr>

                      {/* Expandable passenger breakdown */}
                      {isExpanded && (
                        <tr key={row.pnr + '-passengers'} className="bg-blue-50/50 dark:bg-blue-950/10">
                          <td colSpan={11} className="px-6 py-3">
                            <div className="text-xs font-semibold text-blue-700 dark:text-blue-400 uppercase tracking-wide mb-2 flex items-center gap-1.5">
                              <Users className="w-3.5 h-3.5" />
                              Passengers under {row.pnr}
                            </div>
                            <table className="w-full text-xs">
                              <thead>
                                <tr className="text-left text-gray-500 dark:text-gray-400">
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">#</th>
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">Name</th>
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">Category</th>
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">Coach</th>
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">Seat</th>
                                  <th className="pb-1.5 pr-4 font-semibold uppercase tracking-wide">Class</th>
                                  <th className="pb-1.5 font-semibold uppercase tracking-wide">Fare</th>
                                </tr>
                              </thead>
                              <tbody className="divide-y divide-blue-100 dark:divide-blue-900/30">
                                {row.passengers.map((p, pi) => (
                                  <tr key={pi} className="text-gray-700 dark:text-gray-300">
                                    <td className="py-1.5 pr-4 text-gray-400">{pi + 1}</td>
                                    <td className="py-1.5 pr-4 font-medium text-gray-900 dark:text-white whitespace-nowrap">{p.name}</td>
                                    <td className="py-1.5 pr-4 capitalize">{p.category.toLowerCase()}</td>
                                    <td className="py-1.5 pr-4">{p.coachNumber ?? '—'}</td>
                                    <td className="py-1.5 pr-4 font-mono">{p.seatNumber ?? '—'}</td>
                                    <td className="py-1.5 pr-4">{p.seatType ?? '—'}</td>
                                    <td className="py-1.5 font-medium">
                                      {p.fareMinor != null
                                        ? fmtMoney(p.fareMinor, p.fareCurrency)
                                        : '—'}
                                    </td>
                                  </tr>
                                ))}
                              </tbody>
                            </table>
                          </td>
                        </tr>
                      )}
                    </>
                  );
                })}
              </tbody>
            </table>
          </div>
          {!isSearchMode && (
            <div className="px-4 py-3 border-t border-gray-100 dark:border-gray-800 flex items-center justify-between">
              <span className="text-xs text-gray-400 dark:text-gray-500">
                {rows.filter(r => r.balanceMinor > 0).length} record{rows.filter(r => r.balanceMinor > 0).length !== 1 ? 's' : ''} — click a phone number to call directly, or export CSV for bulk follow-up
              </span>
              <Pagination currentPage={discPage} totalPages={discTotalPages} onPageChange={setDiscPage} />
            </div>
          )}
        </div>
      )}

      {/* Empty state — date range returned nothing */}
      {applied && !isSearchMode && !isLoading && !isError && rows.length === 0 && data && !data.notFound && (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <CheckCircle2 className="w-12 h-12 text-green-400 mb-3" />
          <p className="text-gray-500 dark:text-gray-400">No underpaid bookings found for this period</p>
        </div>
      )}

      {/* Initial state */}
      {!applied && !isLoading && (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <Search className="w-12 h-12 text-gray-300 dark:text-gray-600 mb-3" />
          <p className="text-gray-500 dark:text-gray-400">Enter a PNR or ticket number above, or select a date range to generate the report</p>
        </div>
      )}
    </div>
  );
}
