"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import {
  CheckSquare,
  FileSpreadsheet,
  Megaphone,
  Plus,
  Search,
  Square,
  Upload,
  UserRoundPlus,
} from "lucide-react";
import { toast } from "sonner";

import { CallCenterAPI } from "@/apis/CallCenterAPI";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useCompanyStore } from "@/hooks/store/useCompanyStore";
import { createPanelPageUrl } from "@/utils";

const OPEN_STATUSES = ["abierto"];
const CAMPAIGN_STATUSES = ["en_campana"];
const WORK_STATUSES = ["en_proceso", "pendiente_cliente"];
const DONE_STATUSES = ["resuelto", "cerrado"];

const parseCsvRows = (text) => {
  const lines = String(text || "")
    .replace(/^\uFEFF/, "")
    .split(/\r?\n/)
    .map((line) => line.trim())
    .filter(Boolean);
  if (!lines.length) return [];

  const delimiter = lines[0].includes(";") ? ";" : ",";
  const cells = (line) => line.split(delimiter).map((cell) => cell.trim().replace(/^"|"$/g, ""));
  const header = cells(lines[0]).map((cell) => cell.toLowerCase());
  const nameIdx = header.findIndex((cell) => ["nombre", "name", "contact_name"].includes(cell));
  const phoneIdx = header.findIndex((cell) => ["telefono", "teléfono", "phone", "contact_phone"].includes(cell));
  const emailIdx = header.findIndex((cell) => ["correo", "email", "contact_email"].includes(cell));
  const start = nameIdx >= 0 ? 1 : 0;

  return lines.slice(start).map((line) => {
    const cols = cells(line);
    return {
      contact_name: cols[nameIdx >= 0 ? nameIdx : 0] || "",
      contact_phone: cols[phoneIdx >= 0 ? phoneIdx : 1] || "",
      contact_email: cols[emailIdx >= 0 ? emailIdx : 2] || "",
    };
  }).filter((row) => row.contact_name || row.contact_phone);
};

const statusTone = (status) => {
  if (OPEN_STATUSES.includes(status)) return "bg-sky-100 text-sky-800";
  if (CAMPAIGN_STATUSES.includes(status)) return "bg-violet-100 text-violet-800";
  if (WORK_STATUSES.includes(status)) return "bg-amber-100 text-amber-800";
  return "bg-emerald-100 text-emerald-800";
};

const statusLabel = (status) => {
  if (status === "abierto") return "Nuevo";
  if (status === "en_campana") return "En campaña";
  if (status === "en_proceso") return "Contactado";
  if (status === "pendiente_cliente") return "Contactado";
  if (status === "resuelto" || status === "cerrado") return "Incorporado";
  return status;
};

const isInCampaign = (ticket) =>
  CAMPAIGN_STATUSES.includes(ticket.status) || (ticket.status === "abierto" && Boolean(ticket.campaign_name));

