import React, { useState, useMemo, useEffect, useRef } from 'react';
import { ExcelRow } from '../types';
import { useColumns } from '../contexts/ColumnsContext';
import { Search, ChevronDown, ChevronUp, X, Save, Check, Loader2 } from 'lucide-react';
import { cn } from '../lib/utils';
import { ColumnFilterPopover } from './ColumnFilterPopover';
import { usePersistentState } from '../contexts/FilterContext';
import { saveRowToSupabase } from '../lib/supabase';
import { updateCpnpNoInBC } from '../services/businessCentral';

const COSMETIC_LINES = ['INKEE', 'BATH FUN', 'TOP FASHION', 'SENSES', 'BODYNESS'];

interface CosmeticItemsViewProps {
  data: ExcelRow[];
  headers: string[];
  onSaveRow: (rowIndex: number, updatedRow: ExcelRow) => void;
  onCaptureState: (message: string) => void;
  rowStatuses: Record<string, string>;
}

export function CosmeticItemsView({ data, headers, onSaveRow, onCaptureState, rowStatuses }: CosmeticItemsViewProps) {
  const COLUMNS = useColumns();
  const [search, setSearch] = usePersistentState('cosmeticItems-search', '');
  const [sortCol, setSortCol] = usePersistentState<number | null>('cosmeticItems-sortCol', null);
  const [sortDesc, setSortDesc] = usePersistentState('cosmeticItems-sortDesc', false);
  const [page, setPage] = useState(1);
  const [columnFilters, setColumnFilters] = usePersistentState<Record<number, string[]>>('cosmeticItems-columnFilters', {});
  const [openFilter, setOpenFilter] = useState<number | null>(null);
  const [editingCpnp, setEditingCpnp] = useState<{ rowIndex: number; value: string } | null>(null);
  const [savingCpnp, setSavingCpnp] = useState<number | null>(null);
  const cpnpInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (editingCpnp !== null) cpnpInputRef.current?.focus();
  }, [editingCpnp]);

  const pageSize = 100;

  const columns = [
    { col: COLUMNS.ARTICLE_NO, label: 'SKU', width: 110 },
    { col: COLUMNS.ARTICLE_NAME, label: 'Name', width: 240 },
    { col: COLUMNS.LINE, label: 'Line', width: 120 },
    { col: COLUMNS.ITEM_AVAILABLE, label: 'Item Available', width: 120 },
    { col: COLUMNS.CPNP_NO, label: 'CPNP No.', width: 160 },
  ];

  const columnUniqueValues = useMemo(() => {
    const result: Record<number, Set<string>> = {};
    columns.forEach(c => { result[c.col] = new Set(); });

    data.forEach(row => {
      const lineVal = String(row[COLUMNS.LINE] ?? '').trim().toUpperCase();
      if (!COSMETIC_LINES.some(l => lineVal === l)) return;

      columns.forEach(({ col }) => {
        result[col].add(String(row[col] ?? '').replace(/\s+/g, ' ').trim());
      });
    });

    return result;
  }, [data, COLUMNS]);

  const getUniqueValues = (col: number): string[] =>
    Array.from(columnUniqueValues[col] as Set<string> ?? []).sort((a, b) => {
      const na = parseFloat(a), nb = parseFloat(b);
      if (!isNaN(na) && !isNaN(nb)) return na - nb;
      return a.localeCompare(b);
    });

  const filteredData = useMemo(() => {
    let result = data.map((row, index) => ({ row, index }));

    // Filter: only cosmetic lines
    result = result.filter(({ row }) => {
      const lineVal = String(row[COLUMNS.LINE] ?? '').trim().toUpperCase();
      return COSMETIC_LINES.some(l => lineVal === l);
    });

    // Global search
    if (search) {
      const terms = search.toLowerCase().split(/\s+/).filter(Boolean);
      result = result.filter(({ row }) => {
        const articleNo = String(row[COLUMNS.ARTICLE_NO] || '').toLowerCase();
        const articleName = String(row[COLUMNS.ARTICLE_NAME] || '').toLowerCase();
        return terms.every(t => articleNo.includes(t) || articleName.includes(t));
      });
    }

    // Column filters
    (Object.entries(columnFilters) as [string, string[]][]).forEach(([colIdx, filterValues]) => {
      if (!filterValues || filterValues.length === 0) return;
      const colNum = parseInt(colIdx);
      const knownCount = columnUniqueValues[colNum]?.size ?? 0;
      // All known values selected → no filtering needed
      if (filterValues.length >= knownCount) return;
      const normalize = (v: any) => String(v ?? '').replace(/\s+/g, ' ').trim();
      const filterSet = new Set(filterValues.map(normalize));
      result = result.filter(({ row }) => filterSet.has(normalize(row[colNum])));
    });

    // Sort
    if (sortCol !== null) {
      result.sort((a, b) => {
        const valA = a.row[sortCol];
        const valB = b.row[sortCol];
        if (typeof valA === 'number' && typeof valB === 'number') {
          return sortDesc ? valB - valA : valA - valB;
        }
        const sA = String(valA ?? '');
        const sB = String(valB ?? '');
        return sortDesc ? sB.localeCompare(sA) : sA.localeCompare(sB);
      });
    }

    return result;
  }, [data, search, sortCol, sortDesc, columnFilters, COLUMNS, columnUniqueValues]);

  const paginatedData = useMemo(() => {
    const start = (page - 1) * pageSize;
    return filteredData.slice(start, start + pageSize);
  }, [filteredData, page]);

  const totalPages = Math.ceil(filteredData.length / pageSize);

  const handleSort = (col: number) => {
    if (sortCol === col) setSortDesc(d => !d);
    else { setSortCol(col); setSortDesc(false); }
  };

  const startEditCpnp = (rowIndex: number, currentValue: any) => {
    setEditingCpnp({ rowIndex, value: String(currentValue ?? '') });
  };

  const saveCpnp = async (rowIndex: number) => {
    if (!editingCpnp || editingCpnp.rowIndex !== rowIndex) return;
    const row = data[rowIndex];
    const articleNo = String(row[COLUMNS.ARTICLE_NO]);
    const cpnpValue = editingCpnp.value.trim();
    const newRow = [...row];
    newRow[COLUMNS.CPNP_NO] = cpnpValue;
    setSavingCpnp(rowIndex);
    setEditingCpnp(null);
    onCaptureState(`Updated CPNP No. for ${articleNo}`);
    onSaveRow(rowIndex, newRow);

    const [supabaseResult, bcResult] = await Promise.all([
      saveRowToSupabase(articleNo, newRow, 'edited'),
      updateCpnpNoInBC(articleNo, cpnpValue),
    ]);

    setSavingCpnp(null);

    const errors: string[] = [];
    if (!supabaseResult.success) errors.push(`Supabase: ${supabaseResult.error}`);
    if (!bcResult.success) errors.push(`Business Central: ${bcResult.error}`);
    if (errors.length > 0) {
      alert(`Error saving CPNP No. for ${articleNo}:\n${errors.join('\n')}`);
    }
  };

  const cancelEditCpnp = () => setEditingCpnp(null);

  const lineBadgeColor = (line: string) => {
    const l = String(line).toUpperCase();
    if (l === 'INKEE') return 'bg-pink-500/10 text-pink-400 border-pink-500/20';
    if (l === 'BATH FUN') return 'bg-cyan-500/10 text-cyan-400 border-cyan-500/20';
    if (l === 'TOP FASHION') return 'bg-purple-500/10 text-purple-400 border-purple-500/20';
    if (l === 'SENSES') return 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20';
    return 'bg-slate-700/50 text-slate-400 border-slate-600/50';
  };

  return (
    <div className="flex flex-col h-full">
      <div className="flex flex-wrap gap-4 mb-6 bg-slate-800/50 p-4 rounded-xl border border-slate-700/50">
        <div className="flex-1 min-w-[200px] relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-500" />
          <input
            type="text"
            placeholder="Search SKU or Name..."
            value={search}
            onChange={e => { setSearch(e.target.value); setPage(1); }}
            className="w-full pl-9 pr-10 py-2 bg-slate-900/50 border border-slate-700 rounded-md text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500"
          />
          {search && (
            <button
              onClick={() => { setSearch(''); setPage(1); }}
              className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-white"
            >
              <X className="w-4 h-4" />
            </button>
          )}
        </div>
        <div className="flex items-center gap-3 text-xs text-slate-500">
          <span className="text-slate-400 font-medium">{filteredData.length} items</span>
          <span className="text-slate-600">·</span>
          <span>Lines: {COSMETIC_LINES.join(', ')}</span>
        </div>
      </div>

      <div className="flex-1 bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden flex flex-col">
        <div className="overflow-x-auto flex-1">
          <table className="w-full text-left text-xs">
            <thead className="bg-slate-900/80 text-slate-400 sticky top-0 z-10">
              <tr>
                {columns.map(({ col, label, width }) => {
                  const selectedFilters = columnFilters[col] || [];
                  const filterCount = selectedFilters.length;
                  const isCpnp = col === COLUMNS.CPNP_NO;
                  return (
                    <th
                      key={col}
                      style={{ width, minWidth: width }}
                      className="px-2 py-2 font-medium border-r border-slate-700/30 relative"
                    >
                      <div
                        className="flex items-center gap-1 cursor-pointer select-none hover:text-white"
                        role="button"
                        tabIndex={0}
                        onClick={() => handleSort(col)}
                        onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') handleSort(col); }}
                      >
                        {label}
                        {sortCol === col && (
                          sortDesc ? <ChevronDown className="w-3 h-3" /> : <ChevronUp className="w-3 h-3" />
                        )}
                        {isCpnp && (
                          <span className="ml-1 text-[9px] text-indigo-400 font-normal">(editable)</span>
                        )}
                      </div>
                      <div className="mt-1 relative">
                          <button
                            id={`cosmetic-filter-trigger-${col}`}
                            onClick={(e) => { e.stopPropagation(); setOpenFilter(openFilter === col ? null : col); }}
                            className={cn(
                              "w-full flex items-center justify-between px-1.5 py-0.5 bg-slate-800 border rounded text-[10px] transition-colors",
                              filterCount > 0 ? "border-indigo-500 text-white" : "border-slate-600 text-slate-400 hover:border-slate-500"
                            )}
                          >
                            <span className="truncate">{filterCount > 0 ? `${filterCount} selected` : 'Filter...'}</span>
                            <ChevronDown className={cn("w-3 h-3 transition-transform", openFilter === col && "rotate-180")} />
                          </button>
                          {openFilter === col && (
                            <ColumnFilterPopover
                              triggerId={`cosmetic-filter-trigger-${col}`}
                              uniqueValues={getUniqueValues(col)}
                              selectedValues={selectedFilters}
                              onToggle={(val) => setColumnFilters(prev => {
                                const current = prev[col] || [];
                                if (current.includes(val)) {
                                  return { ...prev, [col]: current.filter(v => v !== val) };
                                }
                                return { ...prev, [col]: [...current, val] };
                              })}
                              onSelectAll={(vals) => setColumnFilters(prev => ({ ...prev, [col]: vals }))}
                              onClear={() => { setColumnFilters(prev => { const n = { ...prev }; delete n[col]; return n; }); }}
                              onClose={() => setOpenFilter(null)}
                            />
                          )}
                        </div>
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-700/30">
              {paginatedData.map(({ row, index }) => {
                const articleNo = String(row[COLUMNS.ARTICLE_NO] ?? '');
                const status = rowStatuses[articleNo];
                const isEditing = editingCpnp?.rowIndex === index;

                return (
                  <tr
                    key={articleNo || index}
                    className={cn(
                      "hover:bg-slate-700/20 transition-colors",
                      status === 'pending' && "bg-amber-500/5"
                    )}
                  >
                    <td className="px-3 py-2 font-mono text-indigo-400 truncate" style={{ width: 110 }}>
                      {articleNo}
                    </td>
                    <td className="px-3 py-2 font-medium text-slate-200 truncate" style={{ width: 240 }} title={row[COLUMNS.ARTICLE_NAME]}>
                      {row[COLUMNS.ARTICLE_NAME]}
                    </td>
                    <td className="px-3 py-2" style={{ width: 120 }}>
                      <span className={cn(
                        "px-1.5 py-0.5 rounded-[4px] text-[10px] font-bold border",
                        lineBadgeColor(String(row[COLUMNS.LINE] ?? ''))
                      )}>
                        {row[COLUMNS.LINE]}
                      </span>
                    </td>
                    <td className="px-3 py-2 font-mono text-slate-300 text-right" style={{ width: 120 }}>
                      {row[COLUMNS.ITEM_AVAILABLE]}
                    </td>
                    <td className="px-3 py-2" style={{ width: 160 }}>
                      {savingCpnp === index ? (
                        <span className="flex items-center gap-1.5 text-[10px] text-slate-400">
                          <Loader2 className="w-3 h-3 animate-spin" />
                          Saving...
                        </span>
                      ) : isEditing ? (
                        <div className="flex items-center gap-1">
                          <input
                            ref={cpnpInputRef}
                            type="text"
                            value={editingCpnp.value}
                            onChange={e => setEditingCpnp(prev => prev ? { ...prev, value: e.target.value } : prev)}
                            onKeyDown={e => {
                              if (e.key === 'Enter') saveCpnp(index);
                              if (e.key === 'Escape') cancelEditCpnp();
                            }}
                            className="flex-1 min-w-0 bg-slate-900 border border-indigo-500 rounded px-2 py-1 text-xs text-white focus:outline-none focus:ring-1 focus:ring-indigo-500"
                            placeholder="Enter CPNP No."
                          />
                          <button
                            onClick={() => saveCpnp(index)}
                            className="p-1 text-emerald-400 hover:text-emerald-300 hover:bg-emerald-400/10 rounded transition-colors"
                            title="Save"
                          >
                            <Check className="w-4 h-4" />
                          </button>
                          <button
                            onClick={cancelEditCpnp}
                            className="p-1 text-slate-500 hover:text-slate-300 hover:bg-slate-700 rounded transition-colors"
                            title="Cancel"
                          >
                            <X className="w-4 h-4" />
                          </button>
                        </div>
                      ) : (() => {
                        const cpnpVal = String(row[COLUMNS.CPNP_NO] ?? '').trim();
                        return cpnpVal ? (
                          <button
                            onClick={() => startEditCpnp(index, row[COLUMNS.CPNP_NO])}
                            className="w-full text-left px-2 py-1 rounded border border-slate-600 text-emerald-400 hover:border-indigo-500 hover:text-indigo-400 transition-colors text-[10px] font-mono"
                            title="Click to edit CPNP No."
                          >
                            {cpnpVal}
                          </button>
                        ) : (
                          <button
                            onClick={() => startEditCpnp(index, row[COLUMNS.CPNP_NO])}
                            className="w-full text-left px-2 py-1 rounded border border-dashed border-slate-600 text-slate-500 hover:border-indigo-500 hover:text-indigo-400 transition-colors text-[10px]"
                            title="Click to enter CPNP No."
                          >
                            <span className="flex items-center gap-1.5">
                              <Save className="w-3 h-3 opacity-50" />
                              Click to fill...
                            </span>
                          </button>
                        );
                      })()}
                    </td>
                  </tr>
                );
              })}
              {paginatedData.length === 0 && (
                <tr>
                  <td colSpan={columns.length} className="px-4 py-8 text-center text-slate-500">
                    No cosmetic items pending CPNP registration.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>

        <div className="bg-slate-900 border-t border-slate-700 p-4 flex items-center justify-between text-xs text-slate-500">
          <div>Showing {paginatedData.length} of {filteredData.length} items</div>
          <div className="flex items-center gap-2">
            <button
              disabled={page === 1}
              onClick={() => setPage(p => p - 1)}
              className="px-2 py-1 rounded bg-slate-800 hover:bg-slate-700 disabled:opacity-50 transition-colors"
            >
              Previous
            </button>
            <span className="text-slate-300">Page {page} of {totalPages || 1}</span>
            <button
              disabled={page === totalPages || totalPages === 0}
              onClick={() => setPage(p => p + 1)}
              className="px-2 py-1 rounded bg-slate-800 hover:bg-slate-700 disabled:opacity-50 transition-colors"
            >
              Next
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
