"use client";

import { useMemo, useState } from "react";
import { useMutation, useQuery } from "convex/react";
import { FunctionReturnType } from "convex/server";
import { Building2, Mail, MapPin, Phone, ShieldAlert } from "lucide-react";

import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import {
  getLeadBlacklistStatusLabel,
  getLeadContactStatusLabel,
  getLeadDuplicateStatusLabel,
  getLeadPriorityLabel,
  leadBlacklistStatusOptions,
  leadContactStatusOptions,
  leadDuplicateStatusOptions,
  leadPriorityOptions,
  type LeadContactStatus,
  type LeadDuplicateStatus,
  type LeadPriority,
  type LeadBlacklistStatus,
} from "@/lib/dashboard-model";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";

type LeadsListResult = FunctionReturnType<typeof api.leads.list>;
type LeadRow = NonNullable<LeadsListResult>[number];

type LeadReviewDraft = {
  priority: LeadPriority;
  contactStatus: LeadContactStatus;
  priorityReason: string;
  contactStatusReason: string;
  notes: string;
  reviewEmail: string;
  reviewEmailSource: string;
  reviewContactPerson: string;
  reviewIsBusinessContactAddress: boolean;
  duplicateStatus: LeadDuplicateStatus;
  blacklistStatus: LeadBlacklistStatus;
};

type LeadReviewPayload = {
  id: Id<"leads">;
  priority?: LeadPriority;
  priorityReason?: string;
  contactStatus?: LeadContactStatus;
  contactStatusReason?: string;
  notes?: string;
  duplicateStatus?: LeadDuplicateStatus;
  duplicateReason?: string;
  blacklistStatus?: LeadBlacklistStatus;
  blacklistReason?: string;
  duplicateOfLeadId?: Id<"leads">;
  applyBlacklist?: boolean;
  reviewEmail?: string;
  reviewEmailSource?: string;
  reviewContactPerson?: string;
  reviewIsBusinessContactAddress?: boolean;
};

function normalizeTextInput(value: string): string | undefined {
  const next = value.trim();

  return next.length > 0 ? next : undefined;
}

function contactSourceLabel(lead: LeadRow): string {
  if (lead.sourceProvider) {
    return lead.sourceProvider;
  }

  if (lead.emailSource) {
    return lead.emailSource;
  }

  return "Unbekannt";
}

function formatLocation(lead: LeadRow): string {
  if (lead.postalCode && lead.city) {
    return `${lead.postalCode} ${lead.city}`;
  }

  if (lead.city || lead.address) {
    return lead.city ?? lead.address ?? "";
  }

  return lead.address ?? "Ort offen";
}

function priorityBadgeClass(priority: LeadPriority): string {
  switch (priority) {
    case "high":
      return "text-destructive border-destructive/30 bg-destructive/15";
    case "medium":
      return "text-muted-foreground border-muted-foreground/30 bg-muted/20";
    case "low":
      return "text-muted-foreground border-muted/40 bg-muted/35";
    case "defer":
      return "text-muted-foreground border-secondary/50 bg-secondary/30";
    case "blocked":
      return "text-destructive border-destructive/40 bg-destructive/15";
    default:
      return "text-muted-foreground border-muted bg-muted/20";
  }
}

function duplicateBadgeVariant(
  duplicateStatus: LeadDuplicateStatus,
): "secondary" | "default" | "outline" | "destructive" {
  if (duplicateStatus === "duplicate") {
    return "destructive";
  }

  if (duplicateStatus === "possible_duplicate") {
    return "outline";
  }

  if (duplicateStatus === "unique") {
    return "secondary";
  }

  return "outline";
}

