"use client";

import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import toast from "react-hot-toast";
import { customInstance } from "@/config/axios";

// Row shape returned by GET /v1/transactions. Kept local (not orval-generated) to avoid
// the orval v8 regen breakage — see package.json pinning history.
interface Transaction {
  uuid: string;
  user?: {
    uuid: string;
    username: string;
    email: string;
    avatar?: string | null;
    role?: string | null;
  } | null;
  amount: number;
  currency: string;
  status: string;
  source: string;
  paid_at: string;
  external_id?: string | null;
}

export default function AdminTransactions() {
  const t = useTranslations();
  const router = useRouter();

  const [searchQuery, setSearchQuery] = useState("");
  const [sortBy, setSortBy] = useState("");
  const [sourceFilter, setSourceFilter] = useState("");
  const [dateFrom, setDateFrom] = useState("");
  const [dateTo, setDateTo] = useState("");

  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [loading, setLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(50);
  const [totalPages, setTotalPages] = useState(1);
  const [totalCount, setTotalCount] = useState(0);

  // Backend already hard-filters amount > 0 and status = 'completed' server-side, so we don't
  // send amount_gt or status — everything returned is already real, completed money.
  const fetchTransactions = useCallback(async () => {
    try {
      const params: Record<string, string | number> = {
        page: currentPage,
        limit: itemsPerPage,
      };
      if (searchQuery) params.search = searchQuery;
      if (sourceFilter) params.source = sourceFilter;
      if (dateFrom) params.date_from = dateFrom;
      if (dateTo) params.date_to = dateTo;
      if (sortBy) {
        params.sort_field = sortBy;
        params.sort_direction = 'DESC';
      }

      const response = await customInstance<{
        data: {
          transactions: Transaction[];
          total_count: number;
          page: number;
          limit: number;
          total_pages: number;
        };
      }>({
        url: '/v1/transactions',
        method: 'GET',
        params,
      });

      setTransactions(response.data.transactions || []);
      setTotalCount(response.data.total_count || 0);
      setTotalPages(response.data.total_pages || 1);
    } catch (error) {
      console.error('Error fetching transactions:', error);
      setTransactions([]);
    }
  }, [currentPage, itemsPerPage, searchQuery, sortBy, sourceFilter, dateFrom, dateTo]);

  useEffect(() => {
    const load = async () => {
      setLoading(true);
      await fetchTransactions();
      setLoading(false);
    };
    load();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (!loading) fetchTransactions();
  }, [currentPage, itemsPerPage, sortBy, sourceFilter, dateFrom, dateTo]); // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    const debounce = setTimeout(() => {
      if (currentPage === 1) fetchTransactions();
      else setCurrentPage(1);
    }, 500);
    return () => clearTimeout(debounce);
  }, [searchQuery]); // eslint-disable-line react-hooks/exhaustive-deps

  const formatDate = (s: string | null | undefined) => {
    if (!s) return '-';
    return new Date(s).toLocaleDateString('en-US', { day: 'numeric', month: 'short', year: 'numeric' });
  };

  const formatMoney = (amount: number | undefined, currency: string | undefined) => {
    if (amount === undefined || amount === null) return '-';
    const symbol = currency === 'USD' ? '$' : (currency || '$');
    return `${symbol}${amount.toLocaleString()}`;
  };

  const exportToXLS = async () => {
    // Page-iterate to grab every row matching the current filters; not capped to the visible page.
    const PAGE_SIZE = 500;
    const all: Transaction[] = [];
    let page = 1;
    let totalPagesRemote = 1;
    let complete = true;
    const filters: Record<string, string | number> = {};
    if (searchQuery) filters.search = searchQuery;
    if (sourceFilter) filters.source = sourceFilter;
    if (dateFrom) filters.date_from = dateFrom;
    if (dateTo) filters.date_to = dateTo;
    if (sortBy) {
      filters.sort_field = sortBy;
      filters.sort_direction = 'DESC';
    }
    try {
      do {
        const resp = await customInstance<{
          data: { transactions: Transaction[]; total_pages: number };
        }>({
          url: '/v1/transactions',
          method: 'GET',
          params: { page, limit: PAGE_SIZE, ...filters },
        });
        all.push(...(resp.data.transactions || []));
        totalPagesRemote = resp.data.total_pages || 1;
        page += 1;
      } while (page <= totalPagesRemote);
    } catch (error) {
      console.error('Error exporting transactions:', error);
      complete = false;
    }

    if (all.length === 0) {
      toast.error(t("admin.transactions.noDataToExport"));
      return;
    }
    if (!complete) {
      toast.error(t("admin.subscription.exportTruncated"));
    }
    toast.success(t("admin.subscription.exportingRows", { count: all.length }));

    const headers = ['Sr No', 'Name', 'Email', 'Amount', 'Paid At', 'Source'];
    const rows = all.map((tx, index) => [
      (index + 1).toString(),
      tx.user?.username || '',
      tx.user?.email || '',
      formatMoney(tx.amount, tx.currency),
      formatDate(tx.paid_at),
      tx.source === 'subscription' ? 'Subscription' : 'One-time Payment',
    ]);

    // Formula-guarded HTML escape for XLS cells (see admin/subscription for rationale).
    const escape = (v: string) => {
      const guarded = /^[=+\-@\t\r]/.test(v) ? `'${v}` : v;
      return guarded.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
    };
    const title = 'Transaction Log';
    const colCount = headers.length;
    const xlsContent = `<html xmlns:x="urn:schemas-microsoft-com:office:excel"><head><meta charset="UTF-8"/></head><body>
<table border="1">
  <tr><th colspan="${colCount}" style="text-align:center;font-size:14px;background:#f3f4f6;padding:8px">${escape(title)}</th></tr>
  <tr>${headers.map((h) => `<th style="background:#f9fafb;text-align:left;padding:6px">${escape(h)}</th>`).join('')}</tr>
  ${rows.map((row) => `<tr>${row.map((cell) => `<td style="padding:4px 6px">${escape(cell)}</td>`).join('')}</tr>`).join('\n  ')}
</table>
</body></html>`;

    const blob = new Blob([xlsContent], { type: 'application/vnd.ms-excel;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', `transactions_${new Date().toISOString().split('T')[0]}.xls`);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  const renderPagination = () => {
    const pages: (number | string)[] = [];
    if (totalPages <= 7) {
      for (let i = 1; i <= totalPages; i++) pages.push(i);
    } else if (currentPage <= 3) {
      pages.push(1, 2, 3, '...', totalPages - 1, totalPages);
    } else if (currentPage >= totalPages - 2) {
      pages.push(1, 2, '...', totalPages - 2, totalPages - 1, totalPages);
    } else {
      pages.push(1, '...', currentPage - 1, currentPage, currentPage + 1, '...', totalPages);
    }
    return pages.map((page, i) => typeof page === 'number' ? (
      <button
        key={i}
        onClick={() => setCurrentPage(page)}
        className={`w-8 h-8 rounded-lg text-sm font-medium cursor-pointer ${
          currentPage === page ? 'bg-gray-100 text-gray-900' : 'text-gray-600 hover:bg-gray-50'
        }`}
      >
        {page}
      </button>
    ) : (
      <span key={i} className="px-2 text-gray-400">{page}</span>
    ));
  };

  if (loading) {
    return (
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
        <div className="flex items-center justify-center h-64">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#3B9EC9]"></div>
        </div>
      </main>
    );
  }

  return (
    <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
      {/* Page Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-6">
        <div className="flex items-center gap-3">
          <button
            onClick={() => router.push('/admin/subscription')}
            className="w-9 h-9 rounded-lg bg-white border border-gray-200 flex items-center justify-center text-gray-500 hover:bg-gray-50 transition cursor-pointer"
            title={t("admin.common.back")}
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <h1 className="text-2xl font-semibold text-gray-900">{t("admin.transactions.title")}</h1>
        </div>
      </div>

      {/* Table card */}
      <div className="bg-white rounded-xl border border-gray-200 shadow-sm">
        {/* Filters row — inputs on the left, Export pinned to the right */}
        <div className="p-5 border-b border-gray-200 flex flex-wrap items-center gap-2">
          <div className="relative">
            <svg className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
            </svg>
            <input
              type="text"
              placeholder={t("admin.common.search")}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="pl-9 pr-4 py-2 w-48 border border-gray-200 rounded-full text-sm focus:outline-none focus:ring-2 focus:ring-[#3B9EC9]"
            />
          </div>
          <input
            type="date"
            value={dateFrom}
            onChange={(e) => setDateFrom(e.target.value)}
            className="px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
            title={t("admin.transactions.dateFrom")}
          />
          <input
            type="date"
            value={dateTo}
            onChange={(e) => setDateTo(e.target.value)}
            className="px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
            title={t("admin.transactions.dateTo")}
          />
          <select
            value={sortBy}
            onChange={(e) => setSortBy(e.target.value)}
            className="px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] min-w-[120px] cursor-pointer"
          >
            <option value="">{t("admin.common.sortBy")}</option>
            <option value="paid_at">{t("admin.transactions.paidAt")}</option>
            <option value="amount">{t("admin.transactions.amount")}</option>
          </select>
          <select
            value={sourceFilter}
            onChange={(e) => setSourceFilter(e.target.value)}
            className="px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] min-w-[120px] cursor-pointer"
          >
            <option value="">{t("admin.transactions.allSources")}</option>
            <option value="payment">{t("admin.transactions.sourcePayment")}</option>
            <option value="subscription">{t("admin.transactions.sourceSubscription")}</option>
          </select>
          <button
            onClick={exportToXLS}
            disabled={transactions.length === 0}
            className="ml-auto flex items-center gap-2 px-4 py-2 bg-[#3B9EC9] text-white rounded-lg text-sm hover:bg-[#2B8EB9] transition cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
            </svg>
            {t("admin.subscription.export")}
          </button>
        </div>

        {/* Table */}
        <div className="mx-5 mb-5 mt-5 border border-gray-300 rounded-lg overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full border-collapse min-w-[700px]">
              <thead>
                <tr className="bg-gray-50">
                  <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300">#</th>
                  <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300">{t("admin.transactions.user")}</th>
                  <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300">{t("admin.transactions.amount")}</th>
                  <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-r border-gray-300">{t("admin.transactions.paidAt")}</th>
                  <th className="text-left px-5 py-3 text-sm font-medium text-gray-600 border-b border-gray-300">{t("admin.transactions.source")}</th>
                </tr>
              </thead>
              <tbody>
                {transactions.length === 0 ? (
                  <tr>
                    <td colSpan={5} className="px-5 py-12 text-center text-gray-500">
                      {t("admin.transactions.noTransactionsFound")}
                    </td>
                  </tr>
                ) : (
                  transactions.map((tx, index) => (
                    <tr key={tx.uuid} className="hover:bg-gray-50/50 transition">
                      <td className={`px-5 py-4 text-sm text-gray-600 border-r border-gray-300 ${index !== transactions.length - 1 ? 'border-b border-gray-300' : ''}`}>
                        {(currentPage - 1) * itemsPerPage + index + 1}
                      </td>
                      <td className={`px-5 py-4 border-r border-gray-300 ${index !== transactions.length - 1 ? 'border-b border-gray-300' : ''}`}>
                        <div>
                          <p className="text-sm font-medium text-gray-900">{tx.user?.username || 'Unknown'}</p>
                          <p className="text-xs text-gray-500">{tx.user?.email || '-'}</p>
                        </div>
                      </td>
                      <td className={`px-5 py-4 text-sm font-medium text-gray-900 border-r border-gray-300 ${index !== transactions.length - 1 ? 'border-b border-gray-300' : ''}`}>
                        {formatMoney(tx.amount, tx.currency)}
                      </td>
                      <td className={`px-5 py-4 text-sm text-gray-600 border-r border-gray-300 ${index !== transactions.length - 1 ? 'border-b border-gray-300' : ''}`}>
                        {formatDate(tx.paid_at)}
                      </td>
                      <td className={`px-5 py-4 ${index !== transactions.length - 1 ? 'border-b border-gray-300' : ''}`}>
                        <span className={`inline-flex items-center gap-1.5 px-3 py-1 text-xs font-medium rounded-full ${
                          tx.source === 'subscription' ? 'bg-blue-50 text-blue-600' : 'bg-green-50 text-green-600'
                        }`}>
                          <span className={`w-1.5 h-1.5 rounded-full ${
                            tx.source === 'subscription' ? 'bg-blue-500' : 'bg-green-500'
                          }`}></span>
                          {tx.source === 'subscription' ? t("admin.transactions.sourceSubscription") : t("admin.transactions.sourcePayment")}
                        </span>
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>

        {/* Pagination */}
        {totalCount > 0 && (
          <div className="px-5 py-4 border-t border-gray-200">
            <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
              <div className="flex items-center gap-4">
                <span className="text-sm text-gray-500">
                  {t("admin.common.showing")} {totalCount === 0 ? 0 : (currentPage - 1) * itemsPerPage + 1}-{Math.min(currentPage * itemsPerPage, totalCount)} {t("admin.common.of")} {totalCount}
                </span>
                <select
                  value={itemsPerPage}
                  onChange={(e) => {
                    setItemsPerPage(Number(e.target.value));
                    setCurrentPage(1);
                  }}
                  className="px-2 py-1 border border-gray-200 rounded-lg text-sm text-gray-600 focus:outline-none focus:ring-2 focus:ring-[#3B9EC9] cursor-pointer"
                >
                  <option value={10}>10</option>
                  <option value={25}>25</option>
                  <option value={50}>50</option>
                  <option value={100}>100</option>
                  <option value={250}>250</option>
                </select>
              </div>
              {totalPages > 1 && (
                <div className="flex items-center gap-2 flex-wrap">
                  <button
                    onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
                    disabled={currentPage === 1}
                    className="flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
                  >
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                    </svg>
                    {t("admin.common.previous")}
                  </button>
                  <div className="flex items-center gap-1">{renderPagination()}</div>
                  <button
                    onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}
                    disabled={currentPage === totalPages}
                    className="flex items-center gap-2 px-4 py-2 border border-gray-200 rounded-lg text-sm text-gray-600 hover:bg-gray-50 transition disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
                  >
                    {t("admin.common.next")}
                    <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                    </svg>
                  </button>
                </div>
              )}
            </div>
          </div>
        )}
      </div>
    </main>
  );
}
