"use client";

import React, { useMemo, useRef, useState, useEffect } from "react";
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  flexRender,
  createColumnHelper,
  SortingState,
  ColumnFiltersState,
} from "@tanstack/react-table";
import { useVirtualizer } from "@tanstack/react-virtual";
import { useGridStore, ColumnMetadata } from "@/store/use-grid-store";
import { cn } from "@/lib/utils";
import { ArrowUp, ArrowDown, ArrowUpDown, Search, AlertCircle, EyeOff, Eye, Info } from "lucide-react";

const columnHelper = createColumnHelper<any>();

// --- Header Component ---
interface EditableHeaderProps {
  column: any;
  metadata: ColumnMetadata;
  onShowInsights: (colName: string) => void;
}

function EditableHeader({ column, metadata, onShowInsights }: EditableHeaderProps) {
  const updateColumn = useGridStore((state) => state.updateColumn);
  const allOutliers = useGridStore((state) => state.detectedOutliers);
  const multivariateOutliers = useGridStore((state) => state.multivariateOutliers);
  const outliers = allOutliers[metadata.name] || [];

  const [isEditing, setIsEditing] = useState(false);
  const [newName, setNewName] = useState(metadata.name);

  const onRename = () => {
    if (newName !== metadata.name) {
      updateColumn(metadata.name, { name: newName });
    }
    setIsEditing(false);
  };

  const onTypeChange = (type: string) => {
    updateColumn(metadata.name, { type });
  };

  const sortDir = column.getIsSorted();

  return (
    <div className="flex flex-col gap-2 p-3 h-full justify-between">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2 flex-1 min-w-0 overflow-hidden">
          {isEditing ? (
            <input
              autoFocus
              className="bg-white border border-indigo-300 rounded px-1 text-xs outline-none w-full"
              value={newName}
              onChange={(e) => setNewName(e.target.value)}
              onBlur={onRename}
              onKeyDown={(e) => e.key === 'Enter' && onRename()}
              onClick={(e) => e.stopPropagation()}
            />
          ) : (
            <span
              className="truncate cursor-text font-bold text-slate-700 hover:text-indigo-600 transition-colors text-sm"
              onClick={(e) => { e.stopPropagation(); setIsEditing(true); }}
              title={metadata.name}
            >
              {metadata.name}
            </span>
          )}

          <div className="flex items-center gap-1 flex-shrink-0">
            {/* Univariate outlier indicator (column-specific) */}
            {outliers.length > 0 && (
              <button
                onClick={(e) => { e.stopPropagation(); onShowInsights(metadata.name); }}
                className="bg-rose-500 text-white rounded-full p-0.5 hover:scale-110 transition-transform animate-pulse"
                title={`${outliers.length} anomalie${outliers.length > 1 ? 's' : ''} détectée${outliers.length > 1 ? 's' : ''} dans cette colonne`}
              >
                <AlertCircle className="w-3 h-3" />
              </button>
            )}

            {/* Multivariate outlier indicator (global) - shows for ALL numeric columns when multivariate outliers exist */}
            {metadata.type === 'numeric' && multivariateOutliers.length > 0 && (
              <button
                onClick={(e) => { e.stopPropagation(); onShowInsights('__GLOBAL__'); }}
                className="bg-purple-500 text-white rounded-full p-0.5 hover:scale-110 transition-transform"
                title={`${multivariateOutliers.length} anomalie${multivariateOutliers.length > 1 ? 's' : ''} multivariée${multivariateOutliers.length > 1 ? 's' : ''} détectée${multivariateOutliers.length > 1 ? 's' : ''}`}
              >
                <AlertCircle className="w-3 h-3" />
              </button>
            )}
          </div>
        </div>

        <div className="flex items-center gap-1 flex-shrink-0">
           <button
            onClick={column.getToggleSortingHandler()}
            className={cn(
              "text-slate-400 hover:text-indigo-600 transition-colors p-1 rounded hover:bg-slate-100",
              sortDir && "text-indigo-600 bg-indigo-50"
            )}
          >
            {sortDir === 'asc' ? <ArrowUp className="w-3 h-3" /> :
             sortDir === 'desc' ? <ArrowDown className="w-3 h-3" /> :
             <ArrowUpDown className="w-3 h-3 opacity-50" />}
          </button>
        </div>
      </div>

      <div className="flex items-center gap-2">
        <select
          className="text-[10px] bg-slate-100 border border-slate-200 rounded px-1.5 py-0.5 font-semibold uppercase text-slate-500 cursor-pointer hover:bg-slate-200 transition-colors focus:ring-1 focus:ring-indigo-500 outline-none w-16"
          value={metadata.type}
          onChange={(e) => onTypeChange(e.target.value)}
          onClick={(e) => e.stopPropagation()}
        >
          <option value="numeric">Num</option>
          <option value="categorical">Cat</option>
          <option value="date">Date</option>
          <option value="boolean">Bool</option>
        </select>

        <div className="relative flex-1 min-w-0">
          <Search className="absolute left-1.5 top-1/2 -translate-y-1/2 w-3 h-3 text-slate-400" />
          <input
            value={(column.getFilterValue() as string) ?? ""}
            onChange={(e) => column.setFilterValue(e.target.value)}
            onClick={(e) => e.stopPropagation()}
            placeholder="Filtrer..."
            className="w-full bg-white border border-slate-200 rounded pl-6 pr-2 py-0.5 text-[10px] outline-none focus:border-indigo-400 transition-all placeholder:text-slate-300"
          />
        </div>
      </div>

      <div className="h-1 w-full bg-slate-100 rounded-full overflow-hidden mt-1">
        <div
          className={cn(
            "h-full transition-all",
            metadata.type === 'numeric' ? "bg-indigo-500 w-full" :
            metadata.type === 'date' ? "bg-emerald-500 w-full" : "bg-slate-400 w-1/2"
          )}
        />
      </div>
    </div>
  );
}