export function LeadsReviewTable() {
  const leads = useQuery(api.leads.list, { limit: 120 });
  const [actionMessage, setActionMessage] = useState<string | null>(null);

  const sortedLeads = useMemo(() => {
    if (!leads) {
      return [];
    }

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

  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">Leads Review</p>
        <h1 className="text-2xl font-semibold tracking-normal">Leads prüfen</h1>
      </div>

      <div className="mx-auto w-full max-w-7xl">
        <Card className="overflow-hidden">
          <div className="overflow-x-auto">
            <div className="min-w-[1150px]">
              <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">Firma / Ort</th>
                    <th className="p-3 font-normal">Kontakt + Quelle</th>
                    <th className="p-3 font-normal">Priorität</th>
                    <th className="p-3 font-normal">Kontaktstatus</th>
                    <th className="p-3 font-normal">Qualität</th>
                    <th className="p-3 font-normal">Review-Felder</th>
                    <th className="p-3 font-normal">Aktionen</th>
                  </tr>
                </thead>

                {leads === undefined ? (
                  <tbody>
                    <tr>
                      <td className="p-3" colSpan={7}>
                        <p className="rounded-md bg-muted p-4 text-sm">
                          Leads werden geladen…
                        </p>
                      </td>
                    </tr>
                  </tbody>
                ) : sortedLeads.length === 0 ? (
                  <tbody>
                    <tr>
                      <td className="p-3" colSpan={7}>
                        <p className="rounded-md border p-4 text-sm text-muted-foreground">
                          Keine Leads vorhanden. Bitte zuerst eine Kampagne starten
                          oder importieren.
                        </p>
                      </td>
                    </tr>
                  </tbody>
                ) : (
                  <tbody>
                    {sortedLeads.map((lead) => (
                      <LeadReviewRow
                        key={lead._id}
                        lead={lead}
                        onActionMessage={setActionMessage}
                      />
                    ))}
                  </tbody>
                )}
              </table>
            </div>
          </div>
        </Card>
      </div>

      {actionMessage ? (
        <p className="mx-auto max-w-7xl text-sm text-muted-foreground">
          {actionMessage}
        </p>
      ) : null}
    </section>
  );
}

function LeadReviewRow({
  lead,
  onActionMessage,
}: {
  lead: LeadRow;
  onActionMessage: (value: string) => void;
}) {
  const [draft, setDraft] = useState<LeadReviewDraft>(() => ({
    priority: lead.priority,
    contactStatus: lead.contactStatus,
    priorityReason: lead.priorityReason ?? "",
    contactStatusReason: lead.contactStatusReason ?? "",
    notes: lead.notes ?? "",
    reviewEmail: lead.email ?? "",
    reviewEmailSource: lead.emailSource ?? "",
    reviewContactPerson: lead.contactPerson ?? "",
    reviewIsBusinessContactAddress: false,
    duplicateStatus: (lead.duplicateStatus as LeadDuplicateStatus) ?? "unchecked",
    blacklistStatus: lead.blacklistStatus,
  }));
  const [isSaving, setIsSaving] = useState(false);
  const [isBlocking, setIsBlocking] = useState(false);
  const [rowMessage, setRowMessage] = useState<string | null>(null);
  const reviewUpdate = useMutation(api.leads.reviewUpdate);

  const location = formatLocation(lead);
  const reasonParts = [
    lead.priorityReason,
    lead.contactStatusReason,
    lead.duplicateReason,
    lead.blacklistReason,
  ].filter((item): item is string => Boolean(item));

  const update = async (
    payload?: Omit<LeadReviewPayload, "id">,
  ) => {
    setIsSaving(true);
    setRowMessage(null);
    onActionMessage("");

    try {
      await reviewUpdate({ id: lead._id, ...payload } as LeadReviewPayload);
      setRowMessage("Gespeichert");
      onActionMessage("Aktualisierung übernommen");
    } catch {
      setRowMessage("Speichern fehlgeschlagen");
    } finally {
      setIsSaving(false);
      setTimeout(() => setRowMessage(null), 1400);
    }
  };

  const saveRow = async () => {
    const reviewEmail = normalizeTextInput(draft.reviewEmail);
    const reviewEmailSource = normalizeTextInput(draft.reviewEmailSource);
    const reviewContactPerson = draft.reviewContactPerson.trim();
    const shouldUpdateEmailReview =
      reviewEmail !== normalizeTextInput(lead.email ?? "") ||
      reviewEmailSource !== normalizeTextInput(lead.emailSource ?? "") ||
      reviewContactPerson !== normalizeTextInput(lead.contactPerson ?? "");

    if (shouldUpdateEmailReview && !reviewEmail && !lead.email) {
      setRowMessage("Review-E-Mail setzen, um Kontaktinfos zu ändern.");
      return;
    }

    const payload = {
      id: lead._id,
      priority: draft.priority,
      priorityReason: draft.priorityReason,
      contactStatus: draft.contactStatus,
      contactStatusReason: draft.contactStatusReason,
      notes: draft.notes,
      duplicateStatus: draft.duplicateStatus,
      duplicateReason: lead.duplicateReason,
      blacklistStatus: draft.blacklistStatus,
      blacklistReason: lead.blacklistReason,
      reviewIsBusinessContactAddress: draft.reviewIsBusinessContactAddress,
      ...(shouldUpdateEmailReview ? {
        reviewEmail: reviewEmail ?? lead.email,
        reviewEmailSource: reviewEmailSource ?? lead.emailSource,
        reviewContactPerson,
      } : {}),
    };

    await update(payload);
  };

  const blockLead = async () => {
    setIsBlocking(true);
    await update({ applyBlacklist: true });
    setIsBlocking(false);
  };

  const updateDraft = <T extends keyof LeadReviewDraft>(
    field: T,
    value: LeadReviewDraft[T],
  ) => {
    setDraft((current) => ({ ...current, [field]: value }));
  };

  return (
    <tr className="border-t">
      <td className="max-w-[260px] p-3 align-top">
        <p className="font-medium">{lead.companyName}</p>
        <p className="mt-1 inline-flex items-center gap-1 truncate text-xs text-muted-foreground">
          <Building2 className="size-3 shrink-0" />
          <span className="truncate">{lead.niche ?? "Nische offen"}</span>
        </p>
        <p className="mt-2 inline-flex items-center gap-1 text-xs text-muted-foreground">
          <MapPin className="size-3 shrink-0" />
          <span>{location}</span>
        </p>
        {lead.address ? (
          <p className="mt-1 max-w-full truncate text-xs text-muted-foreground">
            {lead.address}
          </p>
        ) : null}
      </td>

      <td className="max-w-[260px] p-3 align-top">
        <p className="inline-flex w-full items-start gap-1 text-sm">
          <Mail className="mt-0.5 size-3 shrink-0" />
          <span className="min-w-0 break-all">
            {lead.email || "Keine E-Mail"}
          </span>
        </p>
        {lead.phone ? (
          <p className="mt-2 inline-flex w-full items-start gap-1 text-xs text-muted-foreground">
            <Phone className="size-3 shrink-0" />
            <span className="break-all">{lead.phone}</span>
          </p>
        ) : null}
        <p className="mt-2 text-xs text-muted-foreground">
          Quelle: {contactSourceLabel(lead)}
        </p>
        {lead.websiteDomain ? (
          <p className="mt-1 text-xs text-muted-foreground">
            Domain: {lead.websiteDomain}
          </p>
        ) : null}
      </td>

      <td className="p-3 align-top">
        <p
          className={`inline-flex rounded-md border px-2 py-1 text-xs font-medium ${priorityBadgeClass(
            draft.priority,
          )}`}
        >
          {getLeadPriorityLabel(draft.priority)}
        </p>
        <div className="mt-2 max-w-[160px]">
          <Select
            value={draft.priority}
            onValueChange={(nextPriority) =>
              updateDraft("priority", nextPriority as LeadPriority)
            }
          >
            <SelectTrigger>
              <SelectValue placeholder="Priorität" />
            </SelectTrigger>
            <SelectContent>
              {leadPriorityOptions.map((value) => (
                <SelectItem value={value} key={value}>
                  {getLeadPriorityLabel(value)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </td>

      <td className="p-3 align-top">
        <Badge variant="outline">
          {getLeadContactStatusLabel(draft.contactStatus)}
        </Badge>
        <div className="mt-2 max-w-[180px]">
          <Select
            value={draft.contactStatus}
            onValueChange={(nextStatus) =>
              updateDraft("contactStatus", nextStatus as LeadContactStatus)
            }
          >
            <SelectTrigger>
              <SelectValue placeholder="Kontaktstatus" />
            </SelectTrigger>
            <SelectContent>
              {leadContactStatusOptions.map((status) => (
                <SelectItem value={status} key={status}>
                  {getLeadContactStatusLabel(status)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </td>

      <td className="max-w-[220px] p-3 align-top">
        <div className="grid gap-2">
          <p className="text-xs text-muted-foreground">Prioritätsgrund</p>
          <Input
            value={draft.priorityReason}
            onChange={(event) => {
              updateDraft("priorityReason", event.target.value);
            }}
          />
        </div>
        <div className="mt-2 grid gap-2">
          <p className="text-xs text-muted-foreground">Kontaktstatus-Notiz</p>
          <Input
            value={draft.contactStatusReason}
            onChange={(event) => {
              updateDraft("contactStatusReason", event.target.value);
            }}
          />
        </div>
        <div className="mt-2 grid gap-2">
          <p className="text-xs text-muted-foreground">Notiz</p>
          <Input
            value={draft.notes}
            onChange={(event) => {
              updateDraft("notes", event.target.value);
            }}
          />
        </div>

        <div className="mt-3 flex flex-wrap gap-2">
          <Badge
            variant={duplicateBadgeVariant(draft.duplicateStatus)}
            title={lead.duplicateReason ?? undefined}
          >
            {getLeadDuplicateStatusLabel(draft.duplicateStatus)}
          </Badge>

          <Badge
            variant={lead.blacklistStatus === "blocked" ? "destructive" : "secondary"}
          >
            {getLeadBlacklistStatusLabel(lead.blacklistStatus)}
          </Badge>
        </div>

        <div className="mt-2 space-y-1 text-xs text-muted-foreground">
          {reasonParts.length === 0 ? (
            <p>Keine Zusatzhinweise</p>
          ) : (
            reasonParts.map((reason) => <p key={reason}>• {reason}</p>)
          )}
        </div>
      </td>

      <td className="min-w-[260px] p-3 align-top">
        <div className="grid gap-2">
          <p className="text-xs text-muted-foreground">Review-E-Mail</p>
          <Input
            value={draft.reviewEmail}
            onChange={(event) => {
              updateDraft("reviewEmail", event.target.value);
            }}
          />
        </div>

        <div className="mt-2 grid gap-2">
          <p className="text-xs text-muted-foreground">Review-Quelle</p>
          <Input
            value={draft.reviewEmailSource}
            onChange={(event) => {
              updateDraft("reviewEmailSource", event.target.value);
            }}
          />
        </div>

        <div className="mt-2 grid gap-2">
          <p className="text-xs text-muted-foreground">Ansprechperson</p>
          <Input
            value={draft.reviewContactPerson}
            onChange={(event) => {
              updateDraft("reviewContactPerson", event.target.value);
            }}
          />
        </div>

        <label className="mt-3 inline-flex items-center gap-2 text-xs text-muted-foreground">
          <Switch
            checked={draft.reviewIsBusinessContactAddress}
            onCheckedChange={(checked) => {
              updateDraft("reviewIsBusinessContactAddress", checked);
            }}
          />
          Genannte E-Mail als Business-Kontakt
        </label>

        <div className="mt-3 grid gap-2">
          <p className="text-xs text-muted-foreground">Duplikatstatus</p>
          <Select
            value={draft.duplicateStatus}
            onValueChange={(nextStatus) =>
              updateDraft("duplicateStatus", nextStatus as LeadDuplicateStatus)
            }
          >
            <SelectTrigger>
              <SelectValue placeholder="Duplikatstatus" />
            </SelectTrigger>
            <SelectContent>
              {leadDuplicateStatusOptions.map((status) => (
                <SelectItem value={status} key={status}>
                  {getLeadDuplicateStatusLabel(status)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        <div className="mt-2">
          <label className="text-xs text-muted-foreground">Sperrstatus</label>
          <Select
            value={draft.blacklistStatus}
            onValueChange={(nextStatus) =>
              updateDraft("blacklistStatus", nextStatus as LeadBlacklistStatus)
            }
          >
            <SelectTrigger>
              <SelectValue placeholder="Sperrstatus" />
            </SelectTrigger>
            <SelectContent>
              {leadBlacklistStatusOptions.map((status) => (
                <SelectItem value={status} key={status}>
                  {getLeadBlacklistStatusLabel(status)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </td>

      <td className="max-w-[170px] p-3 align-top">
        <div className="grid gap-2">
          <Button
            onClick={saveRow}
            disabled={isSaving || isBlocking}
            size="sm"
          >
            <span>Speichern</span>
          </Button>

          <Button
            variant="destructive"
            onClick={blockLead}
            disabled={isSaving || isBlocking}
            size="sm"
          >
            <ShieldAlert className="size-4" />
            Sperren
          </Button>
        </div>

        {rowMessage ? (
          <p className="mt-2 text-xs text-muted-foreground">{rowMessage}</p>
        ) : null}
      </td>
    </tr>
  );
}
