import { useEffect, useMemo, useState } from "react";
import { useParams } from "react-router-dom";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { queryKeys } from "@/hooks/queries/keys";
import { levelMappingService } from "@/services/level-mapping.service";
import type { LevelMappingRow } from "@/types";
import { toast } from "sonner";

function validateRows(rows: LevelMappingRow[]): string | null {
  const sorted = [...rows].sort((x, y) => x.cefr_min_score - y.cefr_min_score);
  for (const r of sorted) {
    if (r.cefr_min_score > r.cefr_max_score) return "Each row must have min ≤ max.";
  }
  for (let i = 1; i < sorted.length; i++) {
    if (sorted[i].cefr_min_score <= sorted[i - 1].cefr_max_score) {
      return "CEFR score ranges must not overlap.";
    }
  }
  return null;
}

export default function LevelMappingConfig() {
  const { entityId: eid } = useParams<{ entityId: string }>();
  const entityId = Number(eid);
  const qc = useQueryClient();

  const { data, isLoading } = useQuery({
    queryKey: queryKeys.levelMapping.get(entityId),
    queryFn: () => levelMappingService.get(entityId),
    enabled: Number.isFinite(entityId),
  });

  const [rows, setRows] = useState<LevelMappingRow[]>([]);

  useEffect(() => {
    if (data?.mappings?.length) setRows(data.mappings.map((r) => ({ ...r })));
  }, [data]);

  const dirty = useMemo(() => JSON.stringify(rows) !== JSON.stringify(data?.mappings ?? []), [rows, data]);

  const saveMut = useMutation({
    mutationFn: () => levelMappingService.update(entityId, rows),
    onSuccess: () => {
      toast.success("Saved.");
      qc.invalidateQueries({ queryKey: queryKeys.levelMapping.get(entityId) });
    },
    onError: (e) => toast.error(e instanceof Error ? e.message : "Save failed"),
  });

  const resetMut = useMutation({
    mutationFn: () => levelMappingService.resetToDefault(entityId),
    onSuccess: () => {
      toast.success("Reset.");
      qc.invalidateQueries({ queryKey: queryKeys.levelMapping.get(entityId) });
    },
    onError: (e) => toast.error(e instanceof Error ? e.message : "Reset failed"),
  });

  const updateRow = (index: number, patch: Partial<LevelMappingRow>) => {
    setRows((prev) => prev.map((r, i) => (i === index ? { ...r, ...patch } : r)));
  };

  const addRow = () => {
    setRows((prev) => [
      ...prev,
      {
        cefr_min_score: 0,
        cefr_max_score: 0,
        internal_level_name: "New level",
        cefr_equivalent: "B1",
      },
    ]);
  };

  const save = () => {
    const err = validateRows(rows);
    if (err) {
      toast.error(err);
      return;
    }
    saveMut.mutate();
  };

  if (!Number.isFinite(entityId)) {
    return <div className="p-6 text-destructive">Invalid entity.</div>;
  }

  if (isLoading) {
    return <div className="p-6 text-muted-foreground">Loading mapping…</div>;
  }

  return (
    <div className="space-y-6 p-6 max-w-5xl mx-auto">
      <div>
        <h1 className="text-2xl font-semibold tracking-tight">Level mapping</h1>
        <p className="text-muted-foreground text-sm mt-1">Entity #{entityId}</p>
      </div>

      <Card>
        <CardHeader className="flex flex-row items-center justify-between">
          <div>
            <CardTitle>CEFR ↔ internal levels</CardTitle>
            <CardDescription>Editable grid with overlap validation</CardDescription>
          </div>
          <div className="flex gap-2">
            <Button variant="outline" onClick={addRow}>
              Add Row
            </Button>
            <Button variant="outline" onClick={() => resetMut.mutate()} disabled={resetMut.isPending}>
              Reset to Default
            </Button>
            <Button onClick={save} disabled={!dirty || saveMut.isPending}>
              Save
            </Button>
          </div>
        </CardHeader>
        <CardContent>
          <div className="rounded-md border overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>CEFR min score</TableHead>
                  <TableHead>CEFR max score</TableHead>
                  <TableHead>Internal level name</TableHead>
                  <TableHead>CEFR equivalent</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {rows.map((row, i) => (
                  <TableRow key={row.id ?? i}>
                    <TableCell>
                      <Input
                        type="number"
                        value={row.cefr_min_score}
                        onChange={(e) => updateRow(i, { cefr_min_score: Number(e.target.value) })}
                      />
                    </TableCell>
                    <TableCell>
                      <Input
                        type="number"
                        value={row.cefr_max_score}
                        onChange={(e) => updateRow(i, { cefr_max_score: Number(e.target.value) })}
                      />
                    </TableCell>
                    <TableCell>
                      <Input
                        value={row.internal_level_name}
                        onChange={(e) => updateRow(i, { internal_level_name: e.target.value })}
                      />
                    </TableCell>
                    <TableCell>
                      <Input
                        value={row.cefr_equivalent}
                        onChange={(e) => updateRow(i, { cefr_equivalent: e.target.value })}
                      />
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
