import React, { useState, useMemo } from 'react';
import { ExcelRow } from '../types';
import { Search, Filter, ChevronDown, ChevronUp, X as XIcon } from 'lucide-react';
import { cn } from '../lib/utils';
import { ColumnFilterPopover } from './ColumnFilterPopover';

interface MatrixViewProps {
  data: ExcelRow[];
  headers: string[];
  rowStatuses: Record<string, string>;
}

export function MatrixView({ data, headers, rowStatuses }: MatrixViewProps) {
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(25);
  const [search, setSearch] = useState('');
  const [columnFilters, setColumnFilters] = useState<Record<number, string[]>>({});
  const [openFilterCol, setOpenFilterCol] = useState<number | null>(null);
  const [sortCol, setSortCol] = useState<number | null>(null);
  const [sortDesc, setSortDesc] = useState(false);

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

    // Global search
    if (search) {
      const s = search.toLowerCase();
      result = result.filter(r => 
        r.row.some(cell => String(cell || '').toLowerCase().includes(s))
      );
    }

    // Column-specific filters
    Object.entries(columnFilters).forEach(([colIdx, selectedValues]) => {
      const vals = selectedValues as string[];
      if (vals.length > 0) {
        result = result.filter(r => vals.includes(String(r.row[Number(colIdx)] || '')));
      }
    });

    // Sorting
    if (sortCol !== null) {
      result.sort((a, b) => {
        const valA = String(a.row[sortCol] || '').toLowerCase();
        const valB = String(b.row[sortCol] || '').toLowerCase();
        
        // Handle numbers sorting correctly
        const numA = parseFloat(valA.replace(',', '.'));
        const numB = parseFloat(valB.replace(',', '.'));
        
        if (!isNaN(numA) && !isNaN(numB)) {
          return sortDesc ? numB - numA : numA - numB;
        }
        
        return sortDesc 
          ? valB.localeCompare(valA)
          : valA.localeCompare(valB);
      });
    }

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

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

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

  const getUniqueValues = (col: number) => {
    const values = data.map(r => String(r[col] || ''));
    return Array.from(new Set(values)).sort();
  };

  const toggleColumnFilter = (col: number, value: string) => {
    setColumnFilters(prev => {
      const current = prev[col] || [];
      const next = current.includes(value)
        ? current.filter(v => v !== value)
        : [...current, value];
      return { ...prev, [col]: next };
    });
    setPage(1);
  };

  const setBatchColumnFilter = (col: number, values: string[]) => {
    setColumnFilters(prev => ({ ...prev, [col]: values }));
    setPage(1);
  };

  const formatCellValue = (val: any, header: string = '') => {
    if (val === undefined || val === null || val === '') return '';

    // Convert header to lowercase for checks
    const h = header.toLowerCase();

    // Handle date columns - Excel serial dates are numbers >= 25569 (Jan 1, 1970)
    if (h.includes('date') || h.includes('launch') || h.includes('ready')) {
      if (typeof val === 'number' && val >= 25569 && val <= 60000) {
        const excelEpoch = new Date(1899, 11, 30);
        const date = new Date(excelEpoch.getTime() + val * 86400000);
        return date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' });
      }
      return val;
    }

    // Always format weight/NW/GW/kg columns to 2 decimals — checked before any exclusion logic
    if (h.includes('nw') || h.includes('gw') || h.includes('weight') || h.includes('kg')) {
      if (typeof val === 'number') return val.toFixed(2);
      if (typeof val === 'string') {
        const num = parseFloat(val.trim().replace(',', '.'));
        if (!isNaN(num)) return num.toFixed(2);
      }
      return val;
    }

    // Do NOT format columns that are clearly IDs, barcodes, or codes
    if (h.includes('id') || h.includes('no') || h.includes('code') || h.includes('art.') || h.includes('barcode') || h.includes('article')) {
      return val;
    }

    // List of keywords that typically indicate a price, measure or numeric value to format
    const formatKeywords = ['price', 'eur', 'cost', 'msrp', 'net', 'gross', 'netto', 'brutto', 'pp', 'pph', 'uvp', 'vpe', 'stk', 'nw', 'gw', 'weight', 'kg'];
    const shouldFormat = formatKeywords.some(kw => h.includes(kw));

    // Handle numbers
    if (typeof val === 'number') {
      return val.toFixed(2);
    }

    // Handle strings that represent numbers
    if (typeof val === 'string') {
      // Normalize decimals (handle comma as decimal separator)
      const normalized = val.trim().replace(',', '.');
      const num = parseFloat(normalized);

      if (!isNaN(num)) {
        // Format if header contains keywords OR if it already looks like a decimal
        if (shouldFormat || val.includes('.') || val.includes(',')) {
          return num.toFixed(2);
        }
      }
    }

    return val;
  };

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

  return (
    <div className="flex flex-col h-full bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden">
      <div className="p-4 border-b border-slate-700 bg-slate-800/50 flex items-center justify-between">
        <div>
          <h2 className="text-lg font-semibold text-white">Matrix View</h2>
          <p className="text-sm text-slate-400">All data fields formatted to 2 decimal places for numbers/prices.</p>
        </div>
        <div className="flex items-center gap-4">
          <div className="relative min-w-[300px]">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" />
            <input
              type="text"
              placeholder="Search all columns..."
              value={search}
              onChange={e => { setSearch(e.target.value); setPage(1); }}
              className="w-full pl-9 pr-4 py-2 bg-slate-900 border border-slate-700 rounded-md text-sm text-white focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all font-medium"
            />
          </div>
          {(Object.values(columnFilters) as string[][]).some(v => v.length > 0) && (
            <button
              onClick={() => {
                setColumnFilters({});
                setPage(1);
              }}
              className="flex items-center gap-2 px-4 py-2 bg-red-600/10 text-red-400 hover:bg-red-600 hover:text-white rounded-md text-sm font-medium transition-colors border border-red-600/20"
            >
              <XIcon className="w-4 h-4" />
              Clear All Column Filters
            </button>
          )}
        </div>
      </div>
      
      <div className="overflow-auto flex-1">
        <table className="w-full text-left text-sm whitespace-nowrap">
          <thead className="bg-slate-900/50 text-slate-400 sticky top-0 z-10">
            <tr>
              {headers.map((header, index) => (
                <th 
                  key={index} 
                  className="px-4 py-3 font-medium border-b border-slate-700 transition-colors select-none group relative"
                >
                  <div className="flex items-center justify-between gap-2">
                    <div 
                      className="flex items-center gap-1 cursor-pointer hover:text-white"
                      onClick={() => handleSort(index)}
                    >
                      {header}
                      {sortCol === index && (
                        sortDesc ? <ChevronDown className="w-3 h-3" /> : <ChevronUp className="w-3 h-3" />
                      )}
                    </div>
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        setOpenFilterCol(openFilterCol === index ? null : index);
                      }}
                      className={cn(
                        "p-1 rounded hover:bg-slate-700 transition-colors",
                        (columnFilters[index]?.length || 0) > 0 ? "text-blue-400 bg-blue-400/10 opacity-100" : "text-slate-500 opacity-0 group-hover:opacity-100"
                      )}
                    >
                      <Filter className="w-3.5 h-3.5" />
                    </button>
                  </div>

                  {openFilterCol === index && (
                    <ColumnFilterPopover
                      uniqueValues={getUniqueValues(index)}
                      selectedValues={columnFilters[index] || []}
                      onToggle={(val) => toggleColumnFilter(index, val)}
                      onSelectAll={(vals) => setBatchColumnFilter(index, vals)}
                      onClear={() => {
                        setColumnFilters(prev => {
                          const next = { ...prev };
                          delete next[index];
                          return next;
                        });
                        setOpenFilterCol(null);
                      }}
                      onClose={() => setOpenFilterCol(null)}
                      title={header}
                    />
                  )}
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-slate-700/50">
            {paginatedData.map(({ row, index: rowIndex }) => (
              <tr key={rowIndex} className="hover:bg-slate-700/30 transition-colors">
                {headers.map((header, colIndex) => {
                  const formattedValue = formatCellValue(row[colIndex], header);
                  return (
                    <td 
                      key={colIndex} 
                      className="px-4 py-3 text-slate-300 max-w-[200px] truncate" 
                      title={String(row[colIndex] || '')}
                    >
                      {formattedValue}
                    </td>
                  );
                })}
              </tr>
            ))}
            {paginatedData.length === 0 && (
              <tr>
                <td colSpan={headers.length} className="px-4 py-8 text-center text-slate-500">
                  No data available.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      <div className="bg-slate-900 border-t border-slate-700 p-4 flex items-center justify-between text-sm text-slate-400">
        <div className="flex items-center gap-4">
          <span>Showing {Math.min((page - 1) * pageSize + 1, filteredData.length)} to {Math.min(page * pageSize, filteredData.length)} of {filteredData.length} entries</span>
          <select
            value={pageSize}
            onChange={e => { setPageSize(Number(e.target.value)); setPage(1); }}
            className="bg-slate-800 border border-slate-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
          >
            <option value={25}>25 per page</option>
            <option value={50}>50 per page</option>
            <option value={100}>100 per page</option>
          </select>
        </div>
        <div className="flex items-center gap-2">
          <button
            disabled={page === 1}
            onClick={() => setPage(p => p - 1)}
            className="px-3 py-1 rounded bg-slate-800 hover:bg-slate-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          >
            Previous
          </button>
          <span className="px-3 py-1 font-medium text-white">Page {page} of {totalPages || 1}</span>
          <button
            disabled={page === totalPages || totalPages === 0}
            onClick={() => setPage(p => p + 1)}
            className="px-3 py-1 rounded bg-slate-800 hover:bg-slate-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          >
            Next
          </button>
        </div>
      </div>
    </div>
  );
}