// ... (Rest of the file remains same, keeping Cell and SmartGrid logic) ...

// --- Cell Component ---
interface EditableCellProps {
  initialValue: any;
  rowIndex: number;
  colName: string;
  type: string;
  isExcluded: boolean;
  activeInsightColumn: string | null;
}

function EditableCell({ initialValue, rowIndex, colName, type, isExcluded, activeInsightColumn }: EditableCellProps) {
  const [isEditing, setIsEditing] = useState(false);
  const [value, setValue] = useState(initialValue);
  const updateCellValue = useGridStore((state) => state.updateCellValue);
  const isModified = useGridStore((state) => state.modifiedCells.has(`${rowIndex}:${colName}`));
  const detectedOutliers = useGridStore((state) => state.detectedOutliers);
  const multivariateOutliers = useGridStore((state) => state.multivariateOutliers);

  // Check if this specific cell is a univariate outlier
  const columnOutliers = detectedOutliers[colName] || [];
  const isUnivariateOutlier = columnOutliers.some((o: any) => o.index === rowIndex);

  // Check if this row is a multivariate outlier
  const isMultivariateOutlier = multivariateOutliers.some((o: any) => o.index === rowIndex);

  // Check if this cell should be highlighted (active insight column AND is outlier)
  const shouldHighlightRed = activeInsightColumn === colName && isUnivariateOutlier;

  // Check if this cell should be highlighted purple (global multivariate view is active)
  const shouldHighlightPurple = activeInsightColumn === '__GLOBAL__' && isMultivariateOutlier;

  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]);

  const onCommit = () => {
    if (value !== initialValue) {
      if (type === 'numeric' && isNaN(Number(value))) {
        setValue(initialValue);
      } else {
        updateCellValue(rowIndex, colName, type === 'numeric' ? Number(value) : value);
      }
    }
    setIsEditing(false);
  };

  if (isEditing) {
    return (
      <input
        autoFocus
        className={cn(
          "w-full h-full border-2 outline-none px-2 py-1 font-mono text-sm absolute inset-0 z-20",
          (isUnivariateOutlier || isMultivariateOutlier)
            ? "bg-rose-50 border-rose-500 text-rose-900"
            : "bg-indigo-50 border-indigo-500 text-indigo-900"
        )}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onBlur={onCommit}
        onKeyDown={(e) => {
          if (e.key === 'Enter') onCommit();
          if (e.key === 'Escape') {
            setValue(initialValue);
            setIsEditing(false);
          }
        }}
      />
    );
  }

  return (
    <div
      className={cn(
        "px-3 py-2.5 truncate font-mono text-sm h-full flex items-center relative",
        type === 'numeric' ? "justify-end text-slate-700" : "justify-start text-slate-600",
        isModified && !shouldHighlightRed && !shouldHighlightPurple && "bg-amber-50 font-bold text-amber-800",
        isExcluded && "opacity-30 italic line-through decoration-slate-400 bg-slate-50",
        // Red highlight: univariate outliers for specific column
        shouldHighlightRed && !isExcluded && "bg-rose-200 text-rose-900 font-bold border-4 border-rose-500 shadow-lg shadow-rose-200 animate-pulse",
        // Purple highlight: multivariate outliers (global view)
        shouldHighlightPurple && !isExcluded && "bg-purple-200 text-purple-900 font-bold border-4 border-purple-500 shadow-lg shadow-purple-200 animate-pulse"
      )}
      onDoubleClick={() => setIsEditing(true)}
      title={
        shouldHighlightRed && isUnivariateOutlier ? `⚠️ Outlier univarié: ${value?.toString()}` :
        shouldHighlightPurple && isMultivariateOutlier ? `🔍 Outlier multivarié: ${value?.toString()}` :
        value?.toString()
      }
    >
      {shouldHighlightRed && isUnivariateOutlier && (
        <AlertCircle className="w-3 h-3 text-rose-600 absolute top-1 left-1 shrink-0" />
      )}
      {shouldHighlightPurple && isMultivariateOutlier && (
        <AlertCircle className="w-3 h-3 text-purple-600 absolute top-1 left-1 shrink-0" />
      )}
      <span className={(shouldHighlightRed || shouldHighlightPurple) ? "ml-4" : ""}>{value?.toString() ?? ""}</span>
    </div>
  );
}

