"use client";

import { useEffect, useMemo, useState, useTransition } from "react";
import { createPortal } from "react-dom";
import { useRouter } from "next/navigation";
import { Printer, Search } from "lucide-react";

export type PrintTicketRow = {
  id: string;
  ticketNum: string;
  createdAt: string;
  createdAtLabel: string;
  orderId: string;
  name: string;
  phone: string;
  email: string;
};

type Props = {
  initialTickets: PrintTicketRow[];
  initialFrom: string;
  initialTo: string;
  initialQuery: string;
  truncated: boolean;
  maxTickets: number;
  maxRangeDays: number;
};

type PrintFields = {
  name: boolean;
  ticketNum: boolean;
  phone: boolean;
  email: boolean;
};

const DEFAULT_PRINT_FIELDS: PrintFields = {
  name: true,
  ticketNum: true,
  phone: true,
  email: false,
};

const PRINT_COLS = 4;

function toRows<T>(items: T[], cols: number): T[][] {
  const rows: T[][] = [];
  for (let i = 0; i < items.length; i += cols) {
    rows.push(items.slice(i, i + cols));
  }
  return rows;
}

function TicketCard({
  t,
  printFields,
}: {
  t: PrintTicketRow;
  printFields: PrintFields;
}) {
  return (
    <div className="print-ticket-card">
      {printFields.name && <div className="print-ticket-name">{t.name}</div>}
      {printFields.ticketNum && (
        <div className="print-ticket-code">{t.ticketNum}</div>
      )}
      {printFields.phone && <div className="print-ticket-phone">{t.phone}</div>}
      {printFields.email && <div className="print-ticket-email">{t.email}</div>}
    </div>
  );
}

