"use client";

import { useMemo, useState } from "react";
import { useMutation, useQuery } from "convex/react";
import { FunctionReturnType } from "convex/server";
import { Id } from "@/convex/_generated/dataModel";

import { api } from "@/convex/_generated/api";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";

type BlacklistResult = FunctionReturnType<typeof api.blacklist.list>;
type BlacklistEntry = NonNullable<BlacklistResult>[number];

type BlacklistType =
  | "domain"
  | "email"
  | "phone"
  | "company"
  | "google_place_id"
  | "source_business_id";

const blacklistTypeOptions: BlacklistType[] = [
  "domain",
  "email",
  "phone",
  "company",
  "source_business_id",
  "google_place_id",
];

function labelForType(type: BlacklistType): string {
  if (type === "source_business_id") {
    return "Source Business ID";
  }
  if (type === "google_place_id") {
    return "Google Place ID";
  }

  return type.charAt(0).toUpperCase() + type.slice(1);
}

function formatDate(value: number): string {
  return new Intl.DateTimeFormat("de-DE", {
    dateStyle: "short",
    timeStyle: "short",
  }).format(new Date(value));
}

export function BlacklistManager() {
  const entries = useQuery(api.blacklist.list, { limit: 150 }) as
    | BlacklistResult
    | undefined;
  const createEntry = useMutation(api.blacklist.create);
  const updateEntry = useMutation(api.blacklist.update);
  const removeEntry = useMutation(api.blacklist.remove);

  const [type, setType] = useState<BlacklistType>("domain");
  const [value, setValue] = useState("");
  const [note, setNote] = useState("");
  const [rowBusyId, setRowBusyId] = useState<Id<"blacklistEntries"> | null>(null);
  const [formBusy, setFormBusy] = useState(false);
  const [statusMessage, setStatusMessage] = useState<string | null>(null);
  const [statusError, setStatusError] = useState<string | null>(null);

  const entriesSorted = useMemo(() => {
    if (!entries) {
      return [];
    }

    return [...entries].sort((a, b) => b.createdAt - a.createdAt);
  }, [entries]);

  const submitNew = async () => {
    if (!value.trim()) {
      setStatusError("Bitte ein Sperrwert eintragen.");
      return;
    }

    setFormBusy(true);
    setStatusError(null);
    setStatusMessage(null);

    try {
      await createEntry({
        type,
        value: value.trim(),
        note: note.trim().length > 0 ? note.trim() : undefined,
      });
      setValue("");
      setNote("");
      setStatusMessage("Eintrag hinzugefügt.");
    } catch {
      setStatusError("Eintrag konnte nicht erstellt werden.");
    } finally {
      setFormBusy(false);
    }
  };

  const remove = async (id: Id<"blacklistEntries">) => {
    setRowBusyId(id);
    setStatusError(null);
    setStatusMessage(null);

    try {
      await removeEntry({ id });
      setStatusMessage("Eintrag gelöscht.");
    } catch {
      setStatusError("Eintrag konnte nicht entfernt werden.");
    } finally {
      setRowBusyId(null);
    }
  };

  return (
    <section className="space-y-4 px-4 py-5 sm:px-6 lg:px-8">
      <div className="mx-auto flex w-full max-w-7xl flex-col gap-2">
        <p className="text-sm text-muted-foreground">Blacklist-Verwaltung</p>
        <h1 className="text-2xl font-semibold tracking-normal">Sperrliste</h1>
      </div>

      <div className="mx-auto w-full max-w-7xl">
        <Card className="p-4 space-y-4">
          <h2 className="text-sm font-medium">Neuen Eintrag anlegen</h2>
          <p className="text-sm text-muted-foreground">
            Neue Einträge wirken sofort: bestehende und neue Leads mit passendem
            Typ werden automatisch blockiert.
          </p>

          <div className="grid gap-3 sm:grid-cols-[150px_1fr_1fr_auto]">
            <Select
              value={type}
              onValueChange={(nextType) => setType(nextType as BlacklistType)}
            >
              <SelectTrigger>
                <SelectValue placeholder="Typ" />
              </SelectTrigger>
              <SelectContent>
                {blacklistTypeOptions.map((item) => (
                  <SelectItem value={item} key={item}>
                    {labelForType(item)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>

            <Input
              value={value}
              onChange={(event) => setValue(event.target.value)}
              placeholder="Wert"
            />

            <Input
              value={note}
              onChange={(event) => setNote(event.target.value)}
              placeholder="Notiz (optional)"
            />

            <Button
              onClick={submitNew}
              disabled={formBusy || !value.trim()}
              className="justify-start sm:w-auto"
            >
              Eintrag speichern
            </Button>
          </div>

          {statusError ? (
            <p className="text-sm text-destructive" role="status">
              {statusError}
            </p>
          ) : null}
          {statusMessage ? (
            <p className="text-sm text-muted-foreground" role="status">
              {statusMessage}
            </p>
          ) : null}
        </Card>
      </div>

      <div className="mx-auto w-full max-w-7xl">
        <Card>
          <div className="overflow-x-auto">
            <div className="min-w-[880px]">
              <table className="w-full border-separate border-spacing-0 text-sm">
                <thead>
                  <tr className="text-left text-xs text-muted-foreground">
                    <th className="p-3 font-normal">Typ</th>
                    <th className="p-3 font-normal">Wert</th>
                    <th className="p-3 font-normal">Notiz</th>
                    <th className="p-3 font-normal">Normalisiert</th>
                    <th className="p-3 font-normal">Erstellt</th>
                    <th className="p-3 font-normal">Aktion</th>
                  </tr>
                </thead>

                {entries === undefined ? (
                  <tbody>
                    <tr>
                      <td className="p-3" colSpan={6}>
                        <p className="rounded-md bg-muted p-4 text-sm">
                          Sperrliste wird geladen…
                        </p>
                      </td>
                    </tr>
                  </tbody>
                ) : entriesSorted.length === 0 ? (
                  <tbody>
                    <tr>
                      <td className="p-3" colSpan={6}>
                        <p className="rounded-md border p-4 text-sm text-muted-foreground">
                          Noch keine Sperreinträge.
                        </p>
                      </td>
                    </tr>
                  </tbody>
                ) : (
                  <tbody>
                    {entriesSorted.map((entry) => (
                      <BlacklistEntryRow
                        key={entry._id}
                        entry={entry}
                        onDelete={remove}
                        onUpdate={async (nextEntry) => {
                          setRowBusyId(nextEntry.id);
                          setStatusError(null);
                          setStatusMessage(null);

                          try {
                            await updateEntry(nextEntry);
                            setStatusMessage("Eintrag aktualisiert.");
                          } catch {
                            setStatusError("Eintrag konnte nicht gespeichert werden.");
                          } finally {
                            setRowBusyId(null);
                          }
                        }}
                        isBusy={rowBusyId === entry._id}
                      />
                    ))}
                  </tbody>
                )}
              </table>
            </div>
          </div>
        </Card>
      </div>
    </section>
  );
}

function BlacklistEntryRow({
  entry,
  onDelete,
  onUpdate,
  isBusy,
}: {
  entry: BlacklistEntry;
  onDelete: (id: Id<"blacklistEntries">) => Promise<void>;
  onUpdate: (next: {
    id: Id<"blacklistEntries">;
    type?: BlacklistType;
    value?: string;
    note?: string;
  }) => Promise<void>;
  isBusy: boolean;
}) {
  const [isEditing, setIsEditing] = useState(false);
  const [type, setType] = useState<BlacklistType>(entry.type);
  const [value, setValue] = useState(entry.value);
  const [note, setNote] = useState(entry.note ?? "");
  const [rowMessage, setRowMessage] = useState<string | null>(null);

  const submitUpdate = async () => {
    if (!value.trim()) {
      setRowMessage("Wert darf nicht leer sein.");
      return;
    }

    setRowMessage(null);

    await onUpdate({
      id: entry._id,
      type,
      value: value.trim(),
      note: note.trim().length > 0 ? note.trim() : undefined,
    });

    setIsEditing(false);
    setRowMessage("Gespeichert");
  };

  return (
    <tr className="border-t">
      <td className="p-3 align-top">
        {isEditing ? (
          <Select value={type} onValueChange={(nextType) => setType(nextType as BlacklistType)}>
            <SelectTrigger className="max-w-[168px]">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {blacklistTypeOptions.map((item) => (
                <SelectItem value={item} key={item}>
                  {labelForType(item)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        ) : (
          <Badge variant="secondary">{labelForType(entry.type)}</Badge>
        )}
      </td>
      <td className="max-w-[260px] p-3 align-top">
        {isEditing ? (
          <Input value={value} onChange={(event) => setValue(event.target.value)} />
        ) : (
          <p className="truncate">{entry.value}</p>
        )}
      </td>
      <td className="max-w-[300px] p-3 align-top">
        {isEditing ? (
          <Input value={note} onChange={(event) => setNote(event.target.value)} />
        ) : (
          <p className="truncate text-muted-foreground">
            {entry.note ?? "—"}
          </p>
        )}
      </td>
      <td className="p-3 align-top">
        <p className="truncate">{entry.normalizedValue}</p>
      </td>
      <td className="p-3 align-top">
        <p className="text-muted-foreground">{formatDate(entry.createdAt)}</p>
      </td>
      <td className="p-3 align-top">
        <div className="grid gap-2 sm:grid-cols-2">
          {isEditing ? (
            <>
              <Button size="sm" onClick={submitUpdate} disabled={isBusy}>
                Speichern
              </Button>
              <Button
                variant="outline"
                size="sm"
                onClick={() => setIsEditing(false)}
                disabled={isBusy}
              >
                Abbrechen
              </Button>
            </>
          ) : (
            <>
              <Button
                size="sm"
                variant="outline"
                onClick={() => setIsEditing(true)}
                disabled={isBusy}
              >
                Bearbeiten
              </Button>
              <Button
                size="sm"
                variant="destructive"
                onClick={() => onDelete(entry._id)}
                disabled={isBusy}
              >
                Löschen
              </Button>
            </>
          )}
        </div>
        {rowMessage ? (
          <p className="mt-2 text-xs text-muted-foreground">{rowMessage}</p>
        ) : null}
      </td>
    </tr>
  );
}