// --- Legend Component ---
function AnomalyLegend() {
  const allOutliers = useGridStore((state) => state.detectedOutliers);
  const multivariateOutliers = useGridStore((state) => state.multivariateOutliers);

  // Check if there are any anomalies to show legend for
  const hasUnivariate = Object.values(allOutliers).some(outliers => outliers.length > 0);
  const hasMultivariate = multivariateOutliers.length > 0;

  // Only show legend if there are anomalies
  if (!hasUnivariate && !hasMultivariate) {
    return null;
  }

  return (
    <div className="flex items-center gap-3 px-4 py-2.5 bg-gradient-to-r from-slate-50 to-indigo-50/30 border-b border-slate-200 rounded-t-xl">
      <div className="flex items-center gap-1.5 text-slate-600">
        <Info className="w-4 h-4 text-indigo-500" />
        <span className="text-xs font-semibold uppercase tracking-wide">Légende des anomalies</span>
      </div>

      <div className="h-4 w-px bg-slate-300" />

      {hasUnivariate && (
        <div className="flex items-center gap-2 px-3 py-1.5 bg-white rounded-lg border border-slate-200 shadow-sm">
          <div className="bg-rose-500 text-white rounded-full p-0.5">
            <AlertCircle className="w-3 h-3" />
          </div>
          <span className="text-xs text-slate-700 font-medium">
            Anomalies dans cette colonne
          </span>
        </div>
      )}

      {hasMultivariate && (
        <div className="flex items-center gap-2 px-3 py-1.5 bg-white rounded-lg border border-slate-200 shadow-sm">
          <div className="bg-purple-500 text-white rounded-full p-0.5">
            <AlertCircle className="w-3 h-3" />
          </div>
          <span className="text-xs text-slate-700 font-medium">
            Anomalies globales (multivariées)
          </span>
        </div>
      )}

      <div className="ml-auto text-[10px] text-slate-400 italic">
        Cliquez sur un indicateur pour voir les détails
      </div>
    </div>
  );
}

// --- Main Grid Component ---
interface SmartGridProps {
  onShowInsights: (colName: string) => void;
}

