'use client';

import { useEffect, useState, useCallback } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Skeleton } from '@/components/ui/skeleton';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
  PaginationEllipsis,
} from '@/components/ui/pagination';
import {
  Search,
  Filter,
  RotateCcw,
  Eye,
  Copy,
  Download,
  MoreHorizontal,
  ChevronLeft,
  ChevronRight,
} from 'lucide-react';

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

interface Order {
  id: string;
  mOrderId: string;
  payOrderId: string | null;
  amount: number;
  paidAmount: number;
  currency: string;
  status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'SIGN_FAILED';
  paymentUrl: string | null;
  utr: string | null;
  sign: string | null;
  callbackPayload: string | null;
  signVerified: boolean;
  telegramSent: boolean;
  telegramError: string | null;
  gateway: string;
  createdAt: string;
  callbackAt: string | null;
}

interface PaginationData {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
}

interface Filters {
  status: string;
  search: string;
  startDate: string;
  endDate: string;
  minAmount: string;
  maxAmount: string;
}

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

function formatCurrency(value: number): string {
  return new Intl.NumberFormat('en-IN', {
    style: 'currency',
    currency: 'INR',
    minimumFractionDigits: 2,
  }).format(value);
}

function formatDate(dateStr: string | null): string {
  if (!dateStr) return '—';
  const date = new Date(dateStr);
  return date.toLocaleString('en-IN', {
    day: '2-digit',
    month: 'short',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: true,
  });
}

function formatShortDate(dateStr: string | null): string {
  if (!dateStr) return '—';
  const date = new Date(dateStr);
  return date.toLocaleString('en-IN', {
    day: '2-digit',
    month: 'short',
    hour: '2-digit',
    minute: '2-digit',
    hour12: true,
  });
}

function truncateId(id: string, maxLen = 12): string {
  if (id.length <= maxLen) return id;
  return `${id.slice(0, maxLen)}...`;
}

function getGatewayBadge(gateway: string) {
  switch (gateway) {
    case 'LGPAY':
      return <Badge className="bg-blue-100 text-blue-800 hover:bg-blue-100 border-blue-200 text-xs">LG-Pay</Badge>;
    case 'SILKPAY':
    default:
      return <Badge className="bg-emerald-100 text-emerald-800 hover:bg-emerald-100 border-emerald-200 text-xs">SilkPay</Badge>;
  }
}

function getStatusBadge(status: Order['status']) {
  switch (status) {
    case 'PENDING':
      return (
        <Badge className="bg-amber-100 text-amber-800 hover:bg-amber-100 border-amber-200">
          Pending
        </Badge>
      );
    case 'SUCCESS':
      return (
        <Badge className="bg-emerald-100 text-emerald-800 hover:bg-emerald-100 border-emerald-200">
          Success
        </Badge>
      );
    case 'FAILED':
      return (
        <Badge variant="destructive">
          Failed
        </Badge>
      );
    case 'SIGN_FAILED':
      return (
        <Badge className="bg-orange-100 text-orange-800 hover:bg-orange-100 border-orange-200">
          Sign Failed
        </Badge>
      );
    default:
      return <Badge variant="outline">{status}</Badge>;
  }
}

// ─── Pagination range helper ─────────────────────────────────────────

function getPageRange(current: number, total: number): (number | 'ellipsis')[] {
  if (total <= 7) {
    return Array.from({ length: total }, (_, i) => i + 1);
  }

  const pages: (number | 'ellipsis')[] = [1];

  if (current > 3) {
    pages.push('ellipsis');
  }

  const start = Math.max(2, current - 1);
  const end = Math.min(total - 1, current + 1);

  for (let i = start; i <= end; i++) {
    pages.push(i);
  }

  if (current < total - 2) {
    pages.push('ellipsis');
  }

  if (total > 1) {
    pages.push(total);
  }

  return pages;
}

// ─── Skeleton Row ────────────────────────────────────────────────────

