"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog";
import { ClipboardCheck, Loader2, Printer } from "lucide-react";
import { getSupabaseClient } from "@/lib/supabase";
import { getCompanyContext } from "@/lib/company-context";
import { CustomSelect } from "@/components/ui/custom-select";
import {
  enderecoDaEmpresa,
  enderecoDoCliente,
  imprimirProtocolo,
  montarHtmlDoProtocolo,
  paginarItens,
  variacaoDoItem,
  type ModoDoProtocolo,
  type ProtocoloPedido,
} from "@/lib/orders/protocolo-de-entrega";

/*
  O protocolo de um pedido só.

  A PRÉVIA É O PRÓPRIO DOCUMENTO, num iframe. A etiqueta tem duas
  implementações do mesmo desenho — um componente React para a tela e um
  gerador de HTML para a impressora — e elas podem divergir sem ninguém
  perceber até sair torto no papel. Aqui existe um desenho só: o que você vê é
  literalmente o que a impressora recebe.
*/

export function ProtocoloPrintModal({
  open,
  onOpenChange,
  orderId,
  orderNumber,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  orderId?: string | null;
  orderNumber?: number | string | null;
}) {
  const [carregando, setCarregando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [pedido, setPedido] = useState<ProtocoloPedido | null>(null);
  const [via, setVia] = useState<ModoDoProtocolo>("duas-vias");

  useEffect(() => {
    if (!open || !orderId) {
      setPedido(null);
      setErro(null);
      return;
    }

    let cancelado = false;

    async function carregar() {
      try {
        setCarregando(true);
        setErro(null);

        const supabase = getSupabaseClient();
        const {
          data: { user },
        } = await supabase.auth.getUser();
        if (!user) throw new Error("Não autenticado");

        const ctx = await getCompanyContext(supabase, user);
        const tenantIds = ctx.tenantIds?.length ? ctx.tenantIds : [user.id];

        const { data: orderData, error: orderError } = await supabase
          .from("orders")
          .select("id,number,user_id,client_id")
          .eq("id", orderId)
          .in("user_id", tenantIds)
          .single();
        if (orderError) throw orderError;

        const [{ data: clientData }, { data: profileData }, { data: itemsData }] = await Promise.all([
          orderData.client_id
            ? supabase.from("clients").select("*").eq("id", orderData.client_id).maybeSingle()
            : Promise.resolve({ data: null }),
          supabase.from("profiles").select("*").eq("id", orderData.user_id).maybeSingle(),
          supabase
            .from("order_items")
            .select("title,quantity,unit_type,width_m,height_m,length_m,selected_options,created_at")
            .eq("order_id", orderData.id)
            .order("created_at", { ascending: true }),
        ]);

        if (cancelado) return;

        setPedido({
          numero: orderData.number,
          id: orderData.id,
          empresa: {
            nome: profileData?.store_name || profileData?.catalog_name || "Empresa",
            logoUrl: profileData?.logo_url || profileData?.catalog_logo_url || null,
            cnpj: profileData?.cnpj || null,
            telefone: profileData?.company_phone || profileData?.phone || profileData?.whatsapp || null,
            endereco: enderecoDaEmpresa(profileData as Record<string, unknown> | null),
          },
          cliente: {
            nome: clientData?.name || null,
            empresa: clientData?.company_name || null,
            documento: clientData?.document || null,
            telefone: clientData?.phone || clientData?.whatsapp || null,
            endereco: enderecoDoCliente(clientData as Record<string, unknown> | null),
          },
          itens: (itemsData || []).map((i) => ({
            titulo: i.title,
            quantity: i.quantity,
            unit_type: i.unit_type,
            width_m: i.width_m,
            height_m: i.height_m,
            length_m: i.length_m,
            variacao: variacaoDoItem(i.selected_options),
          })),
        });
      } catch (e) {
        if (!cancelado) {
          console.error("Erro ao montar o protocolo de entrega:", e);
          setErro("Não foi possível carregar os dados deste pedido.");
        }
      } finally {
        if (!cancelado) setCarregando(false);
      }
    }

    void carregar();
    return () => {
      cancelado = true;
    };
  }, [open, orderId]);

  const html = useMemo(() => (pedido ? montarHtmlDoProtocolo([pedido], via) : ""), [pedido, via]);
  const folhas = useMemo(() => (pedido ? paginarItens(pedido.itens).length : 0), [pedido]);

  const imprimir = useCallback(() => {
    if (pedido) void imprimirProtocolo([pedido], via);
  }, [pedido, via]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-3xl overflow-hidden border-0 p-0">
        <DialogTitle className="sr-only">
          Protocolo de entrega{orderNumber ? ` do pedido ${orderNumber}` : ""}
        </DialogTitle>
        <DialogDescription className="sr-only">
          Confira o protocolo de entrega e imprima em folha A4 deitada.
        </DialogDescription>

        <div className="flex max-h-[90vh] flex-col bg-zinc-50">
          <div className="shrink-0 border-b border-zinc-200 bg-white px-5 py-4">
            <div className="flex items-center gap-3">
              <div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-[var(--ks-color-primary-soft)] text-[var(--ks-color-primary)]">
                <ClipboardCheck size={20} />
              </div>
              <div>
                <h3 className="text-lg font-semibold text-zinc-900">
                  Protocolo de entrega{orderNumber ? ` · pedido ${orderNumber}` : ""}
                </h3>
                <p className="text-sm text-zinc-500">
                  Sai em A4 deitada, com a via da empresa e a via do cliente lado a lado. Sem valores.
                </p>
              </div>
            </div>
          </div>

          <div className="flex flex-1 items-start justify-center overflow-auto bg-zinc-100/60 p-5">
            {carregando ? (
              <div className="flex flex-col items-center justify-center py-16 text-zinc-400">
                <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
                <p className="mt-4 text-sm font-medium">Montando o protocolo...</p>
              </div>
            ) : erro ? (
              <div className="py-16 text-center text-sm text-red-600">{erro}</div>
            ) : (
              <div
                className="overflow-hidden rounded-md bg-white shadow-xl ring-1 ring-zinc-900/5"
                style={{ width: 660, height: Math.round(660 * (210 / 297)) * Math.max(1, folhas) }}
              >
                <iframe
                  title="Prévia do protocolo de entrega"
                  srcDoc={html}
                  sandbox="allow-same-origin"
                  scrolling="no"
                  style={{
                    width: 1122,
                    height: 794 * Math.max(1, folhas),
                    border: 0,
                    transform: `scale(${660 / 1122})`,
                    transformOrigin: "top left",
                  }}
                />
              </div>
            )}
          </div>

          <div className="flex shrink-0 flex-wrap items-center gap-3 border-t border-zinc-200 bg-white px-5 py-4">
            <div className="w-[220px]">
              <CustomSelect
                options={[
                  { value: "duas-vias", label: "As duas vias" },
                  { value: "so-cliente", label: "Só a via do cliente" },
                  { value: "so-empresa", label: "Só a via da empresa" },
                ]}
                value={via}
                onChange={(v) => setVia(v as ModoDoProtocolo)}
              />
            </div>
            <p className="flex-1 text-xs leading-5 text-zinc-500">
              {folhas > 1
                ? `São ${folhas} folhas. As assinaturas ficam na última.`
                : via === "duas-vias"
                  ? "Corte no meio: uma via fica com você, a outra com o cliente."
                  : "Metade da folha fica em branco. Corte e guarde para a próxima."}
            </p>
            <button
              type="button"
              onClick={imprimir}
              disabled={carregando || !pedido}
              className="inline-flex h-11 items-center justify-center gap-2 rounded-2xl bg-[var(--ks-color-primary)] px-6 text-sm font-semibold text-white transition-colors hover:bg-[var(--ks-color-primary-strong)] disabled:opacity-60"
            >
              <Printer size={16} />
              Imprimir
            </button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