export function SmartGrid({ onShowInsights }: SmartGridProps) {
  const { data, columns: metadata, isLoading, excludedRows, toggleRowExclusion, detectedOutliers, multivariateOutliers, activeInsightColumn } = useGridStore();
  const parentRef = useRef<HTMLDivElement>(null);

  const [sorting, setSorting] = useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);

  // Check if there are any anomalies for conditional styling
  const hasUnivariate = Object.values(detectedOutliers).some(outliers => outliers.length > 0);
  const hasMultivariate = multivariateOutliers.length > 0;
  const hasAnomalies = hasUnivariate || hasMultivariate;

  const columns = useMemo(() => {
    return metadata.map((col) =>
      columnHelper.accessor(col.name, {
        header: ({ column }) => <EditableHeader column={column} metadata={col} onShowInsights={onShowInsights} />,
        cell: ({ getValue, row }) => (
          <EditableCell
            initialValue={getValue()}
            rowIndex={row.index}
            colName={col.name}
            type={col.type}
            isExcluded={excludedRows.has(row.index)}
            activeInsightColumn={activeInsightColumn}
          />
        ),
        size: 180,
        minSize: 120,
        maxSize: 400,
      })
    );
  }, [metadata, excludedRows, onShowInsights, activeInsightColumn]);

  const table = useReactTable({
    data,
    columns,
    state: {
      sorting,
      columnFilters,
    },
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    defaultColumn: {
      size: 180,
    },
  });

  const { rows } = table.getRowModel();

  const rowVirtualizer = useVirtualizer({
    count: rows.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 40,
    overscan: 20,
  });

  if (isLoading) {
    return (
      <div className="flex flex-col items-center justify-center h-full space-y-4 animate-pulse">
        <div className="w-12 h-12 bg-slate-200 rounded-full"></div>
        <p className="text-slate-500 font-medium">Chargement des données...</p>
      </div>
    );
  }

  if (data.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center h-full border-2 border-dashed border-slate-200 rounded-xl bg-slate-50/50">
        <p className="text-slate-400 font-medium">Aucune donnée chargée. Veuillez uploader un fichier.</p>
      </div>
    );
  }

  return (
    <div className="flex flex-col h-full border border-slate-200 rounded-xl bg-white shadow-sm overflow-hidden">
      {/* Legend Section */}
      <AnomalyLegend />

      {/* Table Container */}
      <div ref={parentRef} className={cn("flex-1 overflow-auto relative", !hasAnomalies && "rounded-t-xl")}>
        <table className="border-separate border-spacing-0 w-full" style={{ width: table.getTotalSize() }}>
          <thead className="sticky top-0 z-20 bg-slate-50 shadow-sm">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id}>
                {/* Fixed Row Number Column Header */}
                <th className="sticky left-0 z-30 w-12 border-b border-r border-slate-200 bg-slate-100/90 backdrop-blur px-2 text-[10px] font-mono text-slate-500 text-center uppercase tracking-tighter">
                  #
                </th>
                {headerGroup.headers.map((header) => (
                  <th
                    key={header.id}
                    style={{ width: header.getSize() }}
                    className="border-b border-r border-slate-200 text-left align-top bg-slate-50/90 backdrop-blur p-0"
                  >
                    {flexRender(header.column.columnDef.header, header.getContext())}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody
            style={{
              height: `${rowVirtualizer.getTotalSize()}px`,
              position: "relative",
            }}
          >
            {rowVirtualizer.getVirtualItems().map((virtualRow) => {
              const row = rows[virtualRow.index];
              const isExcluded = excludedRows.has(row.index);
              return (
                <tr
                  key={row.id}
                  className={cn(
                    "group transition-colors",
                    isExcluded ? "bg-slate-50" : "hover:bg-indigo-50/10"
                  )}
                  style={{
                    position: "absolute",
                    top: 0,
                    left: 0,
                    width: "100%",
                    height: `${virtualRow.size}px`,
                    transform: `translateY(${virtualRow.start}px)`,
                  }}
                >
                  {/* Fixed Row Number Cell */}
                  <td className="sticky left-0 z-10 w-12 border-b border-r border-slate-100 px-0 bg-white group-hover:bg-slate-50">
                    <div className="flex items-center justify-center h-full w-full">
                        <button 
                            onClick={() => toggleRowExclusion(row.index)}
                            className={cn(
                            "p-1 rounded transition-all opacity-0 group-hover:opacity-100 focus:opacity-100",
                            isExcluded ? "text-rose-500 opacity-100" : "text-slate-300 hover:text-slate-500"
                            )}
                            title={isExcluded ? "Inclure" : "Exclure"}
                        >
                            {isExcluded ? <EyeOff className="w-3.5 h-3.5" /> : <Eye className="w-3.5 h-3.5" />}
                        </button>
                        <span className={cn("text-[10px] font-mono text-slate-400 absolute", isExcluded || "group-hover:opacity-0")}>
                            {virtualRow.index + 1}
                        </span>
                    </div>
                  </td>
                  
                  {row.getVisibleCells().map((cell) => (
                    <td 
                      key={cell.id} 
                      style={{ width: cell.column.getSize() }}
                      className="border-b border-r border-slate-100 p-0 relative"
                    >
                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
                    </td>
                  ))}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}
