"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, CardHeader } 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 grid w-full max-w-7xl gap-3">
        {leads === undefined ? (
          <p className="rounded-md bg-muted p-4 text-sm">Leads werden geladen…</p>
        ) : sortedLeads.length === 0 ? (
          <p className="rounded-md border p-4 text-sm text-muted-foreground">
            Keine Leads vorhanden. Bitte zuerst eine Kampagne starten oder
            importieren.
          </p>
        ) : (
          sortedLeads.map((lead) => (
            <LeadReviewRow
              key={lead._id}
              lead={lead}
              onActionMessage={setActionMessage}
            />
          ))
        )}
      </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 [isExpanded, setIsExpanded] = useState(false);
  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 }));
  };

  const detailsId = `lead-review-details-${lead._id}`;

  return (
    <Card>
      <CardHeader className="pb-3">
        <div className="grid min-w-0 gap-2">
          <div className="flex min-w-0 flex-wrap items-start justify-between gap-2">
            <div className="min-w-0 flex-1">
              <p className="max-w-full truncate font-medium">
                {lead.companyName}
              </p>
              <p className="mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground">
                <Building2 className="size-3 shrink-0" />
                <span className="inline-flex min-w-0 max-w-full break-words">
                  {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 className="inline-flex min-w-0 max-w-full truncate">
                  {location}
                </span>
              </p>
            </div>

            <p
              className={`inline-flex shrink-0 rounded-md border px-2 py-1 text-xs font-medium ${priorityBadgeClass(
                draft.priority,
              )}`}
            >
              {getLeadPriorityLabel(draft.priority)}
            </p>
          </div>

          <div className="grid min-w-0 gap-1 text-xs text-muted-foreground">
            <p className="inline-flex min-w-0 items-center gap-1">
              <Mail className="size-3 shrink-0" />
              <span className="max-w-full min-w-0 break-all">
                {lead.email || "Keine E-Mail"}
              </span>
            </p>
            {lead.phone ? (
              <p className="inline-flex min-w-0 items-center gap-1">
                <Phone className="size-3 shrink-0" />
                <span className="max-w-full min-w-0 break-all">{lead.phone}</span>
              </p>
            ) : null}
            <p className="truncate max-w-full">
              Quelle: {contactSourceLabel(lead)}
            </p>
            {lead.websiteDomain ? (
              <p className="truncate max-w-full">Domain: {lead.websiteDomain}</p>
            ) : null}
          </div>
        </div>
      </CardHeader>

      <div className="border-t p-4 pt-3">
        <Button
          type="button"
          variant="outline"
          onClick={() => setIsExpanded((previous) => !previous)}
          aria-expanded={isExpanded}
          aria-controls={detailsId}
          size="sm"
        >
          {isExpanded ? "Weniger anzeigen" : "Mehr anzeigen"}
        </Button>
      </div>

      <div
        id={detailsId}
        className="grid gap-3 border-t p-4"
        hidden={!isExpanded}
      >
        <div className="grid gap-3 xl:grid-cols-2">
          <section className="grid gap-2">
            <div>
              <p className="text-xs text-muted-foreground">Priorität</p>
              <div className="mt-2">
                <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>
            </div>

            <div>
              <p className="text-xs text-muted-foreground">Kontaktstatus</p>
              <div className="mt-2">
                <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>
            </div>
          </section>

          <section className="grid gap-2">
            <div>
              <p className="text-xs text-muted-foreground">Prioritätsgrund</p>
              <Input
                value={draft.priorityReason}
                onChange={(event) => {
                  updateDraft("priorityReason", event.target.value);
                }}
              />
            </div>
            <div>
              <p className="mt-2 text-xs text-muted-foreground">
                Kontaktstatus-Notiz
              </p>
              <Input
                value={draft.contactStatusReason}
                onChange={(event) => {
                  updateDraft("contactStatusReason", event.target.value);
                }}
              />
            </div>
            <div>
              <p className="mt-2 text-xs text-muted-foreground">Notiz</p>
              <Input
                value={draft.notes}
                onChange={(event) => {
                  updateDraft("notes", event.target.value);
                }}
              />
            </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>
          </section>

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

            <div>
              <p className="mt-2 text-xs text-muted-foreground">Review-Quelle</p>
              <Input
                value={draft.reviewEmailSource}
                onChange={(event) => {
                  updateDraft("reviewEmailSource", event.target.value);
                }}
              />
            </div>
            <div>
              <p className="mt-2 text-xs text-muted-foreground">Ansprechperson</p>
              <Input
                value={draft.reviewContactPerson}
                onChange={(event) => {
                  updateDraft("reviewContactPerson", event.target.value);
                }}
              />
            </div>
            <label className="mt-2 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>
          </section>

          <section className="grid gap-2">
            <div>
              <p className="text-xs text-muted-foreground">Duplikatstatus</p>
              <div className="mt-2">
                <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>

            <div>
              <label className="text-xs text-muted-foreground">Sperrstatus</label>
              <div className="mt-2">
                <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>
            </div>

            <div className="mt-2 grid gap-2 sm:grid-cols-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 grid gap-2 sm:grid-cols-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="text-xs text-muted-foreground">{rowMessage}</p>
            ) : null}
          </section>
        </div>
      </div>
    </Card>
  );
}