export default function Reingresos() {
  const router = useRouter();
  const { selectedCompany } = useCompanyStore();
  const idcompany = selectedCompany?.id;
  const fileRef = useRef(null);

  const [rows, setRows] = useState([]);
  const [search, setSearch] = useState("");
  const [selected, setSelected] = useState([]);
  const [createOpen, setCreateOpen] = useState(false);
  const [campaignOpen, setCampaignOpen] = useState(false);
  const [campaignName, setCampaignName] = useState("");
  const [name, setName] = useState("");
  const [phone, setPhone] = useState("");
  const [email, setEmail] = useState("");
  const [saving, setSaving] = useState(false);

  const load = async () => {
    if (!idcompany) return;
    const result = await CallCenterAPI.getAll({ idcompany, type: "reingreso", per_page: 200 });
    setRows(result.tickets || []);
  };

  useEffect(() => {
    void load();
  }, [idcompany]);

  const filtered = useMemo(() => {
    const term = search.trim().toLowerCase();
    if (!term) return rows;
    return rows.filter((ticket) =>
      [ticket.contact_name, ticket.contact_phone, ticket.contact_email, ticket.ticket_number, ticket.subject]
        .filter(Boolean)
        .some((value) => String(value).toLowerCase().includes(term))
    );
  }, [rows, search]);

  const kpis = useMemo(() => {
    return {
      nuevos: rows.filter((ticket) => OPEN_STATUSES.includes(ticket.status) && !ticket.campaign_name).length,
      campana: rows.filter((ticket) => isInCampaign(ticket)).length,
      trabajo: rows.filter((ticket) => WORK_STATUSES.includes(ticket.status)).length,
      incorporados: rows.filter((ticket) => DONE_STATUSES.includes(ticket.status)).length,
    };
  }, [rows]);

  const columns = useMemo(() => ({
    abierto: filtered.filter((ticket) => OPEN_STATUSES.includes(ticket.status) && !ticket.campaign_name),
    campana: filtered.filter((ticket) => isInCampaign(ticket)),
    trabajo: filtered.filter((ticket) => WORK_STATUSES.includes(ticket.status)),
    hecho: filtered.filter((ticket) => DONE_STATUSES.includes(ticket.status)),
  }), [filtered]);

  const toggleSelect = (id) => {
    setSelected((current) =>
      current.includes(id) ? current.filter((value) => value !== id) : [...current, id]
    );
  };

  const submitOne = async (event) => {
    event.preventDefault();
    if (!idcompany) {
      toast.error("Selecciona una empresa.");
      return;
    }
    if (!name.trim() || !phone.trim()) {
      toast.error("Nombre y teléfono son obligatorios. El RUT no se pide.");
      return;
    }
    setSaving(true);
    try {
      const created = await CallCenterAPI.create({
        idcompany,
        type: "reingreso",
        channel: "telefono_entrante",
        priority: "medium",
        contact_name: name.trim(),
        contact_phone: phone.trim(),
        contact_email: email.trim() || undefined,
        subject: `Reingreso: ${name.trim()}`,
      });
      toast.success(`Reingreso ${created.ticket_number} en la cola de Incorporaciones.`);
      setName("");
      setPhone("");
      setEmail("");
      setCreateOpen(false);
      await load();
    } catch {
      toast.error("No se pudo crear el reingreso.");
    } finally {
      setSaving(false);
    }
  };

  const downloadTemplate = () => {
    const csv = "nombre,telefono,correo\nAna Perez,+56911111111,ana@correo.cl\n";
    const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = "plantilla-reingresos.csv";
    link.click();
    URL.revokeObjectURL(url);
  };

  const onCsvFile = async (event) => {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file || !idcompany) return;
    const text = await file.text();
    const parsed = parseCsvRows(text);
    if (!parsed.length) {
      toast.error("El archivo no tiene filas válidas (nombre, teléfono, correo).");
      return;
    }
    setSaving(true);
    try {
      const result = await CallCenterAPI.importReingresos({ idcompany, rows: parsed });
      toast.success(`${result.created_count || 0} reingreso(s) cargados.`);
      if (result.error_count) {
        toast.error(`${result.error_count} fila(s) no se pudieron cargar.`);
      }
      await load();
    } catch {
      toast.error("No se pudo importar el archivo.");
    } finally {
      setSaving(false);
    }
  };

  const markAllNew = () => {
    setSelected(columns.abierto.map((ticket) => ticket.id));
  };

  const unmarkAll = () => setSelected([]);

  const openCampaignDialog = () => {
    if (!selected.length) {
      toast.error("Marca una o más personas y luego crea la campaña.");
      return;
    }
    setCampaignName("");
    setCampaignOpen(true);
  };

  const createCampaign = async (event) => {
    event.preventDefault();
    if (!idcompany || !selected.length) {
      toast.error("Marca una o más personas y luego crea la campaña.");
      return;
    }
    if (!campaignName.trim()) {
      toast.error("Ponle un nombre a la campaña.");
      return;
    }
    setSaving(true);
    try {
      const campaign = await CallCenterAPI.campaignFromReingresos({
        idcompany,
        ticket_ids: selected,
        name: campaignName.trim(),
      });
      toast.success(`Campaña “${campaign.name}” lista en Campañas.`);
      setSelected([]);
      setCampaignOpen(false);
      router.push(createPanelPageUrl("Campaigns"));
    } catch {
      toast.error("No se pudo generar la campaña.");
    } finally {
      setSaving(false);
    }
  };

  const selectedPeople = useMemo(
    () => rows.filter((ticket) => selected.includes(ticket.id)),
    [rows, selected]
  );

  const renderCard = (ticket) => {
    const included = selected.includes(ticket.id);
    return (
    <Card key={ticket.id} className="border-slate-200/80 shadow-sm">
      <CardContent className="p-4 space-y-3">
        <div className="flex items-start justify-between gap-3">
          <span className="min-w-0">
            <p className="font-semibold truncate">{ticket.contact_name || ticket.subject}</p>
            <p className="text-xs text-slate-500">{ticket.ticket_number}</p>
          </span>
          <Badge className={statusTone(isInCampaign(ticket) ? "en_campana" : ticket.status)}>
            {statusLabel(isInCampaign(ticket) ? "en_campana" : ticket.status)}
          </Badge>
        </div>
        <p className="text-sm text-slate-600">
          {ticket.contact_phone || "Sin teléfono"}
          {ticket.contact_email ? ` · ${ticket.contact_email}` : ""}
        </p>
        {ticket.status === "abierto" && !ticket.campaign_name && (
          <Button size="sm" variant="outline" disabled={saving} onClick={() => toggleSelect(ticket.id)}>
            {included ? <CheckSquare className="w-3.5 h-3.5 mr-1" /> : <Square className="w-3.5 h-3.5 mr-1" />}
            {included ? "Quitar de la lista" : "Marcar para campaña nueva"}
          </Button>
        )}
        {isInCampaign(ticket) && (
          <p className="text-sm text-violet-800">
            En campaña: <span className="font-medium">{ticket.campaign_name || "Campaña asignada"}</span>
          </p>
        )}
        {(ticket.call_log?.typification_code || ticket.call_log?.observation) && (
          <div className="rounded-lg border border-slate-100 bg-slate-50 px-2.5 py-2">
            {ticket.call_log?.typification_code ? (
              <p className="text-xs font-medium text-slate-700">
                {String(ticket.call_log.typification_code).replace(/_/g, " ")}
              </p>
            ) : null}
            {ticket.call_log?.observation ? (
              <p className="mt-0.5 text-xs text-slate-600 whitespace-pre-wrap">{ticket.call_log.observation}</p>
            ) : null}
          </div>
        )}
        {WORK_STATUSES.includes(ticket.status) && !ticket.call_log?.observation && (
          <p className="text-xs text-slate-400">
            Contactado desde Campañas. Incorporado se marca allá, después del llamado.
          </p>
        )}
        {DONE_STATUSES.includes(ticket.status) && ticket.campaign_name && (
          <p className="text-xs text-slate-400">Campaña: {ticket.campaign_name}</p>
        )}
      </CardContent>
    </Card>
    );
  };

  return (
    <div className="p-6 space-y-6">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
        <div>
          <h1 className="text-3xl font-bold text-gradient flex items-center gap-2">
            <UserRoundPlus className="w-8 h-8" />
            Reingresos
          </h1>
          <p className="text-slate-600 mt-1 max-w-2xl">
            Nuevos se marcan para una sola campaña y pasan a En campaña. El llamado
            y Incorporado se hacen después, en esa campaña.
          </p>
        </div>
        <div className="flex flex-wrap gap-2">
          <Button variant="outline" onClick={downloadTemplate}>
            <FileSpreadsheet className="w-4 h-4 mr-2" />
            Plantilla CSV
          </Button>
          <Button variant="outline" onClick={() => fileRef.current?.click()} disabled={saving}>
            <Upload className="w-4 h-4 mr-2" />
            Cargar masivo
          </Button>
          <input ref={fileRef} type="file" accept=".csv,text/csv" className="hidden" onChange={onCsvFile} />
          <Button onClick={() => setCreateOpen(true)}>
            <Plus className="w-4 h-4 mr-2" />
            Nuevo reingreso
          </Button>
        </div>
      </div>

      {selected.length > 0 && (
        <div className="sticky top-0 z-10 flex flex-col gap-3 rounded-xl border border-violet-200 bg-violet-50 px-4 py-3 sm:flex-row sm:items-center sm:justify-between">
          <div className="min-w-0">
            <p className="font-medium text-violet-900">
              {selected.length} {selected.length === 1 ? "persona marcada" : "personas marcadas"} para una campaña nueva
            </p>
            <p className="truncate text-sm text-violet-700">
              {selectedPeople.map((ticket) => ticket.contact_name || ticket.ticket_number).join(", ")}
            </p>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" onClick={unmarkAll}>
              Quitar marcas
            </Button>
            <Button onClick={openCampaignDialog} disabled={saving}>
              <Megaphone className="w-4 h-4 mr-2" />
              Crear campaña
            </Button>
          </div>
        </div>
      )}

      <div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-3">
        <Card className="bg-sky-50 border-sky-100">
          <CardHeader className="pb-2">
            <CardTitle className="text-sm text-sky-800">Nuevos</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-sky-900">{kpis.nuevos}</CardContent>
        </Card>
        <Card className="bg-violet-50 border-violet-100">
          <CardHeader className="pb-2">
            <CardTitle className="text-sm text-violet-800">En campaña</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-violet-900">{kpis.campana}</CardContent>
        </Card>
        <Card className="bg-amber-50 border-amber-100">
          <CardHeader className="pb-2">
            <CardTitle className="text-sm text-amber-800">Contactados</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-amber-900">{kpis.trabajo}</CardContent>
        </Card>
        <Card className="bg-emerald-50 border-emerald-100">
          <CardHeader className="pb-2">
            <CardTitle className="text-sm text-emerald-800">Incorporados</CardTitle>
          </CardHeader>
          <CardContent className="text-3xl font-bold text-emerald-900">{kpis.incorporados}</CardContent>
        </Card>
      </div>

      <div className="relative max-w-md">
        <Search className="w-4 h-4 absolute left-3 top-3 text-slate-400" />
        <Input className="pl-9" placeholder="Buscar por nombre, teléfono o folio" value={search} onChange={(event) => setSearch(event.target.value)} />
      </div>

      <div className="grid lg:grid-cols-2 xl:grid-cols-4 gap-4">
        <section className="space-y-3">
          <div className="flex items-center justify-between gap-2">
            <h2 className="font-semibold text-slate-700">Nuevos ({columns.abierto.length})</h2>
            {columns.abierto.length > 0 && (
              <Button size="sm" variant="outline" onClick={markAllNew}>
                Marcar todos
              </Button>
            )}
          </div>
          {columns.abierto.map(renderCard)}
          {!columns.abierto.length && <p className="text-sm text-slate-400">Nadie nuevo en cola.</p>}
        </section>
        <section className="space-y-3">
          <h2 className="font-semibold text-slate-700">En campaña ({columns.campana.length})</h2>
          {columns.campana.map(renderCard)}
          {!columns.campana.length && <p className="text-sm text-slate-400">Nadie asignado a una campaña.</p>}
        </section>
        <section className="space-y-3">
          <h2 className="font-semibold text-slate-700">Contactados ({columns.trabajo.length})</h2>
          {columns.trabajo.map(renderCard)}
          {!columns.trabajo.length && <p className="text-sm text-slate-400">Nadie contactado desde Campañas.</p>}
        </section>
        <section className="space-y-3">
          <h2 className="font-semibold text-slate-700">Incorporados ({columns.hecho.length})</h2>
          {columns.hecho.map(renderCard)}
          {!columns.hecho.length && <p className="text-sm text-slate-400">Aún no hay incorporaciones.</p>}
        </section>
      </div>

      <Dialog open={campaignOpen} onOpenChange={setCampaignOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Nombre de la campaña</DialogTitle>
            <DialogDescription>
              {selected.length} {selected.length === 1 ? "reingreso nuevo" : "reingresos nuevos"} pasarán a esta campaña.
              El trabajo (llamado e incorporado) se hace después, en Campañas.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={createCampaign} className="space-y-3">
            <div>
              <Label>Nombre</Label>
              <Input
                value={campaignName}
                onChange={(event) => setCampaignName(event.target.value)}
                placeholder="Ej: Reingresos octubre"
                required
              />
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setCampaignOpen(false)}>
                Cancelar
              </Button>
              <Button type="submit" disabled={saving}>
                Crear campaña
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Nuevo reingreso</DialogTitle>
            <DialogDescription>
              Alta uno a uno, como en la llamada. Nombre y teléfono bastan. El RUT no se exige.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={submitOne} className="space-y-3">
            <div>
              <Label>Nombre</Label>
              <Input value={name} onChange={(event) => setName(event.target.value)} required />
            </div>
            <div>
              <Label>Teléfono</Label>
              <Input value={phone} onChange={(event) => setPhone(event.target.value)} required />
            </div>
            <div>
              <Label>Correo (opcional)</Label>
              <Input type="email" value={email} onChange={(event) => setEmail(event.target.value)} />
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setCreateOpen(false)}>
                Cancelar
              </Button>
              <Button type="submit" disabled={saving}>
                Crear reingreso
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}
