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

const PAGE_SIZE = 20;

function buildDeliveryNoteExportFilters(f: { search: string; status: string }) {
  const filters: any[] = [];
  if (f.search) filters.push(['Delivery Note', 'name', 'like', `%${f.search}%`]);
  if (f.status === 'Draft') filters.push(['Delivery Note', 'docstatus', '=', 0]);
  if (f.status === 'Submitted') filters.push(['Delivery Note', 'docstatus', '=', 1]);
  if (f.status === 'Cancelled') filters.push(['Delivery Note', 'docstatus', '=', 2]);
  return filters;
}

function getStatusStyle(dn: DeliveryNote) {
  if (dn.docstatus === 2) return 'bg-red-100 text-red-700';
  if (dn.docstatus === 1) return 'bg-green-100 text-green-700';
  return 'bg-yellow-100 text-yellow-800';
}
function getStatusLabel(dn: DeliveryNote) {
  if (dn.docstatus === 2) return 'Cancelled';
  if (dn.docstatus === 1) return dn.status || 'Submitted';
  return 'Draft';
}

const DeliveryNoteList: React.FC = () => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const [notes, setNotes] = useState<DeliveryNote[]>([]);
  const [loading, setLoading] = useState(true);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(0);
  const [filtersOpen, setFiltersOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [statusFilter, setStatusFilter] = useState('');
  const [applied, setApplied] = useState({ search: '', status: '' });
  const [showExportModal, setShowExportModal] = useState(false);
  const didInitUrlSync = useRef(false);
  const searchDebounceRef = useRef<number | null>(null);

  const load = useCallback(async (off: number, f: typeof applied) => {
    setLoading(true);
    try {
      const filters: any[] = [];
      if (f.search) filters.push(['Delivery Note', 'name', 'like', `%${f.search}%`]);
      if (f.status === 'Draft')     filters.push(['Delivery Note', 'docstatus', '=', 0]);
      if (f.status === 'Submitted') filters.push(['Delivery Note', 'docstatus', '=', 1]);
      if (f.status === 'Cancelled') filters.push(['Delivery Note', 'docstatus', '=', 2]);
      const [rows, cnt] = await Promise.all([
        deliveryNoteService.getDeliveryNotes({ filters, limit_start: off, limit_page_length: PAGE_SIZE }),
        deliveryNoteService.getDeliveryNoteCount(filters),
      ]);
      setNotes(rows); setTotal(cnt);
    } catch (e: any) { toast.error(e.message || 'Failed to load'); }
    finally { setLoading(false); }
  }, []);

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

  const selectionResetKey = useMemo(
    () => `${page}|${applied.search}|${applied.status}`,
    [page, applied.search, applied.status],
  );
  const {
    selectedRows,
    toggleRow,
    toggleAllOnPage,
    allOnPageSelected,
    someOnPageSelected,
  } = useListPageSelection(notes, selectionResetKey);

  // Auto-apply filters
  useEffect(() => {
    if (!didInitUrlSync.current) {
      didInitUrlSync.current = true;
      return;
    }
    setApplied((prev) => ({ ...prev, status: statusFilter }));
    setPage(0);
  }, [statusFilter]);

  useEffect(() => {
    if (!didInitUrlSync.current) return;
    if (searchDebounceRef.current) window.clearTimeout(searchDebounceRef.current);
    searchDebounceRef.current = window.setTimeout(() => {
      setApplied((prev) => ({ ...prev, search: searchQuery }));
      setPage(0);
    }, 450);
    return () => {
      if (searchDebounceRef.current) window.clearTimeout(searchDebounceRef.current);
    };
  }, [searchQuery]);

  const clear = () => { setSearchQuery(''); setStatusFilter(''); setApplied({ search: '', status: '' }); setPage(0); };
  const hasActive = !!(applied.search || applied.status);
  const goPage = (p: number) => { setPage(p); load(p * PAGE_SIZE, applied); };
  const handleView = (name: string) => navigate(`/delivery-notes/${encodeURIComponent(name)}`);
  const handleEdit = (name: string) => navigate(`/delivery-notes/${encodeURIComponent(name)}?edit=1`);
  const handleDuplicate = (name: string) => navigate(`/delivery-notes/new?duplicate=${encodeURIComponent(name)}`);

  const fetchAllForExport = useCallback(
    () =>
      fetchAllRowsForExport({
        doctype: 'Delivery Note',
        filters: buildDeliveryNoteExportFilters(applied),
        orderBy: 'modified desc',
      }),
    [applied],
  );

  return (
    <div className="p-6">
      <ToastContainer position="top-right" autoClose={3000} />
      <div className="flex items-center justify-between mb-6 gap-4 flex-wrap">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-teal-600 flex items-center justify-center"><FaTruck className="text-white text-base" /></div>
          <div><h1 className="text-xl font-bold text-gray-900 dark:text-white">Delivery Notes</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 * PAGE_SIZE, applied)} className="p-2 text-gray-500 hover:text-indigo-600 border border-gray-200 rounded-lg"><FaSync size={13} /></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('/delivery-notes/new')} className="flex items-center gap-2 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 text-sm font-medium"><FaPlus size={11} /> New Note</button>
        </div>
      </div>

      <DynamicExportModal
        isOpen={showExportModal}
        onClose={() => setShowExportModal(false)}
        doctype="Delivery Note"
        selectedCount={selectedRows.size}
        pageCount={notes.length}
        totalCount={total}
        pageData={notes}
        selectedRows={selectedRows}
        rowKey="name"
        onFetchAll={fetchAllForExport}
        fileNamePrefix="delivery_notes"
      />

      <div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl mb-5 overflow-hidden">
        <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">
          <div className="flex items-center gap-2 text-sm font-semibold"><FaSearch size={12} /> Filters {hasActive && <span className="bg-white/30 text-white text-xs px-2 py-0.5 rounded-full">Active</span>}</div>
          {filtersOpen ? <FaChevronUp size={11} /> : <FaChevronDown size={11} />}
        </button>
        {hasActive && (
          <div className="px-4 py-2 bg-blue-50 dark:bg-blue-900/20 flex flex-wrap gap-2 items-center border-b border-blue-100 dark:border-blue-900/30">
            {applied.search && <span className="flex items-center gap-1 text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full">ID: {applied.search}<button onClick={() => { setSearchQuery(''); setApplied(a => ({ ...a, search: '' })); }}><FaTimes size={9} /></button></span>}
            {applied.status && <span className="flex items-center gap-1 text-xs bg-blue-100 text-blue-700 px-2 py-1 rounded-full">Status: {applied.status}<button onClick={() => { setStatusFilter(''); setApplied(a => ({ ...a, status: '' })); }}><FaTimes size={9} /></button></span>}
            <button onClick={clear} className="text-xs text-blue-600 hover:underline ml-auto">Clear All</button>
          </div>
        )}
        {filtersOpen && (
          <div className="px-4 py-3 grid grid-cols-1 sm:grid-cols-3 gap-3">
            <div><label className="block text-[11px] font-semibold text-gray-500 uppercase tracking-wide mb-1">Note ID</label>
              <input value={searchQuery} onChange={e => setSearchQuery(e.target.value)} onKeyDown={e => e.key === 'Enter' && e.preventDefault()} placeholder="Search…" className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-indigo-400" /></div>
            <div><label className="block text-[11px] font-semibold text-gray-500 uppercase tracking-wide mb-1">Status</label>
              <select value={statusFilter} onChange={e => setStatusFilter(e.target.value)} className="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-indigo-400">
                <option value="">All</option><option value="Draft">Draft</option><option value="Submitted">Submitted</option><option value="Cancelled">Cancelled</option>
              </select></div>
          </div>
        )}
      </div>

      <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">Note ID</th>
                <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Customer</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">Status</th>
                <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-3 px-4">Grand Total</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={7} className="text-center py-10 text-gray-400">Loading…</td></tr>
                : notes.length === 0 ? <tr><td colSpan={7} className="text-center py-10 text-gray-400">No delivery notes found</td></tr>
                : notes.map(dn => (
                  <tr key={dn.name} onClick={() => handleView(dn.name)} className={`cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors ${selectedRows.has(dn.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(dn.name)}
                        className="text-gray-500 dark:text-gray-400 hover:text-teal-600 dark:hover:text-teal-400 transition-colors"
                        aria-label={`Select ${dn.name}`}
                      >
                        {selectedRows.has(dn.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">{dn.name}</td>
                    <td className="py-3 px-4 text-gray-700 dark:text-gray-300">{dn.customer_name || dn.customer || '-'}</td>
                    <td className="py-3 px-4 text-gray-500">{dn.posting_date || '-'}</td>
                    <td className="py-3 px-4"><span className={`px-2 py-0.5 rounded text-xs font-semibold ${getStatusStyle(dn)}`}>{getStatusLabel(dn)}</span></td>
                    <td className="py-3 px-4 text-right font-semibold text-gray-900 dark:text-white">{dn.currency || 'SAR'} {(dn.grand_total ?? 0).toFixed(2)}</td>
                    <td className="py-2 px-4" onClick={e => e.stopPropagation()}>
                      <div className="flex items-center gap-1">
                        <button onClick={() => handleView(dn.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(dn.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(dn.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>
  );
};

export default DeliveryNoteList;