function TableSkeleton() {
  return (
    <>
      {Array.from({ length: 10 }).map((_, i) => (
        <TableRow key={i}>
          <TableCell>
            <Skeleton className="h-4 w-20" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-28" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-28" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-20" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-20" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-20" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-5 w-16" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-16" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-5 w-14" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-32" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-28" />
          </TableCell>
          <TableCell>
            <Skeleton className="h-4 w-6" />
          </TableCell>
        </TableRow>
      ))}
    </>
  );
}

// ─── Main Component ──────────────────────────────────────────────────

export default function OrdersPage() {
  const router = useRouter();

  // State
  const [orders, setOrders] = useState<Order[]>([]);
  const [pagination, setPagination] = useState<PaginationData>({
    page: 1,
    limit: 20,
    total: 0,
    totalPages: 0,
  });
  const [loading, setLoading] = useState(true);
  const [exporting, setExporting] = useState(false);

  // Filters
  const [filters, setFilters] = useState<Filters>({
    status: 'ALL',
    search: '',
    startDate: '',
    endDate: '',
    minAmount: '',
    maxAmount: '',
  });
  const [appliedFilters, setAppliedFilters] = useState<Filters>({ ...filters });

  // ─── Fetch Orders ──────────────────────────────────────────────────

  const fetchOrders = useCallback(async (page: number, f: Filters) => {
    setLoading(true);
    try {
      const params = new URLSearchParams();
      params.set('page', page.toString());
      params.set('limit', '20');
      if (f.status && f.status !== 'ALL') params.set('status', f.status);
      if (f.search) params.set('search', f.search);
      if (f.startDate) params.set('startDate', f.startDate);
      if (f.endDate) params.set('endDate', f.endDate);
      if (f.minAmount) params.set('minAmount', f.minAmount);
      if (f.maxAmount) params.set('maxAmount', f.maxAmount);

      const res = await fetch(`/api/admin/orders?${params.toString()}`);
      if (!res.ok) {
        throw new Error('Failed to load orders');
      }
      const data = await res.json();
      setOrders(data.orders || []);
      setPagination(data.pagination || { page: 1, limit: 20, total: 0, totalPages: 0 });
    } catch (err) {
      toast.error('Failed to load orders');
      console.error(err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchOrders(pagination.page, appliedFilters);
  }, [pagination.page, appliedFilters, fetchOrders]);

  // ─── Handlers ──────────────────────────────────────────────────────

  const handleApplyFilters = () => {
    setAppliedFilters({ ...filters });
    setPagination((prev) => ({ ...prev, page: 1 }));
  };

  const handleResetFilters = () => {
    const reset: Filters = {
      status: 'ALL',
      search: '',
      startDate: '',
      endDate: '',
      minAmount: '',
      maxAmount: '',
    };
    setFilters(reset);
    setAppliedFilters(reset);
    setPagination((prev) => ({ ...prev, page: 1 }));
  };

  const handlePageChange = (page: number) => {
    if (page >= 1 && page <= pagination.totalPages) {
      setPagination((prev) => ({ ...prev, page }));
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      handleApplyFilters();
    }
  };

  // ─── Actions ───────────────────────────────────────────────────────

  const handleViewDetail = (orderId: string) => {
    router.push(`/admin/orders/${orderId}`);
  };

  const handleCopyPaymentUrl = async (order: Order) => {
    if (!order.paymentUrl) {
      toast.error('No payment URL available');
      return;
    }
    try {
      await navigator.clipboard.writeText(order.paymentUrl);
      toast.success('Payment URL copied to clipboard');
    } catch {
      toast.error('Failed to copy payment URL');
    }
  };

  const handleCopyUTR = async (order: Order) => {
    if (!order.utr) {
      toast.error('No UTR available');
      return;
    }
    try {
      await navigator.clipboard.writeText(order.utr);
      toast.success('UTR copied to clipboard');
    } catch {
      toast.error('Failed to copy UTR');
    }
  };

  // ─── Export CSV ────────────────────────────────────────────────────

  const handleExportCSV = async (exportAll = false) => {
    setExporting(true);
    try {
      let idsToExport: string[];

      if (exportAll) {
        // For "all", we need to fetch all IDs matching current filters
        // We'll use a large limit approach or rely on the backend
        const params = new URLSearchParams();
        params.set('page', '1');
        params.set('limit', '99999');
        if (appliedFilters.status && appliedFilters.status !== 'ALL')
          params.set('status', appliedFilters.status);
        if (appliedFilters.search) params.set('search', appliedFilters.search);
        if (appliedFilters.startDate) params.set('startDate', appliedFilters.startDate);
        if (appliedFilters.endDate) params.set('endDate', appliedFilters.endDate);
        if (appliedFilters.minAmount) params.set('minAmount', appliedFilters.minAmount);
        if (appliedFilters.maxAmount) params.set('maxAmount', appliedFilters.maxAmount);

        const res = await fetch(`/api/admin/orders?${params.toString()}`);
        if (!res.ok) throw new Error('Failed to fetch orders');
        const data = await res.json();
        idsToExport = (data.orders || []).map((o: Order) => o.id);
      } else {
        idsToExport = orders.map((o) => o.id);
      }

      if (idsToExport.length === 0) {
        toast.error('No orders to export');
        return;
      }

      const exportRes = await fetch('/api/admin/orders', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ids: idsToExport }),
      });

      if (!exportRes.ok) throw new Error('Failed to export');

      const exportData = await exportRes.json();

      // Create blob and trigger download
      const blob = new Blob([exportData.csv], { type: 'text/csv;charset=utf-8;' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = exportData.filename || `orders-export-${Date.now()}.csv`;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);

      toast.success(
        `Exported ${idsToExport.length} order${idsToExport.length > 1 ? 's' : ''} successfully`
      );
    } catch (err) {
      toast.error('Failed to export orders');
      console.error(err);
    } finally {
      setExporting(false);
    }
  };

  // ─── Render ────────────────────────────────────────────────────────

  return (
    <div className="space-y-6">
      {/* Page Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">Orders</h1>
          <p className="text-sm text-gray-500 mt-1">
            Manage and monitor all payment orders
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={() => handleExportCSV(false)}
            disabled={exporting || orders.length === 0}
          >
            <Download className="h-4 w-4 mr-1.5" />
            Export Current
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() => handleExportCSV(true)}
            disabled={exporting}
          >
            <Download className="h-4 w-4 mr-1.5" />
            Export All
          </Button>
        </div>
      </div>

      {/* Filters Section */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-base font-semibold flex items-center gap-2">
            <Filter className="h-4 w-4" />
            Filters
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 xl:grid-cols-6 gap-3">
            {/* Search */}
            <div className="relative sm:col-span-2 lg:col-span-2 xl:col-span-2">
              <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-gray-400" />
              <Input
                placeholder="Search by mOrderId, payOrderId, UTR..."
                className="pl-9"
                value={filters.search}
                onChange={(e) => setFilters((prev) => ({ ...prev, search: e.target.value }))}
                onKeyDown={handleKeyDown}
              />
            </div>

            {/* Status */}
            <Select
              value={filters.status}
              onValueChange={(value) =>
                setFilters((prev) => ({ ...prev, status: value }))
              }
            >
              <SelectTrigger>
                <SelectValue placeholder="All Statuses" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="ALL">All Statuses</SelectItem>
                <SelectItem value="PENDING">Pending</SelectItem>
                <SelectItem value="SUCCESS">Success</SelectItem>
                <SelectItem value="FAILED">Failed</SelectItem>
                <SelectItem value="SIGN_FAILED">Sign Failed</SelectItem>
              </SelectContent>
            </Select>

            {/* Start Date */}
            <Input
              type="date"
              placeholder="Start Date"
              value={filters.startDate}
              onChange={(e) =>
                setFilters((prev) => ({ ...prev, startDate: e.target.value }))
              }
            />

            {/* End Date */}
            <Input
              type="date"
              placeholder="End Date"
              value={filters.endDate}
              onChange={(e) =>
                setFilters((prev) => ({ ...prev, endDate: e.target.value }))
              }
            />

            {/* Min Amount */}
            <Input
              type="number"
              placeholder="Min Amount"
              value={filters.minAmount}
              onChange={(e) =>
                setFilters((prev) => ({ ...prev, minAmount: e.target.value }))
              }
              onKeyDown={handleKeyDown}
            />

            {/* Max Amount */}
            <Input
              type="number"
              placeholder="Max Amount"
              value={filters.maxAmount}
              onChange={(e) =>
                setFilters((prev) => ({ ...prev, maxAmount: e.target.value }))
              }
              onKeyDown={handleKeyDown}
            />

            {/* Action Buttons */}
            <div className="flex gap-2 sm:col-span-2 lg:col-span-2 xl:col-span-2">
              <Button onClick={handleApplyFilters} className="flex-1">
                <Filter className="h-4 w-4 mr-1.5" />
                Apply Filters
              </Button>
              <Button variant="outline" onClick={handleResetFilters} className="flex-1">
                <RotateCcw className="h-4 w-4 mr-1.5" />
                Reset
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Orders Table */}
      <Card>
        <CardContent className="p-0">
          <div className="overflow-x-auto -mx-1">
            <Table className="min-w-[900px]">
              <TableHeader>
                <TableRow>
                  <TableHead className="whitespace-nowrap">Order ID</TableHead>
                  <TableHead className="whitespace-nowrap">mOrderId</TableHead>
                  <TableHead className="whitespace-nowrap">Gateway</TableHead>
                  <TableHead className="whitespace-nowrap">payOrderId</TableHead>
                  <TableHead className="whitespace-nowrap text-right">Amount</TableHead>
                  <TableHead className="whitespace-nowrap text-right">Paid</TableHead>
                  <TableHead className="whitespace-nowrap">UTR</TableHead>
                  <TableHead className="whitespace-nowrap">Status</TableHead>
                  <TableHead className="whitespace-nowrap">Payment URL</TableHead>
                  <TableHead className="whitespace-nowrap hidden lg:table-cell">Created At</TableHead>
                  <TableHead className="whitespace-nowrap hidden lg:table-cell">Callback At</TableHead>
                  <TableHead className="whitespace-nowrap text-center">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {loading ? (
                  <TableSkeleton />
                ) : orders.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={12} className="text-center py-12">
                      <div className="flex flex-col items-center gap-2 text-gray-500">
                        <Search className="h-8 w-8" />
                        <p className="text-sm font-medium">No orders found</p>
                        <p className="text-xs">
                          Try adjusting your filters or search criteria
                        </p>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : (
                  orders.map((order) => (
                    <TableRow key={order.id} className="hover:bg-gray-50/50">
                      {/* Order ID (internal, truncated) */}
                      <TableCell>
                        <span
                          className="font-mono text-xs text-gray-600 cursor-help"
                          title={order.id}
                        >
                          {truncateId(order.id, 10)}
                        </span>
                      </TableCell>

                      {/* mOrderId */}
                      <TableCell>
                        <span
                          className="font-mono text-xs font-medium"
                          title={order.mOrderId}
                        >
                          {truncateId(order.mOrderId, 16)}
                        </span>
                      </TableCell>

                      {/* Gateway */}
                      <TableCell>{getGatewayBadge(order.gateway || 'SILKPAY')}</TableCell>

                      {/* payOrderId */}
                      <TableCell>
                        <span
                          className="font-mono text-xs text-gray-500"
                          title={order.payOrderId || undefined}
                        >
                          {order.payOrderId ? truncateId(order.payOrderId, 16) : '—'}
                        </span>
                      </TableCell>

                      {/* Amount */}
                      <TableCell className="text-right whitespace-nowrap font-medium">
                        {formatCurrency(order.amount)}
                      </TableCell>

                      {/* Paid Amount */}
                      <TableCell className="text-right whitespace-nowrap">
                        <span
                          className={
                            order.paidAmount > 0
                              ? 'text-emerald-700 font-medium'
                              : 'text-gray-400'
                          }
                        >
                          {formatCurrency(order.paidAmount)}
                        </span>
                      </TableCell>

                      {/* UTR */}
                      <TableCell>
                        <span
                          className="font-mono text-xs"
                          title={order.utr || undefined}
                        >
                          {order.utr ? truncateId(order.utr, 16) : '—'}
                        </span>
                      </TableCell>

                      {/* Status */}
                      <TableCell>{getStatusBadge(order.status)}</TableCell>

                      {/* Payment URL */}
                      <TableCell>
                        {order.paymentUrl ? (
                          <span
                            className="text-xs text-emerald-600 hover:text-emerald-800 cursor-pointer truncate block max-w-[120px]"
                            title={order.paymentUrl}
                            onClick={() => handleCopyPaymentUrl(order)}
                          >
                            {truncateId(order.paymentUrl, 20)}
                          </span>
                        ) : (
                          <span className="text-xs text-gray-400">—</span>
                        )}
                      </TableCell>

                      {/* Created At */}
                      <TableCell className="whitespace-nowrap text-xs text-gray-600 hidden lg:table-cell">
                        <span title={formatDate(order.createdAt)}>
                          {formatShortDate(order.createdAt)}
                        </span>
                      </TableCell>

                      {/* Callback At */}
                      <TableCell className="whitespace-nowrap text-xs text-gray-600 hidden lg:table-cell">
                        <span title={formatDate(order.callbackAt)}>
                          {formatShortDate(order.callbackAt)}
                        </span>
                      </TableCell>

                      {/* Actions */}
                      <TableCell className="text-center">
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon" className="h-8 w-8">
                              <MoreHorizontal className="h-4 w-4" />
                              <span className="sr-only">Open actions</span>
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem onClick={() => handleViewDetail(order.id)}>
                              <Eye className="h-4 w-4 mr-2" />
                              View Detail
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              onClick={() => handleCopyPaymentUrl(order)}
                              disabled={!order.paymentUrl}
                            >
                              <Copy className="h-4 w-4 mr-2" />
                              Copy Payment URL
                            </DropdownMenuItem>
                            <DropdownMenuItem
                              onClick={() => handleCopyUTR(order)}
                              disabled={!order.utr}
                            >
                              <Copy className="h-4 w-4 mr-2" />
                              Copy UTR
                            </DropdownMenuItem>
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>

          {/* Pagination */}
          {!loading && pagination.totalPages > 1 && (
            <div className="flex flex-col sm:flex-row items-center justify-between gap-4 px-4 py-4 border-t">
              <p className="text-sm text-gray-500">
                Showing{' '}
                <span className="font-medium text-gray-700">
                  {(pagination.page - 1) * pagination.limit + 1}
                </span>{' '}
                to{' '}
                <span className="font-medium text-gray-700">
                  {Math.min(pagination.page * pagination.limit, pagination.total)}
                </span>{' '}
                of{' '}
                <span className="font-medium text-gray-700">
                  {pagination.total}
                </span>{' '}
                results
              </p>

              <Pagination>
                <PaginationContent>
                  <PaginationItem>
                    <PaginationPrevious
                      onClick={() => handlePageChange(pagination.page - 1)}
                      className={
                        pagination.page <= 1
                          ? 'pointer-events-none opacity-50'
                          : 'cursor-pointer'
                      }
                    />
                  </PaginationItem>

                  {getPageRange(pagination.page, pagination.totalPages).map(
                    (page, idx) =>
                      page === 'ellipsis' ? (
                        <PaginationItem key={`ellipsis-${idx}`}>
                          <PaginationEllipsis />
                        </PaginationItem>
                      ) : (
                        <PaginationItem key={page}>
                          <PaginationLink
                            isActive={page === pagination.page}
                            onClick={() => handlePageChange(page)}
                            className="cursor-pointer"
                          >
                            {page}
                          </PaginationLink>
                        </PaginationItem>
                      )
                  )}

                  <PaginationItem>
                    <PaginationNext
                      onClick={() => handlePageChange(pagination.page + 1)}
                      className={
                        pagination.page >= pagination.totalPages
                          ? 'pointer-events-none opacity-50'
                          : 'cursor-pointer'
                      }
                    />
                  </PaginationItem>
                </PaginationContent>
              </Pagination>
            </div>
          )}

          {/* Single page summary */}
          {!loading && pagination.totalPages <= 1 && pagination.total > 0 && (
            <div className="px-4 py-3 border-t">
              <p className="text-sm text-gray-500 text-center">
                Showing all{' '}
                <span className="font-medium text-gray-700">
                  {pagination.total}
                </span>{' '}
                result{pagination.total !== 1 ? 's' : ''}
              </p>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