export default function AdminPrintTicketsClient({
  initialTickets,
  initialFrom,
  initialTo,
  initialQuery,
  truncated,
  maxTickets,
  maxRangeDays,
}: Props) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [mounted, setMounted] = useState(false);
  const [query, setQuery] = useState(initialQuery);
  const [dateFrom, setDateFrom] = useState(initialFrom);
  const [dateTo, setDateTo] = useState(initialTo);
  const [printFields, setPrintFields] = useState<PrintFields>(DEFAULT_PRINT_FIELDS);

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    setDateFrom(initialFrom);
    setDateTo(initialTo);
    setQuery(initialQuery);
  }, [initialFrom, initialTo, initialQuery]);

  const hasAnyPrintField =
    printFields.name || printFields.ticketNum || printFields.phone || printFields.email;

  const previewTickets = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return initialTickets;
    const digits = q.replace(/\D/g, "");
    return initialTickets.filter((t) => {
      if (t.email.toLowerCase().includes(q)) return true;
      if (digits.length >= 3 && t.phone.replace(/\D/g, "").includes(digits)) return true;
      if (t.phone.toLowerCase().includes(q)) return true;
      if (t.name.toLowerCase().includes(q)) return true;
      if (t.ticketNum.toLowerCase().includes(q)) return true;
      return false;
    });
  }, [initialTickets, query]);

  const printRows = useMemo(
    () => toRows(previewTickets, PRINT_COLS),
    [previewTickets]
  );

  const applyDates = () => {
    if (!dateFrom || !dateTo) return;
    const params = new URLSearchParams();
    params.set("from", dateFrom);
    params.set("to", dateTo);
    startTransition(() => {
      router.push(`/admin/print-tickets?${params.toString()}`);
    });
  };

  const handlePrint = () => {
    if (previewTickets.length === 0 || !hasAnyPrintField) return;
    window.print();
  };

  // Tabla + page-break-inside:avoid en cada fila → el navegador no parte tickets
  const printStyles = `
    #print-tickets-root { display: none; }

    @media print {
      @page {
        size: A4 portrait;
        margin: 8mm;
      }

      html, body {
        margin: 0 !important;
        padding: 0 !important;
        background: #fff !important;
        color: #000 !important;
        height: auto !important;
        overflow: visible !important;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
      }

      body > *:not(#print-tickets-root) {
        display: none !important;
      }

      #print-tickets-root {
        display: block !important;
        width: 100% !important;
        margin: 0 !important;
        padding: 0 !important;
        background: #fff !important;
        color: #000 !important;
      }

      #print-tickets-root .print-tickets-table {
        width: 100% !important;
        border-collapse: collapse !important;
        table-layout: fixed !important;
      }

      #print-tickets-root .print-tickets-table tr {
        page-break-inside: avoid !important;
        break-inside: avoid !important;
      }

      #print-tickets-root .print-tickets-table td {
        width: 25% !important;
        vertical-align: top !important;
        padding: 1.5mm !important;
        page-break-inside: avoid !important;
        break-inside: avoid !important;
      }

      #print-tickets-root .print-pad-cell {
        border: none !important;
        padding: 1.5mm !important;
      }

      #print-tickets-root .print-ticket-card {
        border: 1.25px solid #111 !important;
        border-radius: 2px !important;
        padding: 2mm 1.5mm !important;
        height: 26mm !important;
        box-sizing: border-box !important;
        display: flex !important;
        flex-direction: column !important;
        justify-content: space-evenly !important;
        text-align: center !important;
        overflow: hidden !important;
        page-break-inside: avoid !important;
        break-inside: avoid !important;
        background: #fff !important;
        color: #000 !important;
      }

      #print-tickets-root .print-ticket-name {
        font-size: 9px !important;
        font-weight: 700 !important;
        text-transform: uppercase !important;
        line-height: 1.15 !important;
        max-height: 2.3em !important;
        overflow: hidden !important;
      }

      #print-tickets-root .print-ticket-code {
        font-size: 11px !important;
        font-weight: 900 !important;
        font-family: ui-monospace, Menlo, Consolas, monospace !important;
        letter-spacing: 0.04em !important;
        white-space: nowrap !important;
      }

      #print-tickets-root .print-ticket-phone {
        font-size: 10px !important;
        font-weight: 600 !important;
        font-family: ui-monospace, Menlo, Consolas, monospace !important;
        white-space: nowrap !important;
      }

      #print-tickets-root .print-ticket-email {
        font-size: 7.5px !important;
        font-weight: 600 !important;
        line-height: 1.1 !important;
        word-break: break-all !important;
        max-height: 2.2em !important;
        overflow: hidden !important;
      }
    }
  `;

  const printPortal =
    mounted &&
    createPortal(
      <>
        <style>{printStyles}</style>
        <div id="print-tickets-root" aria-hidden>
          <table className="print-tickets-table">
            <tbody>
              {printRows.map((row, ri) => (
                <tr key={`print-row-${ri}`}>
                  {row.map((t) => (
                    <td key={t.id}>
                      <TicketCard t={t} printFields={printFields} />
                    </td>
                  ))}
                  {row.length < PRINT_COLS &&
                    Array.from({ length: PRINT_COLS - row.length }).map((_, i) => (
                      <td key={`pad-${ri}-${i}`} className="print-pad-cell" />
                    ))}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </>,
      document.body
    );

  return (
    <>
      {printPortal}

      <div className="space-y-6">
        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
          <div>
            <h1 className="text-3xl font-bold flex items-center gap-3">
              <Printer className="text-neon-blue w-8 h-8" />
              Imprimir tickets
            </h1>
            <p className="text-gray-400 mt-1 text-sm">
              Vista previa abajo. Al imprimir solo salen los tickets.
            </p>
          </div>
          <button
            type="button"
            onClick={handlePrint}
            disabled={previewTickets.length === 0 || !hasAnyPrintField}
            className="inline-flex items-center justify-center gap-2 bg-[#0ea5e9] hover:bg-[#0284c7] disabled:opacity-40 disabled:cursor-not-allowed text-white font-bold py-3 px-5 rounded-xl transition"
          >
            <Printer className="w-5 h-5" />
            Imprimir ({previewTickets.length})
          </button>
        </div>

        {truncated && (
          <div className="rounded-xl border border-yellow-500/30 bg-yellow-500/10 px-4 py-3 text-sm text-yellow-200">
            Límite de {maxTickets} tickets. Reduce fechas (máx. {maxRangeDays} días).
          </div>
        )}

        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
          <div className="sm:col-span-2">
            <label className="block text-xs text-gray-500 mb-1">
              Filtrar vista previa (teléfono o correo)
            </label>
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-500" />
              <input
                type="search"
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="Escribe teléfono o correo…"
                maxLength={120}
                className="w-full pl-10 pr-3 py-2.5 rounded-xl bg-black/40 border border-white/10 text-sm focus:outline-none focus:border-neon-blue/50"
              />
            </div>
          </div>
          <div>
            <label className="block text-xs text-gray-500 mb-1">Desde</label>
            <input
              type="date"
              value={dateFrom}
              onChange={(e) => setDateFrom(e.target.value)}
              className="w-full px-3 py-2.5 rounded-xl bg-black/40 border border-white/10 text-sm focus:outline-none focus:border-neon-blue/50"
            />
          </div>
          <div>
            <label className="block text-xs text-gray-500 mb-1">Hasta</label>
            <div className="flex gap-2">
              <input
                type="date"
                value={dateTo}
                onChange={(e) => setDateTo(e.target.value)}
                className="w-full px-3 py-2.5 rounded-xl bg-black/40 border border-white/10 text-sm focus:outline-none focus:border-neon-blue/50"
              />
              <button
                type="button"
                disabled={isPending || !dateFrom || !dateTo}
                onClick={applyDates}
                className="shrink-0 px-3 py-2.5 rounded-xl bg-white/10 hover:bg-white/15 text-sm font-medium disabled:opacity-40"
              >
                {isPending ? "…" : "Cargar"}
              </button>
            </div>
          </div>
        </div>

        <div className="rounded-xl border border-white/10 bg-black/30 px-4 py-3">
          <p className="text-xs text-gray-500 mb-2">Qué datos salen en cada ticket</p>
          <div className="flex flex-wrap gap-4 text-sm text-gray-200">
            {(
              [
                ["name", "Nombre"],
                ["ticketNum", "Código"],
                ["phone", "Teléfono"],
                ["email", "Correo"],
              ] as const
            ).map(([key, label]) => (
              <label key={key} className="inline-flex items-center gap-2 cursor-pointer select-none">
                <input
                  type="checkbox"
                  checked={printFields[key]}
                  onChange={() =>
                    setPrintFields((prev) => ({ ...prev, [key]: !prev[key] }))
                  }
                  className="accent-[#0ea5e9] w-4 h-4"
                />
                {label}
              </label>
            ))}
          </div>
        </div>

        <p className="text-sm text-gray-400">
          Vista previa: <strong className="text-white">{previewTickets.length}</strong> ticket
          {previewTickets.length === 1 ? "" : "s"}
          {" · "}
          {initialFrom} → {initialTo}
        </p>

        {/* Vista previa en pantalla (no es lo que imprime el navegador; el portal sí) */}
        <div className="rounded-2xl border border-white/10 bg-white p-4 text-black">
          {previewTickets.length === 0 ? (
            <p className="text-center text-gray-500 py-16">
              No hay tickets. Cambia las fechas y pulsa Cargar, o limpia el filtro.
            </p>
          ) : (
            <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-2">
              {previewTickets.map((t) => (
                <div
                  key={t.id}
                  className="border border-black rounded px-2 py-2 text-center flex flex-col justify-evenly min-h-[5.5rem]"
                >
                  {printFields.name && (
                    <div className="text-[10px] font-bold uppercase leading-tight line-clamp-2">
                      {t.name}
                    </div>
                  )}
                  {printFields.ticketNum && (
                    <div className="text-xs font-black font-mono tracking-wide">
                      {t.ticketNum}
                    </div>
                  )}
                  {printFields.phone && (
                    <div className="text-[11px] font-semibold font-mono">{t.phone}</div>
                  )}
                  {printFields.email && (
                    <div className="text-[9px] font-semibold break-all leading-tight">
                      {t.email}
                    </div>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </>
  );
}
