import React, { useEffect, useState, useCallback, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { FaMoneyBillWave, FaPlus, FaSync, FaChevronDown, FaChevronUp, FaFilter, FaTimes, FaFileExport, FaEye, FaEdit, FaCopy, FaCheckSquare, FaSquare } from 'react-icons/fa';
import { toast, ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { paymentEntryService } from '../services/paymentEntryService';
import DynamicExportModal from '../components/DynamicExportModal';
import { fetchAllRowsForExport } from '../utils/frappeListExport';
import { useListPageSelection } from '../hooks/useListPageSelection';

const PAGE_SIZE = 20;

const statusStyle = (status: string, docstatus: number) => {
  if (docstatus === 1) {
    if (status === 'Paid') return 'bg-green-100 text-green-700';
    if (status === 'Submitted') return 'bg-blue-100 text-blue-700';
    return 'bg-blue-100 text-blue-700';
  }
  if (docstatus === 2) return 'bg-red-100 text-red-700';
  return 'bg-yellow-100 text-yellow-700';
};

const statusLabel = (status: string, docstatus: number) => {
  if (docstatus === 2) return 'Cancelled';
  if (docstatus === 1) return status || 'Submitted';
  return 'Draft';
};

export default function PaymentEntryList() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const [entries, setEntries] = useState<any[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(0);
  const [loading, setLoading] = useState(true);
  const [filtersOpen, setFiltersOpen] = useState(true);
  const [searchQuery, setSearchQuery] = useState('');
  const [partyFilter, setPartyFilter] = useState('');
  const [typeFilter, setTypeFilter] = useState('');
  const [showExportModal, setShowExportModal] = useState(false);

  const buildFilters = useCallback(() => {
    const f: any[] = [];
    if (searchQuery) f.push(['name', 'like', `%${searchQuery}%`]);
    if (partyFilter) f.push(['party', 'like', `%${partyFilter}%`]);
    if (typeFilter) f.push(['payment_type', '=', typeFilter]);
    return f;
  }, [searchQuery, partyFilter, typeFilter]);

  const load = useCallback(async (pg = 0) => {
    setLoading(true);
    try {
      const filters = buildFilters();
      const [data, cnt] = await Promise.all([
        paymentEntryService.getPaymentEntries({ filters, limit_start: pg * PAGE_SIZE, limit_page_length: PAGE_SIZE }),
        paymentEntryService.getPaymentEntryCount(filters),
      ]);
      setEntries(data); setTotal(cnt); setPage(pg);
    } catch (e: any) { toast.error(e.message || 'Error loading'); }
    finally { setLoading(false); }
  }, [buildFilters]);

  useEffect(() => { load(0); }, [load]);

  const selectionResetKey = useMemo(
    () => `${page}|${searchQuery}|${partyFilter}|${typeFilter}`,
    [page, searchQuery, partyFilter, typeFilter],
  );
  const {
    selectedRows,
    toggleRow,
    toggleAllOnPage,
    allOnPageSelected,
    someOnPageSelected,
  } = useListPageSelection(entries, selectionResetKey);

  const fetchAllForExport = useCallback(
    () => fetchAllRowsForExport({ doctype: 'Payment Entry', filters: buildFilters(), orderBy: 'modified desc' }),
    [buildFilters],
  );

  const goPage = (pg: number) => load(pg);

  const activeFilterCount = [searchQuery, partyFilter, typeFilter].filter(Boolean).length;

  const clearFilters = () => { setSearchQuery(''); setPartyFilter(''); setTypeFilter(''); };
  const handleView = (name: string) => navigate(`/payment-entries/${encodeURIComponent(name)}`);
  const handleEdit = (name: string) => navigate(`/payment-entries/${encodeURIComponent(name)}?edit=1`);
  const handleDuplicate = (name: string) => navigate(`/payment-entries/new?duplicate=${encodeURIComponent(name)}`);

  return (
    <><ToastContainer position="top-right" autoClose={3000} />
    <div className="px-6 py-6 space-y-4">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-teal-600 flex items-center justify-center shadow">
            <FaMoneyBillWave className="text-white" size={18} />
          </div>
          <div>
            <h1 className="text-xl font-bold text-gray-900 dark:text-white">Payment Entries</h1>
            <p className="text-xs text-gray-500">{total} total</p>
          </div>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <button onClick={() => load(page)} className="p-2 text-gray-500 hover:text-teal-600 hover:bg-teal-50 rounded-lg transition-colors"><FaSync size={14} /></button>
          <button
            type="button"
            onClick={() => setShowExportModal(true)}
            className="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 shadow transition-all text-sm font-medium disabled:opacity-50"
            disabled={total === 0 && selectedRows.size === 0}
          >
            <FaFileExport /> {t('listPages.export')}
            {selectedRows.size > 0 && (
              <span className="bg-white/25 px-1.5 py-0.5 rounded text-xs font-bold">{selectedRows.size}</span>
            )}
          </button>
          <button onClick={() => navigate('/payment-entries/new')} className="flex items-center gap-2 px-4 py-2 bg-teal-600 hover:bg-teal-700 text-white text-sm font-semibold rounded-lg shadow transition-colors">
            <FaPlus size={12} /> New Entry
          </button>
        </div>
      </div>

      <DynamicExportModal
        isOpen={showExportModal}
        onClose={() => setShowExportModal(false)}
        doctype="Payment Entry"
        selectedCount={selectedRows.size}
        pageCount={entries.length}
        totalCount={total}
        pageData={entries}
        selectedRows={selectedRows}
        rowKey="name"
        onFetchAll={fetchAllForExport}
        fileNamePrefix="payment_entries"
      />

      {/* Filters */}
      <div className="rounded-xl border border-blue-200 dark:border-blue-800 overflow-hidden shadow-sm">
        <button onClick={() => setFiltersOpen(o => !o)} className="w-full flex items-center justify-between px-4 py-3 bg-gradient-to-r from-blue-500 to-blue-600 dark:from-blue-600 dark:to-blue-700 text-white text-sm font-semibold">
          <span className="flex items-center gap-2"><FaFilter size={12} /> Filters {activeFilterCount > 0 && <span className="bg-white/25 text-white text-[10px] px-1.5 py-0.5 rounded-full">{activeFilterCount}</span>}</span>
          {filtersOpen ? <FaChevronUp size={12} /> : <FaChevronDown size={12} />}
        </button>
        {filtersOpen && (
          <div className="p-4 bg-white dark:bg-gray-800 grid grid-cols-1 sm:grid-cols-3 gap-3">
            <div>
              <label className="block text-[10px] font-semibold text-gray-500 uppercase mb-1">Payment ID</label>
              <input value={searchQuery} onChange={e => setSearchQuery(e.target.value)} placeholder="Search by ID…" className="w-full border border-gray-200 dark:border-gray-600 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" />
            </div>
            <div>
              <label className="block text-[10px] font-semibold text-gray-500 uppercase mb-1">Party</label>
              <input value={partyFilter} onChange={e => setPartyFilter(e.target.value)} placeholder="Customer / Supplier…" className="w-full border border-gray-200 dark:border-gray-600 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" />
            </div>
            <div>
              <label className="block text-[10px] font-semibold text-gray-500 uppercase mb-1">Type</label>
              <select value={typeFilter} onChange={e => setTypeFilter(e.target.value)} className="w-full border border-gray-200 dark:border-gray-600 rounded-lg px-3 py-2 text-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100">
                <option value="">All Types</option>
                <option value="Receive">Receive</option>
                <option value="Pay">Pay</option>
                <option value="Internal Transfer">Internal Transfer</option>
              </select>
            </div>
            {activeFilterCount > 0 && (
              <div className="sm:col-span-3 flex flex-wrap gap-2 items-center">
                {searchQuery && <span className="flex items-center gap-1 bg-blue-100 text-blue-700 text-xs px-2 py-1 rounded-full">ID: {searchQuery}<button onClick={() => setSearchQuery('')}><FaTimes size={9} /></button></span>}
                {partyFilter && <span className="flex items-center gap-1 bg-blue-100 text-blue-700 text-xs px-2 py-1 rounded-full">Party: {partyFilter}<button onClick={() => setPartyFilter('')}><FaTimes size={9} /></button></span>}
                {typeFilter && <span className="flex items-center gap-1 bg-blue-100 text-blue-700 text-xs px-2 py-1 rounded-full">Type: {typeFilter}<button onClick={() => setTypeFilter('')}><FaTimes size={9} /></button></span>}
                <button onClick={clearFilters} className="text-xs text-blue-600 hover:text-blue-800 font-medium ml-1">Clear all</button>
              </div>
            )}
          </div>
        )}
      </div>

      {/* Table */}
      <div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden">
        <div className="overflow-x-auto">
          <table className="min-w-full text-sm">
            <thead>
              <tr className="border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40">
                <th className="w-10 px-4 py-3 text-left">
                  <button
                    type="button"
                    onClick={toggleAllOnPage}
                    className="text-gray-500 dark:text-gray-400 hover:text-teal-600 dark:hover:text-teal-400 transition-colors"
                    title={allOnPageSelected ? 'Deselect all' : 'Select all'}
                    aria-label="Select all on page"
                  >
                    {allOnPageSelected
                      ? <FaCheckSquare className="text-teal-600 dark:text-teal-400" size={18} />
                      : someOnPageSelected
                        ? (
                            <div className="relative inline-block">
                              <FaSquare size={18} />
                              <div className="absolute inset-0 flex items-center justify-center">
                                <div className="w-2 h-0.5 bg-current" />
                              </div>
                            </div>
                          )
                        : <FaSquare size={18} />}
                  </button>
                </th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Payment ID</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Type</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Date</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Party</th>
                <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Amount</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Status</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4 w-28"> </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-gray-100 dark:divide-gray-700">
              {loading
                ? <tr><td colSpan={8} className="text-center py-10 text-gray-400">Loading…</td></tr>
                : entries.length === 0
                  ? <tr><td colSpan={8} className="text-center py-10 text-gray-400">No payment entries found</td></tr>
                  : entries.map(pe => (
                    <tr key={pe.name} onClick={() => handleView(pe.name)} className={`cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors ${selectedRows.has(pe.name) ? 'bg-teal-50 dark:bg-teal-900/20' : ''}`}>
                      <td className="w-10 px-4 py-3" onClick={e => e.stopPropagation()}>
                        <button
                          type="button"
                          onClick={() => toggleRow(pe.name)}
                          className="text-gray-500 dark:text-gray-400 hover:text-teal-600 dark:hover:text-teal-400 transition-colors"
                          aria-label={`Select ${pe.name}`}
                        >
                          {selectedRows.has(pe.name)
                            ? <FaCheckSquare className="text-teal-600 dark:text-teal-400" size={18} />
                            : <FaSquare size={18} />}
                        </button>
                      </td>
                      <td className="py-3 px-4 font-medium text-gray-900 dark:text-white">{pe.name}</td>
                      <td className="py-3 px-4 text-gray-700 dark:text-gray-300">{pe.payment_type || '-'}</td>
                      <td className="py-3 px-4 text-gray-500">{pe.posting_date || '-'}</td>
                      <td className="py-3 px-4 text-gray-700 dark:text-gray-300">{pe.party_name || pe.party || '-'}</td>
                      <td className="py-3 px-4 text-right font-semibold text-gray-900 dark:text-white">{(pe.paid_amount || 0).toFixed(2)}</td>
                      <td className="py-3 px-4">
                        <span className={`px-2 py-0.5 rounded text-xs font-semibold ${statusStyle(pe.status, pe.docstatus)}`}>
                          {statusLabel(pe.status, pe.docstatus)}
                        </span>
                      </td>
                      <td className="py-2 px-4" onClick={e => e.stopPropagation()}>
                        <div className="flex items-center gap-1">
                          <button onClick={() => handleView(pe.name)} className="text-blue-600 dark:text-blue-400 hover:text-blue-900 dark:hover:text-blue-300 p-2 hover:bg-blue-50 dark:hover:bg-blue-900/30 rounded transition-colors" title="View"><FaEye /></button>
                          <button onClick={() => handleEdit(pe.name)} className="text-green-600 dark:text-green-400 hover:text-green-900 dark:hover:text-green-300 p-2 hover:bg-green-50 dark:hover:bg-green-900/30 rounded transition-colors" title="Edit"><FaEdit /></button>
                          <button onClick={() => handleDuplicate(pe.name)} className="text-purple-600 dark:text-purple-400 hover:text-purple-900 dark:hover:text-purple-300 p-2 hover:bg-purple-50 dark:hover:bg-purple-900/30 rounded transition-colors" title="Duplicate"><FaCopy /></button>
                        </div>
                      </td>
                    </tr>
                  ))}
            </tbody>
          </table>
        </div>
        {total > PAGE_SIZE && (
          <div className="flex items-center justify-between px-4 py-3 border-t border-gray-100 dark:border-gray-700">
            <span className="text-xs text-gray-500">{page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} of {total}</span>
            <div className="flex gap-2">
              <button disabled={page === 0} onClick={() => goPage(page - 1)} className="px-3 py-1 text-xs border border-gray-300 rounded disabled:opacity-40">Prev</button>
              <button disabled={(page + 1) * PAGE_SIZE >= total} onClick={() => goPage(page + 1)} className="px-3 py-1 text-xs border border-gray-300 rounded disabled:opacity-40">Next</button>
            </div>
          </div>
        )}
      </div>
    </div>
    </>
  );
}
