"use client";

import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { getSupabaseClient } from "@/lib/supabase";
import { getCompanyContext } from "@/lib/company-context";
import { resolveCreatorNamesBatch } from "@/lib/employee-utils";
import { Loader2 } from "lucide-react";
import { OrderPrintDocument, type OrderPrintCompanyProfile, type OrderPrintDocumentOrder } from "@/components/orders/order-print-document";
import type { OrderItem, Payment } from "@/types/orders";

type PrintOrderRecord = OrderPrintDocumentOrder & {
  user_id: string;
  created_by?: string | null;
};

type PrintDocumentRecord = {
  order: PrintOrderRecord;
  items: OrderItem[];
  payments: Payment[];
  profile: OrderPrintCompanyProfile | null;
  creatorName: string;
};

export default function BatchOrdersPrintPage() {
  const searchParams = useSearchParams();
  const [loading, setLoading] = useState(true);
  const [documents, setDocuments] = useState<PrintDocumentRecord[]>([]);
  const [errorMessage, setErrorMessage] = useState("");
  const [hasPrinted, setHasPrinted] = useState(false);
  const autoPrint = searchParams.get("autoprint") === "1";
  const embedded = searchParams.get("embedded") === "1";

  const ids = useMemo(() => {
    const raw = searchParams.get("ids") || "";
    return raw
      .split(",")
      .map((id) => id.trim())
      .filter(Boolean);
  }, [searchParams]);

  useEffect(() => {
    let active = true;

    async function load() {
      if (ids.length === 0) {
        setDocuments([]);
        setErrorMessage("Nenhum pedido informado para impressão.");
        setLoading(false);
        return;
      }

      setLoading(true);
      setErrorMessage("");
      try {
        const supabase = getSupabaseClient();
        const {
          data: { user },
        } = await supabase.auth.getUser();

        if (!user) {
          throw new Error("Usuário não autenticado.");
        }

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

        const { data: ordersData, error: ordersError } = await supabase
          .from("orders")
          .select(
            "id, number, status, created_at, total_amount, paid_amount, delivery_date, payment_terms, notes, internal_notes, approval_signature, approval_signed_name, approval_signed_at, user_id, created_by, clients(name, company_name, type, is_deleted, document, email, phone, whatsapp, whatsapp_notify, address_street, address_number, address_complement, address_neighborhood, address_city, address_state, address_zip, notes, tags, active), quotes(id, number, user_id, share_token, share_enabled, title, internal_notes, notes, subtotal, discount, shipping, total, delivery_date)"
          )
          .in("id", ids)
          .in("user_id", tenantIds);

        if (ordersError) throw ordersError;

        const orders = (ordersData || []) as PrintOrderRecord[];
        if (!active) return;
        if (orders.length === 0) {
          setDocuments([]);
          setErrorMessage("Nenhum pedido encontrado para impressão.");
          setLoading(false);
          return;
        }

        const userIds = Array.from(new Set(orders.map((order) => order.user_id).filter(Boolean)));
        const creatorIds = Array.from(new Set(orders.map((order) => order.created_by).filter(Boolean))) as string[];

        const [profilesResult, itemsResult, paymentsResult, creatorNames] = await Promise.all([
          userIds.length > 0
            ? supabase
                .from("profiles")
                .select(
                  "slug, store_name, logo_url, catalog_logo_url, catalog_name, cnpj, address, company_phone, phone, company_whatsapp, whatsapp, company_email, quote_signature_required, quote_art_registration_enabled, quote_art_approval_required, quote_default_notes_enabled, quote_default_notes, id"
                )
                .in("id", userIds)
            : Promise.resolve({ data: [] as (OrderPrintCompanyProfile & { id: string })[] }),
          supabase
            .from("order_items")
            .select(
              "id, created_at, order_id, product_id, title, description, quantity, unit_price, total_price, unit_type, width_m, height_m, length_m, valor_minimo_aplicado, valor_sem_minimo, products(sku, barcode)"
            )
            .in("order_id", ids)
            .order("created_at", { ascending: true }),
          supabase
            .from("payments")
            .select("id, order_id, amount, payment_method, payment_date")
            .in("order_id", ids)
            .in("user_id", tenantIds)
            .order("payment_date", { ascending: true }),
          resolveCreatorNamesBatch(
            supabase,
            creatorIds.reduce((acc, creatorId) => {
              acc[creatorId] = { isOwner: creatorId === user.id };
              return acc;
            }, {} as Record<string, { isOwner?: boolean }>)
          ),
        ]);

        const profilesMap = ((profilesResult.data || []) as (OrderPrintCompanyProfile & { id: string })[]).reduce(
          (acc, profile) => {
            acc[profile.id] = profile;
            return acc;
          },
          {} as Record<string, OrderPrintCompanyProfile>
        );

        const itemsByOrderId = ((itemsResult.data || []) as (OrderItem & { order_id: string })[]).reduce(
          (acc, item) => {
            if (!acc[item.order_id]) acc[item.order_id] = [];
            acc[item.order_id].push(item);
            return acc;
          },
          {} as Record<string, OrderItem[]>
        );

        const paymentsByOrderId = ((paymentsResult.data || []) as (Payment & { order_id: string })[]).reduce(
          (acc, payment) => {
            if (!acc[payment.order_id]) acc[payment.order_id] = [];
            acc[payment.order_id].push(payment);
            return acc;
          },
          {} as Record<string, Payment[]>
        );

        const orderPosition = ids.reduce((acc, id, index) => {
          acc[id] = index;
          return acc;
        }, {} as Record<string, number>);

        const nextDocuments = orders
          .sort((a, b) => (orderPosition[a.id] ?? 0) - (orderPosition[b.id] ?? 0))
          .map((order) => ({
            order,
            items: itemsByOrderId[order.id] || [],
            payments: paymentsByOrderId[order.id] || [],
            profile: profilesMap[order.user_id] || null,
            creatorName: order.created_by ? creatorNames[order.created_by] || "Usuário" : "",
          }));

        if (!active) return;
        setDocuments(nextDocuments);
      } catch (error) {
        console.error("Erro ao preparar impressão em massa dos pedidos:", error);
        if (!active) return;
        setDocuments([]);
        setErrorMessage("Não foi possível carregar os pedidos para impressão.");
      } finally {
        if (active) setLoading(false);
      }
    }

    void load();

    return () => {
      active = false;
    };
  }, [ids]);

  useEffect(() => {
    if (!autoPrint) return;
    if (loading || documents.length === 0 || hasPrinted) return;

    const timer = window.setTimeout(() => {
      setHasPrinted(true);
      window.print();
    }, 300);

    const handleAfterPrint = () => {
      if (embedded) {
        window.parent.postMessage({ type: "batch-orders-print-finished" }, window.location.origin);
        return;
      }

      if (window.opener && !window.opener.closed) {
        window.close();
        return;
      }

      if (window.history.length > 1) {
        window.history.back();
        return;
      }

      window.location.assign("/dashboard/orders");
    };

    window.addEventListener("afterprint", handleAfterPrint);
    return () => {
      window.clearTimeout(timer);
      window.removeEventListener("afterprint", handleAfterPrint);
    };
  }, [loading, documents, hasPrinted, autoPrint, embedded]);

  return (
    <div className="min-h-screen bg-white">
      {loading ? (
        <div className="flex min-h-screen items-center justify-center gap-3 text-zinc-500">
          <Loader2 className="h-5 w-5 animate-spin" />
          <span>Preparando pedidos para impressão...</span>
        </div>
      ) : errorMessage ? (
        <div className="flex min-h-screen items-center justify-center px-6 text-center text-zinc-500">
          {errorMessage}
        </div>
      ) : (
        <>
          {documents.map((doc, index) => (
            <OrderPrintDocument
              key={doc.order.id}
              order={doc.order}
              items={doc.items}
              payments={doc.payments}
              profile={doc.profile}
              creatorName={doc.creatorName}
              alwaysVisible
              style={index < documents.length - 1 ? { breakAfter: "page", pageBreakAfter: "always" } : undefined}
            />
          ))}
        </>
      )}
    </div>
  );
}
