"use client";

import { quantidadeDoItem } from "@/lib/orders/quantidade-do-item";
import { useEffect, useMemo, useState } from "react";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { AnimatePresence, motion } from "framer-motion";
import { getSupabaseClient } from "@/lib/supabase";
import { getCompanyContext } from "@/lib/company-context";
import { resolveCreatorNamesBatch } from "@/lib/employee-utils";
import { FileText, Plus, Search, Trash2, AlertCircle, Clock, CheckCircle2, Ban, Settings, Eye, User, Calendar, LayoutGrid, List, Copy, Check, Sparkles, Link2, StickyNote, ShieldCheck } from "lucide-react";
import { CustomSelect } from "@/components/ui/custom-select";
import { PageHeader } from "@/components/ui/page-header";
import { Button } from "@/components/ui/button";
import { usePermissoes } from "@/lib/permissoes-do-usuario";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { InfoTooltip } from "@/components/ui/info-tooltip";
import {
  formatMeasureInput,
  formatMoneyInput,
  parseMeasureInput,
  parseMoneyInput,
  unitLabel,
} from "@/utils/formatters";
import { calculateEffectiveQuantity, checkSaleQuantityLimits, type ProductPriceTier } from "@/lib/price-tiers";
import { precoDaLinha, valorMinimoDoItem, textoDoMinimoAplicado, COLUNAS_DO_VALOR_MINIMO } from "@/lib/adicionais";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { registrarEnvioDoLink } from "@/lib/envio-do-link";
import { prazoDoLink } from "@/lib/prazo-do-link";

type QuoteStatus = "draft" | "sent" | "approved" | "rejected" | "production" | "delivered";

interface QuoteRow {
  id: string;
  created_at: string;
  updated_at: string;
  user_id: string;
  client_id: string;
  number: number;
  status: QuoteStatus;
  title: string | null;
  description: string | null;
  currency: string;
  subtotal: number;
  discount: number;
  shipping: number;
  total: number;
  list_price_mode?: boolean | null;
  expires_at: string | null;
  notes: string | null;
  internal_notes: string | null;
  share_enabled: boolean;
  share_token?: string | null;
  public_view_count: number | null;
  public_last_viewed_at: string | null;
  created_by?: string | null;
  client?: {
    id: string;
    name: string;
    company_name: string | null;
    whatsapp: string | null;
    active?: boolean | null;
    is_deleted?: boolean | null;
  } | null;
  orders?: {
    id: string;
    number: number;
    status: string;
  } | null;
}

interface ProductOption {
  id: string;
  name: string;
  price: number;
  cost_total: number;
  unit_type: string | null;
  image_url: string | null;
  price_on_request?: boolean | null;
  product_price_tiers?: ProductPriceTier[] | null;
  min_sale_qty_enabled?: boolean | null;
  min_sale_qty?: number | null;
  max_sale_qty_enabled?: boolean | null;
  max_sale_qty?: number | null;
  allowed_sale_qty_enabled?: boolean | null;
  allowed_sale_quantities?: number[] | null;
  valor_minimo_item?: number | null;
  valor_minimo_orcamentos?: boolean | null;
}

interface QuickQuoteItemDraft {
  id: string;
  product_id: string;
  title: string;
  unit_type: string;
  width_m: string;
  height_m: string;
  length_m: string;
  quantity: number;
  unit_price: string;
  /** O valor mínimo do item pegou nesta linha: a linha vale `minimo`. */
  minimo?: { minimo: number; semMinimo: number; precoPorMedida: number } | null;
}
type QuickQuoteStep = "details" | "review" | "done";

type QuickConfettiPiece = {
  left: number;
  size: number;
  rotate: number;
  duration: number;
  delay: number;
  xDrift: number;
  color: string;
};

const statusLabel: Record<QuoteStatus, string> = {
  draft: "Rascunho",
  sent: "Enviado",
  approved: "Aprovado",
  rejected: "Recusado",
  production: "Em produção",
  delivered: "Entregue",
};

function getQuoteStatusBadgeClass(status: QuoteStatus) {
  if (status === "approved" || status === "delivered") {
    return "bg-emerald-50 text-emerald-700 border-emerald-200";
  }
  if (status === "rejected") {
    return "bg-red-50 text-red-600 border-red-200";
  }
  if (status === "sent") {
    return "bg-indigo-50 text-indigo-700 border-indigo-100";
  }
  if (status === "production") {
    return "bg-amber-50 text-amber-700 border-amber-200";
  }
  return "bg-gray-50 text-gray-600 border-gray-200";
}

function getQuoteClientAvatarClass(name: string) {
  return ["bg-blue-600", "bg-indigo-600", "bg-purple-600", "bg-teal-600"][
    ((name?.charCodeAt(0) || 0) + (name?.length || 0)) % 4
  ];
}

function formatMoney(value: number) {
  return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(value || 0);
}
function generateShareToken() {
  const bytes = new Uint8Array(24);
  crypto.getRandomValues(bytes);
  return Array.from(bytes)
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

/* O prazo do link mora em lib/prazo-do-link.ts: a mesma conta da tela do
   orçamento e da revisão rápida do Dashboard. */
const resolveShareExpiry = prazoDoLink;

function createQuickConfettiPieces() {
  const palette = ["#6D28D9", "#7C3AED", "#8B5CF6", "#A855F7", "#C084FC"];
  return Array.from({ length: 70 }).map(() => {
    return {
      left: Math.random() * 100,
      size: 6 + Math.random() * 7,
      rotate: Math.random() * 360,
      duration: 1.5 + Math.random() * 1.1,
      delay: Math.random() * 0.2,
      xDrift: (Math.random() - 0.5) * 70,
      color: palette[Math.floor(Math.random() * palette.length)],
    };
  });
}

function generateDraftId() {
  if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
    return crypto.randomUUID();
  }
  return `draft-${Math.random().toString(16).slice(2)}-${Date.now()}`;
}

function createEmptyQuickItem(): QuickQuoteItemDraft {
  return {
    id: generateDraftId(),
    product_id: "",
    title: "",
    unit_type: "unit",
    width_m: "0,00",
    height_m: "0,00",
    length_m: "0,00",
    quantity: 1,
    unit_price: "0,00",
  };
}

function effectiveQuantity(item: Pick<QuickQuoteItemDraft, "quantity" | "unit_type" | "width_m" | "height_m" | "length_m">) {
  return calculateEffectiveQuantity({
    quantity: item.quantity || 0,
    unit_type: item.unit_type,
    width_m: parseMeasureInput(item.width_m),
    height_m: parseMeasureInput(item.height_m),
    length_m: parseMeasureInput(item.length_m),
  });
}

function formatUnitPriceValue(value: number) {
  return new Intl.NumberFormat("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(value || 0);
}

function formatQuantityLimit(value: number | null) {
  if (value === null || !Number.isFinite(value)) return "0";
  const rounded = Number(value.toFixed(3));
  return Number.isInteger(rounded)
    ? String(rounded)
    : new Intl.NumberFormat("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 3 }).format(rounded);
}

function getMinimumItemQuantity(product?: ProductOption | null) {
  if (!product) return 1;
  const allowedQuantities = getAllowedItemQuantities(product);
  if (Boolean(product.allowed_sale_qty_enabled) && allowedQuantities.length > 0) {
    return Number(allowedQuantities[0].toFixed(3));
  }
  if (Boolean(product.min_sale_qty_enabled)) {
    const minQty = Number(product.min_sale_qty);
    if (Number.isFinite(minQty) && minQty > 0) return Number(minQty.toFixed(3));
  }
  return 1;
}

function getAllowedItemQuantities(product?: ProductOption | null) {
  if (!product) return [] as number[];
  return Array.isArray(product.allowed_sale_quantities)
    ? product.allowed_sale_quantities
        .map((value) => Number(value))
        .filter((value) => Number.isFinite(value) && value > 0)
        .sort((a, b) => a - b)
    : [];
}

export default function QuotesPage() {
  const { pode } = usePermissoes();
  const podeMexerEmOrcamentos = pode("quotes.write");

  const router = useRouter();
  const [quotes, setQuotes] = useState<QuoteRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [searchTerm, setSearchTerm] = useState("");
  const [activeTab, setActiveTab] = useState("pending");
  const [onlyListPriceFilter, setOnlyListPriceFilter] = useState(false);
  const [viewMode, setViewMode] = useState<"list" | "grid">("grid");
  const [createdByNames, setCreatedByNames] = useState<Record<string, string>>({});

  // Error modal state
  const [errorModal, setErrorModal] = useState<{
    open: boolean;
    title: string;
    description: string;
    action?: {
      label: string;
      onClick: () => void;
    };
  }>({
    open: false,
    title: "",
    description: "",
  });

  // Confirmation modal state
  const [confirmModal, setConfirmModal] = useState<{
    open: boolean;
    title: string;
    description: string;
    action: () => void;
    isLoading?: boolean;
    /* O botão da caixa: "Excluir" (o padrão) ou "Recusar". */
    rotulo?: string;
    rotuloEsperando?: string;
  }>({
    open: false,
    title: "",
    description: "",
    action: () => {},
    isLoading: false,
  });
  const [settingsModalOpen, setSettingsModalOpen] = useState(false);
  const [settingsTab, setSettingsTab] = useState<"rules" | "links" | "notes">("rules");
  const [settingsProfileId, setSettingsProfileId] = useState<string | null>(null);
  const [profileSlug, setProfileSlug] = useState<string | null>(null);
  const [profileCustomDomain, setProfileCustomDomain] = useState<string | null>(null);
  const [profileCustomDomainVerified, setProfileCustomDomainVerified] = useState(false);
  const [quoteSettings, setQuoteSettings] = useState({
    signatureRequired: false,
    artEnabled: false,
    artApprovalRequired: false,
    linkExpiryEnabled: false,
    linkExpiryDays: 7 as number | null,
    numberStartFrom: 1,
  });
  const [quoteNumberStartInput, setQuoteNumberStartInput] = useState("1");
  const [quoteNumberSaveState, setQuoteNumberSaveState] = useState<"idle" | "saving" | "saved">("idle");
  const [linkExpiryModal, setLinkExpiryModal] = useState({
    open: false,
    enabled: false,
    days: "7",
  });
  // Global default notes
  const [defaultNotesEnabled, setDefaultNotesEnabled] = useState(false);
  const [defaultNotesText, setDefaultNotesText] = useState("");
  const [defaultNotesSaving, setDefaultNotesSaving] = useState(false);
  const [defaultNotesSaved, setDefaultNotesSaved] = useState(false);
  const [quickQuoteModalOpen, setQuickQuoteModalOpen] = useState(false);
  const [quickQuoteStep, setQuickQuoteStep] = useState<QuickQuoteStep>("details");
  const [quickQuoteSaving, setQuickQuoteSaving] = useState(false);
  const [quickQuoteError, setQuickQuoteError] = useState("");
  const [quickCreatedQuote, setQuickCreatedQuote] = useState<{ id: string; number: number | null } | null>(null);
  const [quickConfettiSeed, setQuickConfettiSeed] = useState(0);
  const [quickConfettiVisible, setQuickConfettiVisible] = useState(false);
  const [quickConfettiPieces, setQuickConfettiPieces] = useState<QuickConfettiPiece[]>([]);
  const [quickTitle, setQuickTitle] = useState("");
  const [quickNotes, setQuickNotes] = useState("");
  const [quickProductsLoading, setQuickProductsLoading] = useState(false);
  const [quickProducts, setQuickProducts] = useState<ProductOption[]>([]);
  const [quickItems, setQuickItems] = useState<QuickQuoteItemDraft[]>([createEmptyQuickItem()]);
  const [quickManualProductSubmittingItemId, setQuickManualProductSubmittingItemId] = useState<string | null>(null);
  const [quickManualProductErrors, setQuickManualProductErrors] = useState<Record<string, string>>({});
  const [sharingQuoteId, setSharingQuoteId] = useState<string | null>(null);
  const [copiedQuoteId, setCopiedQuoteId] = useState<string | null>(null);
  const [duplicatingQuoteId, setDuplicatingQuoteId] = useState<string | null>(null);

  const publicBaseUrl = useMemo(() => {
    const origin = typeof window !== "undefined" ? window.location.origin : "https://ktalogu.com.br";
    const resolved = process.env.NEXT_PUBLIC_PUBLIC_CATALOG_BASE_URL || origin;
    const normalized = resolved.replace(":3002", ":3001").replace(/\/\/admin\./, "//");
    return normalized.replace(/\/$/, "");
  }, []);

  const quickProductsById = useMemo(() => new Map(quickProducts.map((product) => [product.id, product])), [quickProducts]);
  const quickSummaryItems = useMemo(() => quickItems.filter((item) => item.title.trim()), [quickItems]);
  const quickEstimatedTotal = useMemo(
    () => quickSummaryItems.reduce((acc, item) => acc + totalDoItemRapido(item), 0),
    [quickSummaryItems]
  );

  function totalDoItemRapido(item: QuickQuoteItemDraft) {
    if (item.minimo) return item.minimo.minimo;
    return effectiveQuantity(item) * parseMoneyInput(item.unit_price);
  }

  /* Faixa pela quantidade e, por último, o valor mínimo do item (a linha
     inteira comparada sozinha com ele). */
  function resolveQuickProductLine(item: QuickQuoteItemDraft, product: ProductOption) {
    const linha = precoDaLinha({
      precoBase: Number(product.price) || 0,
      faixas: product.product_price_tiers || [],
      pecas: Number(item.quantity) || 0,
      quantidadeEfetiva: effectiveQuantity(item),
      sobConsulta: Boolean(product.price_on_request),
      valorMinimo: valorMinimoDoItem(product, "orcamentos"),
    });
    const minimo =
      linha.minimoAplicado == null
        ? null
        : { minimo: linha.minimoAplicado, semMinimo: linha.totalSemMinimo, precoPorMedida: linha.precoPorMedida };
    return { unitPrice: linha.precoPorMedida, minimo };
  }

  function resolveQuickProductUnitPrice(item: QuickQuoteItemDraft, product: ProductOption) {
    return resolveQuickProductLine(item, product).unitPrice;
  }

  function getQuickItemQuantityRuleMessage(item: QuickQuoteItemDraft, product?: ProductOption | null) {
    if (!product) return null;
    const quantityCheck = checkSaleQuantityLimits({
      min_sale_qty_enabled: product.min_sale_qty_enabled,
      min_sale_qty: product.min_sale_qty,
      max_sale_qty_enabled: product.max_sale_qty_enabled,
      max_sale_qty: product.max_sale_qty,
      allowed_sale_qty_enabled: product.allowed_sale_qty_enabled,
      allowed_sale_quantities: product.allowed_sale_quantities,
      effectiveQuantity: effectiveQuantity(item),
    });
    if (quantityCheck.isBelowMin && quantityCheck.minQty !== null) {
      return `Quantidade minima: ${formatQuantityLimit(quantityCheck.minQty)}.`;
    }
    if (quantityCheck.isAboveMax && quantityCheck.maxQty !== null) {
      return `Quantidade maxima: ${formatQuantityLimit(quantityCheck.maxQty)}.`;
    }
    if (quantityCheck.isNotAllowedValue && quantityCheck.allowedQuantities.length > 0) {
      const values = quantityCheck.allowedQuantities.map((value) => formatQuantityLimit(value)).join(", ");
      return `Use uma quantidade permitida: ${values}.`;
    }
    return null;
  }

  function resetQuickQuoteState() {
    setQuickQuoteStep("details");
    setQuickQuoteSaving(false);
    setQuickQuoteError("");
    setQuickCreatedQuote(null);
    setQuickConfettiVisible(false);
    setQuickConfettiPieces([]);
    setQuickTitle("");
    setQuickNotes("");
    setQuickItems([createEmptyQuickItem()]);
    setQuickManualProductSubmittingItemId(null);
    setQuickManualProductErrors({});
  }

  function canRegisterQuickManualItem(item: QuickQuoteItemDraft) {
    const hasName = item.title.trim().length > 0;
    const hasUnitType = Boolean(item.unit_type?.trim());
    const hasPrice = parseMoneyInput(item.unit_price) > 0;
    return hasName && hasUnitType && hasPrice;
  }

  async function registerQuickManualItemAsProduct(itemId: string) {
    if (quickManualProductSubmittingItemId) return;
    const index = quickItems.findIndex((entry) => entry.id === itemId);
    if (index < 0) return;
    const item = quickItems[index];
    const name = item.title.trim();
    if (!canRegisterQuickManualItem(item)) {
      setQuickManualProductErrors((prev) => ({ ...prev, [item.id]: "Preencha nome, unidade e valor." }));
      return;
    }
    if (!name) return;

    setQuickManualProductSubmittingItemId(item.id);
    setQuickManualProductErrors((prev) => ({ ...prev, [item.id]: "" }));
    try {
      const unitPrice = Math.max(0, parseMoneyInput(item.unit_price));
      const response = await fetch("/api/products", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          name,
          description: "",
          price: unitPrice,
          price_on_request: false,
          use_variation_price_only: false,
          estimated_base_cost: 0,
          stock: 0,
          unit_type: item.unit_type || "unit",
          active: true,
          category_id: null,
          image_url: null,
          images: [],
          show_in_catalog: false,
          catalog_color: "#4F46E5",
          is_catalog_exclusive: false,
          min_sale_qty_enabled: false,
          min_sale_qty: null,
          max_sale_qty_enabled: false,
          max_sale_qty: null,
          allowed_sale_qty_enabled: false,
          allowed_sale_quantities: null,
          sku: null,
          barcode: null,
          track_inventory: false,
          inventory_scope: "product",
          inventory_attribute_name: null,
          allow_negative_stock: false,
          materials: [],
          processes: [],
          attributes: [],
          variations: [],
          price_tiers: [],
        }),
      });
      const json = (await response.json().catch(() => null)) as { id?: string; error?: string } | null;
      if (!response.ok || !json?.id) {
        setQuickManualProductErrors((prev) => ({ ...prev, [item.id]: json?.error || "Não foi possível cadastrar o produto." }));
        return;
      }
      const createdProduct: ProductOption = {
        id: json.id,
        name,
        price: unitPrice,
        cost_total: 0,
        unit_type: item.unit_type || "unit",
        price_on_request: false,
        image_url: null,
        product_price_tiers: [],
        min_sale_qty_enabled: false,
        min_sale_qty: null,
        max_sale_qty_enabled: false,
        max_sale_qty: null,
        allowed_sale_qty_enabled: false,
        allowed_sale_quantities: null,
      };
      setQuickProducts((prev) =>
        [...prev, createdProduct].sort((a, b) => a.name.localeCompare(b.name, "pt-BR", { sensitivity: "base" }))
      );
      updateQuickItem(
        index,
        {
          product_id: createdProduct.id,
          title: createdProduct.name,
          unit_type: createdProduct.unit_type || "unit",
          width_m: "0,00",
          height_m: "0,00",
          length_m: "0,00",
          unit_price: formatUnitPriceValue(createdProduct.price || 0),
          quantity: Math.max(1, item.quantity || 1),
        },
        { forceRecalculate: false }
      );
      setQuickManualProductErrors((prev) => ({ ...prev, [item.id]: "" }));
    } catch {
      setQuickManualProductErrors((prev) => ({ ...prev, [item.id]: "Não foi possível cadastrar o produto." }));
    } finally {
      setQuickManualProductSubmittingItemId(null);
    }
  }

  async function loadQuickProducts() {
    setQuickProductsLoading(true);
    try {
      const supabase = getSupabaseClient();
      const {
        data: { user },
      } = await supabase.auth.getUser();
      if (!user) throw new Error("Sua sessao expirou. Entre novamente.");
      const ctx = await getCompanyContext(supabase, user);
      const tenantIds = ctx.tenantIds?.length ? ctx.tenantIds : [user.id];

      const primary = await supabase
        .from("products")
        .select(`id,name,price,cost_total,unit_type,image_url,price_on_request,min_sale_qty_enabled,min_sale_qty,max_sale_qty_enabled,max_sale_qty,allowed_sale_qty_enabled,allowed_sale_quantities,product_price_tiers(min_qty,max_qty,unit_price,sort_order,active),${COLUNAS_DO_VALOR_MINIMO}`)
        .in("user_id", tenantIds)
        .neq("product_kind", "digital")
        .eq("active", true)
        .order("name", { ascending: true });

      let resolvedProductsData = (primary.data as ProductOption[] | null) ?? null;
      if (primary.error) {
        const message = String((primary.error as { message?: unknown } | null)?.message ?? "").toLowerCase();
        if (message.includes("product_price_tiers")) {
          const fallback = await supabase
            .from("products")
            .select("id,name,price,cost_total,unit_type,image_url,price_on_request,min_sale_qty_enabled,min_sale_qty,max_sale_qty_enabled,max_sale_qty,allowed_sale_qty_enabled,allowed_sale_quantities")
            .in("user_id", tenantIds)
            .neq("product_kind", "digital")
            .eq("active", true)
            .order("name", { ascending: true });
          if (fallback.error) throw fallback.error;
          resolvedProductsData = (fallback.data as ProductOption[] | null) ?? null;
        } else {
          throw primary.error;
        }
      }

      setQuickProducts(resolvedProductsData || []);
    } catch (err) {
      const message = err instanceof Error ? err.message : "Nao foi possivel carregar os produtos.";
      setQuickQuoteError(message);
    } finally {
      setQuickProductsLoading(false);
    }
  }

  function openQuickQuoteModal() {
    resetQuickQuoteState();
    setQuickQuoteModalOpen(true);
    void loadQuickProducts();
  }

  function closeQuickQuoteModal() {
    if (quickQuoteSaving) return;
    setQuickQuoteModalOpen(false);
  }

  function updateQuickItem(index: number, patch: Partial<QuickQuoteItemDraft>, options?: { forceRecalculate?: boolean }) {
    setQuickItems((prev) =>
      prev.map((it, i) => {
        if (i !== index) return it;
        const next = { ...it, ...patch };

        const shouldRecalculate =
          options?.forceRecalculate === true ||
          Object.prototype.hasOwnProperty.call(patch, "product_id") ||
          Object.prototype.hasOwnProperty.call(patch, "quantity") ||
          Object.prototype.hasOwnProperty.call(patch, "unit_type") ||
          Object.prototype.hasOwnProperty.call(patch, "width_m") ||
          Object.prototype.hasOwnProperty.call(patch, "height_m") ||
          Object.prototype.hasOwnProperty.call(patch, "length_m");

        // Preço digitado à mão não leva o mínimo do item.
        if (Object.prototype.hasOwnProperty.call(patch, "unit_price") && !options?.forceRecalculate) {
          return { ...next, minimo: null };
        }
        if (!next.product_id) return next.minimo ? { ...next, minimo: null } : next;
        if (!shouldRecalculate) return next;

        const selected = quickProductsById.get(next.product_id);
        if (!selected) return next;

        const linha = resolveQuickProductLine(next, selected);
        return { ...next, unit_price: formatUnitPriceValue(linha.unitPrice), minimo: linha.minimo };
      })
    );
  }

  function addQuickItem() {
    setQuickItems((prev) => [...prev, createEmptyQuickItem()]);
  }

  function removeQuickItem(index: number) {
    const removedId = quickItems[index]?.id;
    setQuickItems((prev) => {
      if (prev.length <= 1) return prev;
      return prev.filter((_, i) => i !== index);
    });
    if (removedId) {
      setQuickManualProductErrors((prev) => {
        const next = { ...prev };
        delete next[removedId];
        return next;
      });
    }
  }

  function handleQuickQuoteNextStep() {
    if (quickProductsLoading) {
      setQuickQuoteError("Aguarde o carregamento dos produtos.");
      return;
    }

    if (quickSummaryItems.length === 0) {
      setQuickQuoteError("Adicione pelo menos um item para continuar.");
      return;
    }

    const hasInvalidQty = quickSummaryItems.some((item) => !Number.isFinite(item.quantity) || item.quantity <= 0);
    if (hasInvalidQty) {
      setQuickQuoteError("Existe item com quantidade invalida.");
      return;
    }

    for (const item of quickSummaryItems) {
      const product = quickProductsById.get(item.product_id);
      const quantityRuleMessage = getQuickItemQuantityRuleMessage(item, product);
      if (quantityRuleMessage) {
        const itemLabel = item.title.trim() || product?.name || "Item";
        setQuickQuoteError(`${itemLabel}: ${quantityRuleMessage}`);
        return;
      }
    }

    setQuickQuoteError("");
    setQuickQuoteStep("review");
  }

  async function handleCreateQuickQuote() {
    if (quickQuoteSaving) return;
    setQuickQuoteSaving(true);
    setQuickQuoteError("");
    try {
      const meaningfulItems = quickSummaryItems.map((item) => {
        const product = quickProductsById.get(item.product_id);
        const width = parseMeasureInput(item.width_m);
        const height = parseMeasureInput(item.height_m);
        const length = parseMeasureInput(item.length_m);
        return {
          product_id: item.product_id || null,
          unit_type: item.unit_type || "unit",
          width_m: width > 0 ? width : null,
          height_m: height > 0 ? height : null,
          length_m: length > 0 ? length : null,
          title: item.title.trim(),
          description: null,
          quantity: Math.max(1, Number(item.quantity) || 1),
          unit_price: item.minimo
            ? Math.round(item.minimo.precoPorMedida * 1e6) / 1e6
            : Math.max(0, parseMoneyInput(item.unit_price)),
          unit_cost: Math.max(0, Number(product?.cost_total) || 0),
          valor_minimo_aplicado: item.minimo ? item.minimo.minimo : null,
          valor_sem_minimo: item.minimo ? Math.round(item.minimo.semMinimo * 100) / 100 : null,
        };
      });

      if (meaningfulItems.length === 0) {
        setQuickQuoteError("Adicione pelo menos um item valido.");
        return;
      }

      const payload = {
        quick_quote: true,
        status: "draft",
        title: quickTitle.trim() || null,
        notes: quickNotes.trim() || null,
        discount: 0,
        shipping: 0,
        items: meaningfulItems,
      };

      const res = await fetch("/api/quotes", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify(payload),
      });

      const json = (await res.json().catch(() => null)) as { quoteId?: string; quoteNumber?: number; error?: string } | null;
      if (!res.ok) {
        throw new Error(json?.error || "Nao foi possivel criar o orcamento rapido.");
      }

      const createdId = String(json?.quoteId || "");
      if (!createdId) {
        throw new Error("Resposta invalida ao criar orcamento rapido.");
      }

      const createdNumber = typeof json?.quoteNumber === "number" ? json.quoteNumber : null;
      setQuickCreatedQuote({ id: createdId, number: createdNumber });
      setQuickQuoteStep("done");
      setQuickConfettiSeed((value) => value + 1);
      setQuickConfettiPieces(createQuickConfettiPieces());
      setQuickConfettiVisible(true);
      window.setTimeout(() => setQuickConfettiVisible(false), 2200);

      await fetchQuotes();
    } catch (err) {
      const message = err instanceof Error ? err.message : "Nao foi possivel criar o orcamento rapido.";
      setQuickQuoteError(message);
    } finally {
      setQuickQuoteSaving(false);
    }
  }

  function openQuickCreatedQuote() {
    if (!quickCreatedQuote?.id) return;
    setQuickQuoteModalOpen(false);
    window.location.href = `/dashboard/quotes/${quickCreatedQuote.id}`;
  }

  async function fetchQuotes() {
    setLoading(true);
    try {
      const supabase = getSupabaseClient();
      const {
        data: { user },
      } = await supabase.auth.getUser();
      if (!user) return;
      const ctx = await getCompanyContext(supabase, user);
      const tenantIds = ctx.tenantIds?.length ? ctx.tenantIds : [user.id];

      const { data, error } = await supabase
        .from("quotes")
        .select("*, client:clients(id,name,company_name,whatsapp,active,is_deleted), orders(id, number, status)")
        .in("user_id", tenantIds)
        .order("created_at", { ascending: false });

      if (error) throw error;
      
      // O Supabase retorna orders como array (relação 1:N no schema, mas unique garante 0 ou 1)
      // Normalizamos para objeto único se existir
      const normalized = ((data as unknown[]) || []).map((q) => {
        const row = q as QuoteRow & { orders?: Array<{ id: string; number: number; status: QuoteStatus }> | null };
        const firstOrder = row.orders && row.orders.length > 0 ? row.orders[0] : null;
        return {
          ...row,
          orders: firstOrder,
        };
      });
      
      setQuotes(normalized);

      const ids = Array.from(new Set(normalized.map((q) => q.created_by).filter((id): id is string => Boolean(id))));
      if (ids.length > 0) {
        // Primeiro criar um mapa para verificar se created_by é igual ao user_id (dono da empresa)
        const ownerMap: Record<string, boolean> = {};
        for (const q of normalized) {
          if (q.created_by && q.created_by === q.user_id) {
            ownerMap[q.created_by] = true;
          }
        }
        
        // Usa utilitário centralizado para buscar nomes dos criadores
        const userMap: Record<string, { isOwner?: boolean }> = {};
        for (const id of ids) {
          userMap[id] = { isOwner: ownerMap[id] };
        }
        
        const finalMap = await resolveCreatorNamesBatch(supabase, userMap);
        
        console.log("Nomes dos criadores resolvidos (quotes):", {
          ids,
          result: finalMap
        });
        setCreatedByNames(finalMap);
      } else {
        setCreatedByNames({});
      }
    } catch (err) {
      console.error("Erro ao buscar orçamentos:", err);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    fetchQuotes();
  }, []);

  useEffect(() => {
    let cancelled = false;
    async function fetchQuoteSettings() {
      try {
        const supabase = getSupabaseClient();
        const {
          data: { user },
        } = await supabase.auth.getUser();
        if (!user) return;
        const ctx = await getCompanyContext(supabase, user);
        const profileId = ctx.ownerId || user.id;
        if (cancelled) return;
        setSettingsProfileId(profileId);
        const fullSettingsColumns =
          "quote_signature_required, quote_art_registration_enabled, quote_art_approval_required, quote_share_link_expires_enabled, quote_share_link_expires_days, quote_number_start_from, slug, quote_default_notes_enabled, quote_default_notes";
        const legacySettingsColumns =
          "quote_signature_required, quote_art_registration_enabled, quote_art_approval_required, quote_share_link_expires_enabled, quote_share_link_expires_days, slug";

        const fullSettingsResponse = await supabase
          .from("profiles")
          .select(fullSettingsColumns)
          .eq("id", profileId)
          .maybeSingle();
        let data = fullSettingsResponse.data as Record<string, unknown> | null;
        let error = fullSettingsResponse.error as { code?: string; message?: string } | null;

        if (error) {
          const errorMessage = String((error as { message?: unknown } | null)?.message ?? "").toLowerCase();
          if (errorMessage.includes("quote_number_start_from")) {
            const fallback = await supabase
              .from("profiles")
              .select(legacySettingsColumns)
              .eq("id", profileId)
              .maybeSingle();
            data = fallback.data as Record<string, unknown> | null;
            error = fallback.error as { code?: string; message?: string } | null;
          }
        }

        if (error && error.code !== "PGRST116") throw error;
        if (data) {
          const linkExpiryEnabled = Boolean(data.quote_share_link_expires_enabled);
          const linkExpiryDaysRaw = typeof data.quote_share_link_expires_days === "number"
            ? data.quote_share_link_expires_days
            : null;
          const linkExpiryDays = linkExpiryDaysRaw && linkExpiryDaysRaw > 0 ? linkExpiryDaysRaw : 7;
          const numberStartFromRaw = typeof data.quote_number_start_from === "number" ? data.quote_number_start_from : 1;
          const numberStartFrom = Number.isFinite(numberStartFromRaw) && numberStartFromRaw > 0
            ? Math.floor(numberStartFromRaw)
            : 1;
          setQuoteSettings({
            signatureRequired: Boolean(data.quote_signature_required),
            artEnabled: Boolean(data.quote_art_registration_enabled),
            artApprovalRequired: Boolean(data.quote_art_approval_required),
            linkExpiryEnabled,
            linkExpiryDays: linkExpiryEnabled ? linkExpiryDays : 7,
            numberStartFrom,
          });
          setQuoteNumberStartInput(String(numberStartFrom));
          const profileSlugValue = typeof data.slug === "string" ? data.slug : null;
          setProfileSlug(profileSlugValue);
          // Default notes
          setDefaultNotesEnabled(Boolean(data.quote_default_notes_enabled));
          setDefaultNotesText(typeof data.quote_default_notes === "string" ? data.quote_default_notes : "");
        }
        const { data: domainData, error: domainError } = await supabase
          .from("profile_custom_domains")
          .select("domain,verified")
          .eq("profile_id", profileId)
          .maybeSingle();
        if (!domainError || domainError.code === "PGRST116" || domainError.code === "42P01") {
          setProfileCustomDomain((domainData as { domain?: string | null } | null)?.domain || null);
          setProfileCustomDomainVerified(Boolean((domainData as { verified?: boolean | null } | null)?.verified));
        }
      } catch (err) {
        console.error("Erro ao carregar configurações de orçamento:", err);
      }
    }
    fetchQuoteSettings();
    return () => {
      cancelled = true;
    };
  }, []);

  async function persistQuoteSettings(next: {
    signatureRequired: boolean;
    artEnabled: boolean;
    artApprovalRequired: boolean;
    linkExpiryEnabled: boolean;
    linkExpiryDays: number | null;
    numberStartFrom: number;
  }) {
    if (!settingsProfileId) return false;
    try {
      const supabase = getSupabaseClient();
      const updates: Record<string, unknown> = {
        id: settingsProfileId,
        quote_signature_required: next.signatureRequired,
        quote_art_registration_enabled: next.artEnabled,
        quote_art_approval_required: next.artApprovalRequired,
        quote_share_link_expires_enabled: next.linkExpiryEnabled,
        quote_share_link_expires_days: next.linkExpiryEnabled ? next.linkExpiryDays : null,
        quote_number_start_from: Math.max(1, Math.floor(next.numberStartFrom || 1)),
        updated_at: new Date().toISOString(),
      };
      let lastError: unknown = null;
      for (let attempt = 0; attempt < 20; attempt++) {
        const { error } = await supabase.from("profiles").upsert(updates);
        if (!error) {
          lastError = null;
          break;
        }
        lastError = error;
        const errorMessage = String((error as { message?: unknown } | null)?.message ?? "");
        const match = errorMessage.match(/column ["']?([a-zA-Z0-9_]+)["']? .*does not exist/i);
        const unknownColumn = match?.[1];
        if (!unknownColumn || !(unknownColumn in updates)) break;
        delete updates[unknownColumn];
      }
      if (lastError) throw lastError;
      return true;
    } catch (err) {
      console.error("Erro ao salvar configurações de orçamento:", err);
      setErrorModal({
        open: true,
        title: "Erro ao salvar configurações",
        description: "Não foi possível salvar as configurações de orçamento. Tente novamente.",
      });
      return false;
    }
  }

  function applyQuoteSettings(patch: Partial<{
    signatureRequired: boolean;
    artEnabled: boolean;
    artApprovalRequired: boolean;
    linkExpiryEnabled: boolean;
    linkExpiryDays: number | null;
    numberStartFrom: number;
  }>) {
    setQuoteSettings((prev) => {
      const next = { ...prev, ...patch };
      if (!next.artEnabled) next.artApprovalRequired = false;
      void persistQuoteSettings(next);
      return next;
    });
  }

  function openLinkExpiryModal() {
    setLinkExpiryModal({
      open: true,
      enabled: quoteSettings.linkExpiryEnabled,
      days: String(quoteSettings.linkExpiryDays ?? 7),
    });
  }

  function saveLinkExpiryModal() {
    const normalizedDays = Math.max(1, Number(linkExpiryModal.days) || 1);
    applyQuoteSettings({
      linkExpiryEnabled: linkExpiryModal.enabled,
      linkExpiryDays: linkExpiryModal.enabled ? normalizedDays : null,
    });
    setLinkExpiryModal((prev) => ({ ...prev, open: false, days: String(normalizedDays) }));
  }

  async function saveQuoteNumberStartFrom() {
    if (quoteNumberSaveState === "saving") return;
    const normalized = Math.max(1, Math.floor(Number(quoteNumberStartInput) || 1));
    setQuoteNumberStartInput(String(normalized));
    const nextSettings = { ...quoteSettings, numberStartFrom: normalized };
    setQuoteSettings(nextSettings);
    setQuoteNumberSaveState("saving");
    const ok = await persistQuoteSettings(nextSettings);
    if (ok) {
      setQuoteNumberSaveState("saved");
      window.setTimeout(() => setQuoteNumberSaveState("idle"), 1500);
      return;
    }
    setQuoteNumberSaveState("idle");
  }

  async function saveDefaultNotes() {
    if (!settingsProfileId || defaultNotesSaving) return;
    setDefaultNotesSaving(true);
    try {
      const supabase = getSupabaseClient();
      const updates: Record<string, unknown> = {
        id: settingsProfileId,
        quote_default_notes_enabled: defaultNotesEnabled,
        quote_default_notes: defaultNotesText.trim() || null,
        updated_at: new Date().toISOString(),
      };
      let lastError: unknown = null;
      for (let attempt = 0; attempt < 5; attempt++) {
        const { error } = await supabase.from("profiles").upsert(updates);
        if (!error) { lastError = null; break; }
        lastError = error;
        const errorMessage = String((error as { message?: unknown } | null)?.message ?? "");
        const match = errorMessage.match(/column ["']?([a-zA-Z0-9_]+)["']? .*does not exist/i);
        const unknownColumn = match?.[1];
        if (!unknownColumn || !(unknownColumn in updates)) break;
        delete updates[unknownColumn];
      }
      if (lastError) throw lastError;
      setDefaultNotesSaved(true);
      window.setTimeout(() => setDefaultNotesSaved(false), 1500);
    } catch (err) {
      console.error("Erro ao salvar observação padrão:", err);
    } finally {
      setDefaultNotesSaving(false);
    }
  }

  useEffect(() => {
    if (activeTab !== "pending" && onlyListPriceFilter) {
      setOnlyListPriceFilter(false);
    }
  }, [activeTab, onlyListPriceFilter]);

  const filtered = useMemo(() => {
    const term = searchTerm.trim().toLowerCase();
    return quotes.filter((q) => {
      if (activeTab === "pending") {
        if (!["draft", "sent"].includes(q.status)) return false;
      } else if (activeTab === "approved") {
        if (!["approved", "production", "delivered"].includes(q.status)) return false;
      } else if (activeTab === "cancelled") {
        if (q.status !== "rejected") return false;
      }

      if (activeTab === "pending" && onlyListPriceFilter && !q.list_price_mode) return false;

      if (!term) return true;
      const clientName = q.client?.company_name 
        ? `${q.client.company_name} ${q.client.name}`
        : q.client?.name || "";
      const haystack = [String(q.number), q.title || "", clientName, statusLabel[q.status]].join(" ").toLowerCase();
      return haystack.includes(term);
    });
  }, [quotes, searchTerm, activeTab, onlyListPriceFilter]);

  async function handleCancel(quote: QuoteRow) {
    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];

      /* `.select()` para saber quantas linhas mudaram de verdade. Sem ele, uma
         recusa da regra do banco volta sem erro e com zero linhas, e a lista
         marcava como cancelado na tela um orçamento que continuou ativo. */
      const { data: alterados, error } = await supabase
        .from("quotes")
        .update({ status: "rejected" })
        .eq("id", quote.id)
        .in("user_id", tenantIds)
        .select("id");

      if (error) throw error;
      if (!alterados || alterados.length === 0) {
        throw new Error("Você não tem permissão para cancelar orçamentos. Fale com quem administra a conta.");
      }

      setQuotes((prev) =>
        prev.map((q) => (q.id === quote.id ? { ...q, status: "rejected" } : q))
      );
      setErrorModal((prev) => ({ ...prev, open: false }));
    } catch (err) {
      setErrorModal({
        open: true,
        title: "Erro ao cancelar",
        description: err instanceof Error ? err.message : "Não foi possível cancelar o orçamento.",
      });
    }
  }

  async function confirmDelete(quote: QuoteRow) {
    setConfirmModal(prev => ({ ...prev, isLoading: true }));
    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];
      /* Mesma história do cancelar: sem `.select()`, a exclusão barrada pela
         regra do banco voltava calada, a linha sumia da tela e o orçamento
         continuava lá. */
      const { data: apagados, error } = await supabase
        .from("quotes")
        .delete()
        .eq("id", quote.id)
        .in("user_id", tenantIds)
        .select("id");

      if (error) {
        // Check for FK violation
        if (error.code === "23503") {
           setConfirmModal(prev => ({ ...prev, open: false }));
           setErrorModal({
            open: true,
            title: "Não é possível excluir",
            description: "Este orçamento possui registros vinculados (como itens ou pedidos) que impedem a exclusão. Tente cancelar o orçamento.",
            action: {
              label: "Cancelar Orçamento",
              onClick: () => handleCancel(quote),
            },
          });
          return;
        }
        throw error;
      }

      if (!apagados || apagados.length === 0) {
        throw new Error("Você não tem permissão para excluir orçamentos. Fale com quem administra a conta.");
      }

      setQuotes((prev) => prev.filter((q) => q.id !== quote.id));
      setConfirmModal(prev => ({ ...prev, open: false }));
    } catch (err) {
      setConfirmModal(prev => ({ ...prev, open: false }));
      setErrorModal({
        open: true,
        title: "Erro ao excluir",
        description:
          err instanceof Error
            ? err.message
            : "Ocorreu um erro ao tentar excluir o orçamento. Tente novamente ou contate o suporte.",
      });
    } finally {
      setConfirmModal(prev => ({ ...prev, isLoading: false }));
    }
  }

  /* Recusar direto do card (o cliente não fechou), sem precisar abrir orçamento por orçamento: vai para Cancelados. */
  function pedirRecusa(quote: QuoteRow) {
    setConfirmModal({
      open: true,
      title: `Recusar o orçamento #${quote.number}?`,
      description: "Ele vai para a aba Cancelados e não pode mais ser editado. Você ainda pode abrir, imprimir e duplicar.",
      action: async () => {
        setConfirmModal((prev) => ({ ...prev, isLoading: true }));
        await handleCancel(quote);
        setConfirmModal((prev) => ({ ...prev, open: false, isLoading: false }));
      },
      isLoading: false,
      rotulo: "Recusar",
      rotuloEsperando: "Recusando...",
    });
  }
  const podeRecusar = (q: QuoteRow) => podeMexerEmOrcamentos && !q.orders && (q.status === "draft" || q.status === "sent" || q.status === "approved");

  function handleDelete(quote: QuoteRow) {
    // Check if quote has orders
    if (quote.orders) {
      setErrorModal({
        open: true,
        title: "Não é possível excluir",
        description: `Este orçamento gerou o pedido #${quote.orders.number} e não pode ser excluído. Você pode cancelá-lo, o que moverá para a aba de cancelados.`,
        action: {
          label: "Cancelar Orçamento",
          onClick: () => handleCancel(quote),
        },
      });
      return;
    }

    setConfirmModal({
      open: true,
      title: `Excluir orçamento #${quote.number}?`,
      description: "Esta ação não pode ser desfeita.",
      action: () => confirmDelete(quote),
      isLoading: false
    });
  }

  async function ensurePublicShare(quote: QuoteRow) {
    if (!profileSlug) {
      setErrorModal({
        open: true,
        title: "Link público indisponível",
        description: "Configure o link público da loja (slug) em Catálogo.",
      });
      return null;
    }
    setSharingQuoteId(quote.id);
    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];

      let token = quote.share_token;
      if (!token) token = generateShareToken();

      const shareExpiresAt = resolveShareExpiry(quoteSettings.linkExpiryEnabled, quoteSettings.linkExpiryDays);
      const { error: upErr } = await supabase
        .from("quotes")
        .update({ share_enabled: true, share_token: token, share_expires_at: shareExpiresAt })
        .eq("id", quote.id)
        .in("user_id", tenantIds);

      if (upErr) {
        if ((upErr as { code?: string } | null)?.code === "23505") {
          token = generateShareToken();
          const shareExpiresAt = resolveShareExpiry(quoteSettings.linkExpiryEnabled, quoteSettings.linkExpiryDays);
          const { error: retryErr } = await supabase
            .from("quotes")
            .update({ share_enabled: true, share_token: token, share_expires_at: shareExpiresAt })
            .eq("id", quote.id)
            .in("user_id", tenantIds);
          if (retryErr) throw retryErr;
        } else {
          throw upErr;
        }
      }

      setQuotes((prev) =>
        prev.map((q) => (q.id === quote.id ? { ...q, share_enabled: true, share_token: token } : q))
      );
      const shareUrl =
        profileCustomDomain && profileCustomDomainVerified
          ? `https://${profileCustomDomain}/o/${token}`
          : `${publicBaseUrl}/${profileSlug}/o/${token}`;
      return { token, url: shareUrl };
    } catch (err) {
      console.error("Erro ao gerar link público:", err);
      setErrorModal({
        open: true,
        title: "Erro ao gerar link",
        description: "Não foi possível gerar o link público do orçamento.",
      });
      return null;
    } finally {
      setSharingQuoteId(null);
    }
  }

  async function handleCopyLink(quote: QuoteRow) {
    const share = await ensurePublicShare(quote);
    if (!share) return;
    try {
      let copied = false;
      if (navigator.clipboard && document.hasFocus()) {
        await navigator.clipboard.writeText(share.url);
        copied = true;
      } else {
        const textarea = document.createElement("textarea");
        textarea.value = share.url;
        textarea.setAttribute("readonly", "true");
        textarea.style.position = "fixed";
        textarea.style.opacity = "0";
        document.body.appendChild(textarea);
        textarea.select();
        textarea.setSelectionRange(0, textarea.value.length);
        copied = document.execCommand("copy");
        document.body.removeChild(textarea);
      }
      if (!copied) throw new Error("copy_failed");
      setCopiedQuoteId(quote.id);
      window.setTimeout(() => setCopiedQuoteId(null), 1400);
      void registrarEnvioDoLink(quote.id, "link");
    } catch (err) {
      console.error("Erro ao copiar:", err);
      setErrorModal({
        open: true,
        title: "Erro ao copiar",
        description: "Não foi possível copiar o link. Clique na página e tente novamente.",
      });
    }
  }

  async function handleDuplicateQuote(quote: QuoteRow) {
    if (duplicatingQuoteId) return;
    setDuplicatingQuoteId(quote.id);
    try {
      const response = await fetch(`/api/quotes/${quote.id}/duplicate`, { method: "POST" });
      const payload = (await response.json().catch(() => null)) as
        | { quoteId?: string; error?: string }
        | null;

      if (!response.ok || !payload?.quoteId) {
        throw new Error(payload?.error || "Não foi possível duplicar o orçamento.");
      }

      await fetchQuotes();
      router.push(`/dashboard/quotes/${payload.quoteId}?duplicated=1`);
    } catch (err) {
      console.error("Erro ao duplicar orçamento:", err);
      setErrorModal({
        open: true,
        title: "Erro ao duplicar",
        description: err instanceof Error ? err.message : "Não foi possível duplicar o orçamento.",
      });
    } finally {
      setDuplicatingQuoteId(null);
    }
  }

  const settingsModalNode = settingsModalOpen ? (
    <Dialog open={settingsModalOpen} onOpenChange={setSettingsModalOpen}>
      <DialogContent className="sm:max-w-[540px] p-0 overflow-hidden">
        <DialogHeader className="px-5 pt-5 pb-0">
          <DialogTitle className="flex items-center gap-2 text-base">
            <Settings size={18} />
            Configurações de orçamento
          </DialogTitle>
          <DialogDescription className="text-xs">
            Gerencie regras, links e observações dos seus orçamentos.
          </DialogDescription>
        </DialogHeader>

        {/* Tabs */}
        <div className="flex border-b border-zinc-200 px-5 gap-0 mt-2">
          {([
            { key: "rules" as const, label: "Regras", icon: ShieldCheck },
            { key: "links" as const, label: "Links & Numeração", icon: Link2 },
            { key: "notes" as const, label: "Observações", icon: StickyNote },
          ]).map((tab) => (
            <button
              key={tab.key}
              type="button"
              onClick={() => setSettingsTab(tab.key)}
              className={[
                "flex items-center gap-1.5 px-3 py-2.5 text-xs font-semibold border-b-2 transition-colors -mb-px",
                settingsTab === tab.key
                  ? "border-[var(--ks-color-primary)] text-[var(--ks-color-primary)]"
                  : "border-transparent text-zinc-500 hover:text-zinc-700",
              ].join(" ")}
            >
              <tab.icon size={14} />
              {tab.label}
            </button>
          ))}
        </div>

        <div className="px-5 py-4 max-h-[60vh] overflow-y-auto">
          {/* ===== Aba: Regras ===== */}
          {settingsTab === "rules" && (
            <div className="space-y-5">
              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <div className="text-sm font-semibold text-zinc-900">Pedir Assinatura nos orçamentos</div>
                  <div className="text-xs text-zinc-500 mt-0.5">
                    Ao ativar, o cliente só aprova o orçamento mediante assinatura obrigatória.
                  </div>
                </div>
                <Switch
                  checked={quoteSettings.signatureRequired}
                  onCheckedChange={(checked) => applyQuoteSettings({ signatureRequired: checked })}
                />
              </div>

              <div className="h-px bg-zinc-100" />

              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <div className="text-sm font-semibold text-zinc-900">Cadastro de arte no Orçamento</div>
                  <div className="text-xs text-zinc-500 mt-0.5">Permite anexar artes aos itens do orçamento.</div>
                </div>
                <Switch
                  checked={quoteSettings.artEnabled}
                  onCheckedChange={(checked) => applyQuoteSettings({ artEnabled: checked })}
                />
              </div>

              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <div className="text-sm font-semibold text-zinc-900">Aprovação de arte Obrigatória</div>
                  <div className="text-xs text-zinc-500 mt-0.5">A arte precisa ser aprovada pelo cliente.</div>
                </div>
                <Switch
                  checked={quoteSettings.artApprovalRequired}
                  onCheckedChange={(checked) => applyQuoteSettings({ artApprovalRequired: checked })}
                  disabled={!quoteSettings.artEnabled}
                />
              </div>
            </div>
          )}

          {/* ===== Aba: Links & Numeração ===== */}
          {settingsTab === "links" && (
            <div className="space-y-5">
              <button
                type="button"
                onClick={() => {
                  setSettingsModalOpen(false);
                  openLinkExpiryModal();
                }}
                className="flex w-full items-center justify-between gap-3 rounded-lg border border-zinc-200 px-3 py-3 text-left text-sm font-medium text-zinc-700 transition hover:bg-zinc-50"
              >
                <div>
                  <div className="font-semibold text-zinc-900">Validade do link público</div>
                  <div className="text-xs text-zinc-500 mt-0.5">Define prazo de expiração para links de orçamentos compartilhados.</div>
                </div>
                <span className="text-xs text-zinc-500 whitespace-nowrap shrink-0">
                  {quoteSettings.linkExpiryEnabled ? `${quoteSettings.linkExpiryDays ?? 7} dias` : "Sem prazo"}
                </span>
              </button>

              <div className="h-px bg-zinc-100" />

              <div className="rounded-lg border border-zinc-200 px-3 py-3 space-y-2">
                <div className="text-sm font-semibold text-zinc-900 flex items-center">
                  Numeração do orçamento
                  <InfoTooltip text="Define de qual número os próximos orçamentos devem continuar. Orçamentos já emitidos não são alterados." />
                </div>
                <div className="flex items-center gap-2">
                  <input
                    type="number"
                    min={1}
                    step={1}
                    value={quoteNumberStartInput}
                    onChange={(e) => {
                      setQuoteNumberStartInput(e.target.value);
                      if (quoteNumberSaveState === "saved") setQuoteNumberSaveState("idle");
                    }}
                    onBlur={saveQuoteNumberStartFrom}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") {
                        e.preventDefault();
                        saveQuoteNumberStartFrom();
                      }
                    }}
                    className="h-10 w-full rounded-lg border border-zinc-200 px-3 text-sm font-medium text-zinc-900 outline-none focus:border-[var(--ks-color-primary)] focus:ring-2 focus:ring-[var(--ks-color-primary)]/20"
                  />
                  <Button
                    type="button"
                    size="sm"
                    variant="outline"
                    onClick={saveQuoteNumberStartFrom}
                    disabled={quoteNumberSaveState === "saving"}
                    className={quoteNumberSaveState === "saved" ? "border-emerald-300 text-emerald-700" : ""}
                  >
                    {quoteNumberSaveState === "saving" ? "Salvando..." : quoteNumberSaveState === "saved" ? "Salvo" : "Salvar"}
                  </Button>
                </div>
                <div className="text-[11px] text-zinc-900">
                  Valor atual: #{quoteSettings.numberStartFrom}
                </div>
                {quoteNumberSaveState === "saved" && (
                  <div className="text-[11px] font-semibold text-emerald-700 flex items-center gap-1">
                    <Check size={12} />
                    Numeração salva com sucesso.
                  </div>
                )}
              </div>
            </div>
          )}

          {/* ===== Aba: Observações ===== */}
          {settingsTab === "notes" && (
            <div className="space-y-5">
              <div className="flex items-start justify-between gap-4">
                <div className="min-w-0">
                  <div className="text-sm font-semibold text-zinc-900">Observação padrão</div>
                  <div className="text-xs text-zinc-500 mt-0.5">
                    Quando ativada, essa observação aparece automaticamente em todos os orçamentos, PDFs e links públicos. A observação individual do orçamento continuará aparecendo abaixo.
                  </div>
                </div>
                <Switch
                  checked={defaultNotesEnabled}
                  onCheckedChange={(checked) => {
                    setDefaultNotesEnabled(checked);
                    setDefaultNotesSaved(false);
                  }}
                />
              </div>

              {defaultNotesEnabled && (
                <div className="space-y-2">
                  <div className="text-xs font-semibold text-zinc-500 uppercase tracking-wider">Texto da observação padrão</div>
                  <div className="text-[10px] text-zinc-400">💡 Suporta emojis: 📦 🚚 ⚠️ ✅ 💰 📋 🔒 ⏰ 📞 — Cole diretamente no texto.</div>
                  <textarea
                    value={defaultNotesText}
                    onChange={(e) => {
                      setDefaultNotesText(e.target.value);
                      setDefaultNotesSaved(false);
                    }}
                    rows={5}
                    placeholder="Ex:\n📦 Prazo de produção: 5 a 7 dias úteis.\n🚚 Frete a combinar.\n⚠️ Orçamento válido por 15 dias."
                    className="w-full px-3 py-2.5 rounded-lg border border-zinc-200 text-sm text-zinc-900 resize-none outline-none focus:border-[var(--ks-color-primary)] focus:ring-2 focus:ring-[var(--ks-color-primary)]/20 leading-relaxed"
                  />
                  <div className="flex items-center justify-between">
                    <div className="text-[10px] text-zinc-400">
                      {defaultNotesText.length} caracteres
                    </div>
                    <Button
                      type="button"
                      size="sm"
                      onClick={saveDefaultNotes}
                      disabled={defaultNotesSaving}
                      className={defaultNotesSaved ? "border-emerald-300 text-emerald-700" : ""}
                    >
                      {defaultNotesSaving ? "Salvando..." : defaultNotesSaved ? (
                        <span className="flex items-center gap-1"><Check size={12} /> Salvo</span>
                      ) : "Salvar observação"}
                    </Button>
                  </div>
                </div>
              )}

              <div className="h-px bg-zinc-100" />

              <div className="rounded-lg border border-zinc-100 bg-zinc-50 p-3 space-y-1">
                <div className="text-xs font-semibold text-zinc-600">ℹ️ Como funciona</div>
                <ul className="text-[11px] text-zinc-500 space-y-1 list-disc ml-3">
                  <li>A observação padrão aparece <strong>primeiro</strong>, acima da observação individual.</li>
                  <li>A observação individual de cada orçamento <strong>não é anulada</strong> — ela aparece logo abaixo.</li>
                  <li>Aparece no <strong>PDF</strong>, no <strong>link público</strong> e na <strong>página do pedido</strong>.</li>
                </ul>
              </div>
            </div>
          )}
        </div>
      </DialogContent>
    </Dialog>
  ) : null;

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Comercial"
        title="Orçamentos"
        subtitle="Cotações organizadas por status, prontas para virar pedido."
        actions={
          /* Os tres em linha tambem no celular: em grade de 3 colunas cada um
             fica com ~1/3 da largura e o rotulo encolhe para a versao curta.
             Empilhados, empurravam o conteudo da pagina para baixo. */
          !podeMexerEmOrcamentos ? null : (
          <div className="grid w-full grid-cols-3 gap-2 md:flex md:w-auto md:flex-wrap md:items-center">
            <button
              type="button"
              onClick={() => { setSettingsTab("rules"); setSettingsModalOpen(true); }}
              className="inline-flex h-10 w-full items-center justify-center gap-1.5 overflow-hidden whitespace-nowrap rounded-xl border border-zinc-200 bg-white px-2 text-xs font-semibold text-zinc-700 transition hover:bg-zinc-50 md:w-auto md:gap-2 md:px-3 md:text-sm"
            >
              <Settings size={16} className="shrink-0" />
              <span className="truncate md:hidden">Config.</span>
              <span className="hidden md:inline">Configurações de orçamento</span>
            </button>
            <Button
              type="button"
              variant="secondary"
              className="w-full justify-center px-2 text-xs md:w-auto md:px-4 md:text-sm"
              icon={<Sparkles size={16} />}
              onClick={openQuickQuoteModal}
            >
              <span className="truncate md:hidden">{"R\u00e1pido"}</span>
              <span className="hidden md:inline">{"Or\u00e7amento R\u00e1pido"}</span>
            </Button>
            <Link href="/dashboard/quotes/new" className="w-full md:w-auto">
              <Button
                className="w-full justify-center px-2 text-xs md:w-auto md:px-4 md:text-sm"
                icon={<Plus size={18} />}
              >
                <span className="truncate md:hidden">Novo</span>
                <span className="hidden md:inline">Novo orçamento</span>
              </Button>
            </Link>
          </div>
          )
        }
      />
      {settingsModalNode}

      <div className="flex p-1 bg-[rgba(244,245,255,0.9)] rounded-xl w-full md:w-fit overflow-x-auto mb-6">
        <button
          onClick={() => setActiveTab("pending")}
          className={`px-4 py-2 rounded-lg text-sm font-medium transition-all flex items-center gap-2 whitespace-nowrap ${
            activeTab === "pending"
              ? "bg-white shadow-sm text-[var(--ks-color-text-primary)]"
              : "text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-text-primary)]"
          }`}
        >
          <Clock size={16} />
          Pendentes
        </button>
        <button
          onClick={() => setActiveTab("approved")}
          className={`px-4 py-2 rounded-lg text-sm font-medium transition-all flex items-center gap-2 whitespace-nowrap ${
            activeTab === "approved"
              ? "bg-white shadow-sm text-[var(--ks-color-text-primary)]"
              : "text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-text-primary)]"
          }`}
        >
          <CheckCircle2 size={16} />
          Aprovados
        </button>
        <button
          onClick={() => setActiveTab("cancelled")}
          className={`px-4 py-2 rounded-lg text-sm font-medium transition-all flex items-center gap-2 whitespace-nowrap ${
            activeTab === "cancelled"
              ? "bg-white shadow-sm text-[var(--ks-color-text-primary)]"
              : "text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-text-primary)]"
          }`}
        >
          <Ban size={16} />
          Cancelados
        </button>
      </div>

      <div className="flex flex-col gap-3 md:flex-row items-center">
        <div className="flex-1 w-full">
          <Input
            placeholder="Buscar por número, cliente ou título"
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            icon={<Search size={16} />}
          />
        </div>
        <div className="flex items-center gap-2 w-full md:w-auto">
          <button
            type="button"
            onClick={() => setOnlyListPriceFilter((prev) => !prev)}
            disabled={activeTab !== "pending"}
            className={`h-10 w-full md:w-auto rounded-xl border px-4 text-sm font-semibold transition ${
              onlyListPriceFilter
                ? "border-[var(--ks-color-primary)] bg-[rgba(10,192,214,0.12)] text-[var(--ks-color-primary-strong)]"
                : "border-zinc-200 bg-white text-zinc-700 hover:bg-zinc-50"
            } ${activeTab !== "pending" ? "cursor-not-allowed opacity-50" : ""}`}
          >
            Somente Lista de Preço
          </button>
          <div className="flex items-center border border-zinc-200 rounded-lg p-1 bg-white shrink-0">
            <button
              onClick={() => setViewMode("list")}
              className={`p-2 rounded-md transition-colors ${
                viewMode === "list"
                  ? "bg-zinc-100 text-zinc-900"
                  : "text-zinc-400 hover:text-zinc-600 hover:bg-zinc-50"
              }`}
              title="Lista"
            >
              <List size={18} />
            </button>
            <button
              onClick={() => setViewMode("grid")}
              className={`p-2 rounded-md transition-colors ${
                viewMode === "grid"
                  ? "bg-zinc-100 text-zinc-900"
                  : "text-zinc-400 hover:text-zinc-600 hover:bg-zinc-50"
              }`}
              title="Grade"
            >
              <LayoutGrid size={18} />
            </button>
          </div>
        </div>
      </div>

      {/* List Content */}
        <div className="mt-0">
          {loading ? (
            <div className="ks-surface flex items-center justify-center py-12">
              <span className="text-sm text-[var(--ks-color-text-muted)]">Carregando orçamentos...</span>
            </div>
          ) : filtered.length === 0 ? (
            <div className="ks-surface ks-empty-state border-dashed">
              <div className="w-12 h-12 rounded-full bg-[rgba(226,232,255,0.8)] flex items-center justify-center mx-auto mb-3 text-[var(--ks-color-text-soft)]">
                <FileText size={24} />
              </div>
              <h3 className="ks-empty-state-title">Nenhum orçamento encontrado</h3>
              <p className="ks-empty-state-subtitle">
                {activeTab === "pending" 
                  ? "Crie o primeiro orçamento para começar a registrar propostas."
                  : activeTab === "approved" 
                  ? "Nenhum orçamento aprovado encontrado." 
                  : "Nenhum orçamento cancelado encontrado."}
              </p>
            </div>
          ) : (
            <>
              {viewMode === "grid" ? (
                <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
                  {filtered.map((q) => {
                    const clientTitle = q.client?.company_name
                      ? q.client.company_name
                      : q.client?.name || "Cliente sem nome";
                    const clientSubtitle = q.client?.company_name ? q.client?.name : "";
                    const isDeletedClient = Boolean(q.client?.is_deleted);
                    const creatorName = q.created_by
                      ? (q.created_by === q.user_id ? "Admin" : (createdByNames[q.created_by] || "Usuário"))
                      : "-";

                    return (
                      <div
                        key={q.id}
                        className="group relative flex h-full flex-col overflow-hidden rounded-2xl border border-gray-100 bg-white p-5 transition-all duration-200 hover:border-gray-300 hover:shadow-sm"
                      >
                        <div className="mb-4 flex items-start justify-between gap-3">
                          <div className="min-w-0 flex-1">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Orçamento</span>
                            <div className="mt-1 text-xl font-black tracking-tight text-gray-900">#{q.number}</div>
                            <span className="mt-1 inline-block text-xs font-medium text-gray-500">
                              Criado em {new Date(q.created_at).toLocaleDateString("pt-BR")}
                            </span>
                          </div>
                          <div className="flex flex-col items-end gap-1.5">
                            <span className={`inline-flex shrink-0 rounded-md border px-2 py-1 text-[10px] font-bold uppercase tracking-wide ${getQuoteStatusBadgeClass(q.status)}`}>
                              {statusLabel[q.status]}
                            </span>
                            {q.list_price_mode ? (
                              <span className="inline-flex rounded-md border border-indigo-100 bg-indigo-50 px-2 py-1 text-[10px] font-bold uppercase tracking-wide text-indigo-700">
                                Lista de Preço
                              </span>
                            ) : null}
                          </div>
                        </div>

                        <div className="mb-4">
                          <div className="flex items-center gap-3">
                            <div className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-sm font-bold text-white ${getQuoteClientAvatarClass(clientTitle)}`}>
                              {clientTitle.substring(0, 2).toUpperCase()}
                            </div>
                            <div className="min-w-0">
                              <h3 className="truncate text-base font-semibold leading-tight text-gray-900" title={clientTitle}>
                                {clientTitle}
                              </h3>
                              {clientSubtitle ? (
                                <p className="truncate text-xs font-medium text-gray-500">{clientSubtitle}</p>
                              ) : null}
                            </div>
                          </div>
                          {isDeletedClient ? (
                            <div className="mt-2">
                              <span className="inline-flex rounded-md bg-red-50 px-2 py-1 text-[10px] font-bold uppercase tracking-wide text-red-600">
                                Cliente Excluído
                              </span>
                            </div>
                          ) : null}
                        </div>

                        <div className="mb-5 flex-1">
                          <div className="rounded-xl bg-gray-50 p-3">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Título</span>
                            <p className="mt-1 line-clamp-2 text-sm font-medium text-gray-700">
                              {q.title || "Sem título"}
                            </p>
                          </div>
                        </div>

                        <div className="mb-5 grid grid-cols-2 gap-3 rounded-xl bg-gray-50 p-3">
                          <div className="flex flex-col">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Criado por</span>
                            <span className="mt-0.5 truncate text-xs font-medium text-gray-700">{creatorName}</span>
                          </div>
                          <div className="flex flex-col">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Link público</span>
                            <div className="mt-0.5 flex items-center gap-1.5 text-xs font-medium text-indigo-700">
                              {q.share_enabled ? <Eye size={12} /> : <Link2 size={12} />}
                              <span>{q.share_enabled ? `${q.public_view_count ?? 0} views` : "Gerar link"}</span>
                              <button
                                type="button"
                                onClick={() => handleCopyLink(q)}
                                disabled={sharingQuoteId === q.id}
                                className="ml-1 flex h-5 w-5 items-center justify-center rounded-full border border-indigo-200 bg-white text-indigo-700 transition hover:bg-indigo-50 disabled:cursor-not-allowed disabled:opacity-60"
                                title={copiedQuoteId === q.id ? "Link copiado" : "Copiar link"}
                              >
                                {copiedQuoteId === q.id ? <Check size={12} /> : <Copy size={12} />}
                              </button>
                            </div>
                          </div>
                        </div>

                        {/* O total numa linha e os botões embaixo, dividindo a largura do cartão: cabem com qualquer valor. */}
                        <div className="mt-auto flex flex-col gap-3">
                          <div className="flex flex-col">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Total</span>
                            <span className="mt-0.5 text-lg font-black leading-none tracking-tight text-gray-900">
                              {formatMoney(Number(q.total))}
                            </span>
                          </div>
                          <div className="flex items-center gap-2">
                            <Link href={`/dashboard/quotes/${q.id}`} className="flex min-w-0 flex-1">
                              <button
                                className="flex h-9 min-w-0 flex-1 items-center justify-center rounded-lg border border-gray-200 bg-white text-gray-600 transition-colors hover:bg-gray-50"
                                title={q.status === "rejected" ? "Visualizar" : "Abrir"}
                              >
                                {q.status === "rejected" ? <Eye size={16} /> : <FileText size={16} />}
                              </button>
                            </Link>
                            {podeMexerEmOrcamentos && (
                            <button
                              type="button"
                              onClick={() => handleDuplicateQuote(q)}
                              disabled={duplicatingQuoteId === q.id}
                              className="flex h-9 min-w-0 flex-1 items-center justify-center rounded-lg border border-gray-200 bg-white text-gray-600 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60"
                              title="Duplicar orçamento"
                            >
                              <Copy size={16} />
                            </button>
                            )}
                            {podeRecusar(q) && (
                              <button
                                type="button"
                                onClick={() => pedirRecusa(q)}
                                className="flex h-9 min-w-0 flex-1 items-center justify-center rounded-lg border border-gray-200 bg-white text-amber-600 transition-colors hover:bg-amber-50"
                                title="Recusar orçamento"
                                aria-label="Recusar orçamento"
                                data-recusar-orcamento
                              >
                                <Ban size={16} />
                              </button>
                            )}
                            {podeMexerEmOrcamentos && q.status !== "rejected" && !q.orders && (
                              <button
                                onClick={() => handleDelete(q)}
                                className="flex h-9 min-w-0 flex-1 items-center justify-center rounded-lg border border-gray-200 bg-white text-red-500 transition-colors hover:bg-red-50"
                                title="Excluir"
                              >
                                <Trash2 size={16} />
                              </button>
                            )}
                            {q.orders && (
                              <Link href={`/dashboard/orders/${q.orders.id}`} className="flex min-w-0 flex-1">
                                <button
                                  className="flex h-9 min-w-0 flex-1 items-center justify-center rounded-lg border border-emerald-200 bg-emerald-50 text-emerald-700 transition-colors hover:bg-emerald-100"
                                  title={`Ver Pedido #${q.orders.number}`}
                                >
                                  <CheckCircle2 size={16} />
                                </button>
                              </Link>
                            )}
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
              ) : (
                <div className="flex flex-col gap-3">
                  {filtered.map((q) => {
                    const clientTitle = q.client?.company_name
                      ? q.client.company_name
                      : q.client?.name || "Cliente sem nome";
                    const clientSubtitle = q.client?.company_name ? q.client?.name : "";
                    const isDeletedClient = Boolean(q.client?.is_deleted);
                    const creatorName = q.created_by
                      ? (q.created_by === q.user_id ? "Admin" : (createdByNames[q.created_by] || "Usuário"))
                      : "-";
                    
                    return (
                      <div
                        key={q.id}
                        className="group relative overflow-hidden rounded-2xl border border-gray-100 bg-white p-4 transition-all duration-200 hover:border-gray-300 hover:shadow-sm"
                      >
                        <div className={`absolute left-0 top-0 bottom-0 w-1.5 ${
                          q.status === "approved" || q.status === "delivered" ? "bg-emerald-500" :
                          q.status === "rejected" ? "bg-red-500" :
                          q.status === "production" ? "bg-amber-500" :
                          q.status === "sent" ? "bg-indigo-500" :
                          "bg-gray-300"
                        }`} />

                        {/* As colunas de texto encolhem (com reticências) e a dos botões fica do tamanho deles: em 1280 com o menu aberto a linha passava da borda. */}
                        <div className="flex flex-col gap-4 pl-2 xl:grid xl:grid-cols-[minmax(0,1.8fr)_minmax(170px,0.9fr)_minmax(0,1.15fr)_minmax(110px,0.7fr)_auto] xl:items-center xl:gap-4 xl:pl-3">
                          <div className="flex min-w-0 items-center gap-3">
                            <div className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-sm font-bold text-white ${getQuoteClientAvatarClass(clientTitle)}`}>
                              {clientTitle.substring(0, 2).toUpperCase()}
                            </div>
                            <div className="min-w-0">
                              <span className="block truncate text-base font-semibold text-gray-900" title={clientTitle}>
                                {clientTitle}
                              </span>
                              {clientSubtitle ? (
                                <span className="mt-0.5 block truncate text-xs font-medium text-gray-500">{clientSubtitle}</span>
                              ) : null}
                              {isDeletedClient ? (
                                <span className="mt-1 inline-flex w-fit rounded-md bg-red-50 px-2 py-1 text-[10px] font-bold uppercase tracking-wide text-red-600">
                                  Cliente Excluído
                                </span>
                              ) : null}
                            </div>
                          </div>

                          <div className="flex min-w-[170px] items-center gap-3 xl:border-l xl:border-gray-100 xl:pl-4">
                            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-gray-200 bg-gray-50 text-xs font-bold text-gray-500">
                              #{q.number}
                            </div>
                            <div className="flex flex-col">
                              <span className={`inline-flex w-fit rounded-md border px-2 py-1 text-[10px] font-bold uppercase tracking-wide ${getQuoteStatusBadgeClass(q.status)}`}>
                                {statusLabel[q.status]}
                              </span>
                              {q.list_price_mode ? (
                                <span className="mt-1 inline-flex w-fit rounded-md border border-indigo-100 bg-indigo-50 px-2 py-1 text-[9px] font-bold uppercase tracking-wide text-indigo-700">
                                  Lista de Preço
                                </span>
                              ) : null}
                              <span className="mt-1 text-[10px] font-medium text-gray-500">
                                {new Date(q.created_at).toLocaleDateString("pt-BR")}
                              </span>
                            </div>
                          </div>

                          <div className="flex flex-col gap-1.5 text-[11px] text-gray-500 xl:border-l xl:border-gray-100 xl:pl-4">
                            <div className="flex flex-col">
                              <span className="text-[9px] font-semibold uppercase tracking-wider text-gray-400">Título</span>
                              <span className="mt-0.5 truncate font-medium text-gray-700" title={q.title || "Sem título"}>
                                {q.title || "Sem título"}
                              </span>
                            </div>
                            <div className="flex flex-col">
                              <span className="text-[9px] font-semibold uppercase tracking-wider text-gray-400">Criado por</span>
                              <span className="mt-0.5 truncate font-medium text-gray-700">{creatorName}</span>
                            </div>
                            <div className="flex items-center gap-1.5 text-indigo-700">
                              {q.share_enabled ? <Eye size={12} /> : <Link2 size={12} />}
                              <span>{q.share_enabled ? `${q.public_view_count ?? 0} views` : "Gerar link"}</span>
                              <button
                                type="button"
                                onClick={() => handleCopyLink(q)}
                                disabled={sharingQuoteId === q.id}
                                className="ml-1 flex h-5 w-5 items-center justify-center rounded-full border border-indigo-200 bg-white text-indigo-700 transition hover:bg-indigo-50 disabled:cursor-not-allowed disabled:opacity-60"
                                title={copiedQuoteId === q.id ? "Link copiado" : "Copiar link"}
                              >
                                {copiedQuoteId === q.id ? <Check size={12} /> : <Copy size={12} />}
                              </button>
                            </div>
                          </div>

                          <div className="flex flex-col xl:items-end xl:border-l xl:border-gray-100 xl:pl-4">
                            <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">Total</span>
                            <span className="mt-0.5 text-sm font-black leading-none tracking-tight text-gray-900">
                              {formatMoney(Number(q.total))}
                            </span>
                          </div>

                          <div className="flex items-center gap-2 xl:justify-end xl:border-l xl:border-gray-100 xl:pl-4">
                            <Link href={`/dashboard/quotes/${q.id}`}>
                              <button
                                className="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 bg-white text-gray-600 transition-colors hover:bg-gray-50"
                                title={q.status === "rejected" ? "Visualizar" : "Abrir"}
                              >
                                {q.status === "rejected" ? <Eye size={16} /> : <FileText size={16} />}
                              </button>
                            </Link>
                            {podeMexerEmOrcamentos && (
                            <button
                              type="button"
                              onClick={() => handleDuplicateQuote(q)}
                              disabled={duplicatingQuoteId === q.id}
                              className="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 bg-white text-gray-600 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60"
                              title="Duplicar orçamento"
                            >
                              <Copy size={16} />
                            </button>
                            )}
                            {podeRecusar(q) && (
                              <button
                                type="button"
                                onClick={() => pedirRecusa(q)}
                                className="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 bg-white text-amber-600 transition-colors hover:bg-amber-50"
                                title="Recusar orçamento"
                                aria-label="Recusar orçamento"
                                data-recusar-orcamento
                              >
                                <Ban size={16} />
                              </button>
                            )}
                            {podeMexerEmOrcamentos && q.status !== "rejected" && !q.orders && (
                              <button
                                onClick={() => handleDelete(q)}
                                className="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 bg-white text-red-500 transition-colors hover:bg-red-50"
                                title="Excluir"
                              >
                                <Trash2 size={16} />
                              </button>
                            )}
                            {q.orders && (
                              <Link href={`/dashboard/orders/${q.orders.id}`}>
                                <button
                                  className="flex h-10 w-10 items-center justify-center rounded-lg border border-emerald-200 bg-emerald-50 text-emerald-700 transition-colors hover:bg-emerald-100"
                                  title={`Ver Pedido #${q.orders.number}`}
                                >
                                  <CheckCircle2 size={16} />
                                </button>
                              </Link>
                            )}
                          </div>
                        </div>
                      </div>
                    );
                  })}
                </div>
              )}
            </>
          )}
        </div>
      
      {quickQuoteModalOpen ? (
        <div
          aria-hidden
          className="fixed inset-0 z-40 bg-[rgba(17,24,39,0.28)] backdrop-blur-sm"
        />
      ) : null}

      <Dialog modal={false} open={quickQuoteModalOpen} onOpenChange={(open) => !open && closeQuickQuoteModal()}>
        <DialogContent
          className="sm:max-w-3xl overflow-hidden"
          onInteractOutside={(event) => {
            const target = event.target as HTMLElement | null;
            if (target?.closest?.('[data-ks-select-dropdown="true"]')) {
              event.preventDefault();
              return;
            }
            event.preventDefault();
          }}
        >
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Sparkles className="text-[var(--ks-color-primary)]" size={18} />
              {"Or\u00e7amento R\u00e1pido"}
            </DialogTitle>
            <DialogDescription>
              Crie um rascunho imediato sem cliente cadastrado. Para gerar pedido depois, complete o cliente no orçamento.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="grid grid-cols-3 gap-2">
              <div
                className={`h-1.5 rounded-full ${
                  quickQuoteStep === "details" ? "bg-[var(--ks-color-primary)]" : "bg-zinc-200"
                }`}
              />
              <div
                className={`h-1.5 rounded-full ${
                  quickQuoteStep === "review" ? "bg-[var(--ks-color-primary)]" : "bg-zinc-200"
                }`}
              />
              <div
                className={`h-1.5 rounded-full ${
                  quickQuoteStep === "done" ? "bg-emerald-500" : "bg-zinc-200"
                }`}
              />
            </div>

            {quickQuoteStep === "details" && (
              <div className="space-y-4">
                <div className="space-y-1">
                  <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Titulo (opcional)</label>
                  <Input value={quickTitle} onChange={(e) => setQuickTitle(e.target.value)} placeholder="Ex: Orcamento para campanha de maio" />
                </div>
                <div className="space-y-1">
                  <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Observacoes (opcional)</label>
                  <textarea
                    value={quickNotes}
                    onChange={(e) => setQuickNotes(e.target.value)}
                    placeholder="Prazo, acabamento, observacoes..."
                    className="w-full min-h-[88px] rounded-md border border-zinc-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/25"
                  />
                </div>
                <div className="rounded-xl border border-zinc-200 bg-zinc-50/60 p-4 space-y-3">
                  <div className="flex items-center justify-between gap-3">
                    <div>
                      <p className="text-sm font-semibold text-zinc-900">Produtos</p>
                      <p className="text-xs text-zinc-500">Use produtos cadastrados no sistema.</p>
                    </div>
                    <Button type="button" variant="outline" onClick={addQuickItem} disabled={quickProductsLoading} icon={<Plus size={14} />}>
                      Adicionar produto
                    </Button>
                  </div>

                  {quickProductsLoading && (
                    <div className="rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-600">Carregando produtos...</div>
                  )}

                  {!quickProductsLoading && quickProducts.length === 0 && (
                    <div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-700">
                      Nenhum produto ativo encontrado.
                    </div>
                  )}

                  <div className="space-y-3 max-h-[42vh] overflow-y-auto overflow-x-hidden pr-1">
                    {quickItems.map((item, index) => {
                      const selectedProduct = item.product_id ? quickProductsById.get(item.product_id) : null;
                      const quantityRuleMessage = getQuickItemQuantityRuleMessage(item, selectedProduct);
                      const allowedQuantities = getAllowedItemQuantities(selectedProduct);
                      const usesAllowedQuantities = Boolean(selectedProduct?.allowed_sale_qty_enabled) && allowedQuantities.length > 0;
                      const selectedAllowedQuantity = usesAllowedQuantities
                        ? allowedQuantities.find((value) => Math.abs(value - Number(item.quantity || 0)) <= 0.000001)
                        : null;
                      const lineTotal = totalDoItemRapido(item);
                      return (
                        <div key={item.id} className="rounded-xl border border-zinc-200 bg-white p-3 space-y-3">
                          <div className="grid grid-cols-1 gap-3 lg:grid-cols-12">
                            <div className="space-y-1 lg:col-span-6">
                              <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Produto</label>
                              <CustomSelect
                                options={[
                                  { value: "__manual__", label: "Item manual" },
                                  { value: "", label: "Selecione um produto" },
                                  ...quickProducts.map((product) => ({
                                    value: product.id,
                                    label: `${product.name} (${unitLabel(product.unit_type || "unit")}) - ${product.price_on_request ? "Sob consulta" : formatMoney(product.price || 0)}`,
                                    image_url: product.image_url || "https://placehold.co/100x100/f4f4f5/a1a1aa?text=IMG",
                                  })),
                                ]}
                                value={item.product_id || (item.title.trim() ? "__manual__" : "")}
                                onChange={(value) => {
                                  if (!value) {
                                    updateQuickItem(index, {
                                      product_id: "",
                                      title: "",
                                      unit_type: "unit",
                                      width_m: "0,00",
                                      height_m: "0,00",
                                      length_m: "0,00",
                                      unit_price: "0,00",
                                    });
                                    return;
                                  }
                                  if (value === "__manual__") {
                                    updateQuickItem(
                                      index,
                                      {
                                        product_id: "",
                                        title: item.title || "",
                                        unit_type: "unit",
                                        width_m: "0,00",
                                        height_m: "0,00",
                                        length_m: "0,00",
                                        quantity: Math.max(1, item.quantity || 1),
                                        unit_price: item.unit_price || "0,00",
                                      },
                                      { forceRecalculate: false }
                                    );
                                    return;
                                  }
                                  const selected = quickProductsById.get(value);
                                  if (!selected) return;
                                  const minQty = getMinimumItemQuantity(selected);
                                  const nextDraft: QuickQuoteItemDraft = {
                                    ...item,
                                    product_id: selected.id,
                                    title: selected.name,
                                    unit_type: selected.unit_type || "unit",
                                    width_m: "0,00",
                                    height_m: "0,00",
                                    length_m: "0,00",
                                    quantity: Math.max(minQty, item.quantity || minQty),
                                    unit_price: "0,00",
                                  };
                                  updateQuickItem(
                                    index,
                                    {
                                      product_id: selected.id,
                                      title: selected.name,
                                      unit_type: selected.unit_type || "unit",
                                      width_m: "0,00",
                                      height_m: "0,00",
                                      length_m: "0,00",
                                      quantity: Math.max(minQty, item.quantity || minQty),
                                      unit_price: formatUnitPriceValue(resolveQuickProductUnitPrice(nextDraft, selected)),
                                    },
                                    { forceRecalculate: true }
                                  );
                                }}
                                searchable
                              />
                              {!item.product_id && (
                                <div className="space-y-1 pt-1">
                                  <Input
                                    value={item.title}
                                    onChange={(e) => updateQuickItem(index, { title: e.target.value })}
                                    placeholder="Nome do item manual"
                                  />
                                  <button
                                    type="button"
                                    onClick={() => registerQuickManualItemAsProduct(item.id)}
                                    disabled={!canRegisterQuickManualItem(item) || quickManualProductSubmittingItemId === item.id}
                                    className="inline-flex h-6 items-center rounded-md border border-[var(--ks-color-primary-soft-strong)] px-2 text-[11px] font-semibold text-[var(--ks-color-primary)] hover:bg-[rgba(68,37,167,0.08)] disabled:opacity-45 disabled:cursor-not-allowed"
                                  >
                                    {quickManualProductSubmittingItemId === item.id ? "Cadastrando..." : "Cadastrar produto"}
                                  </button>
                                  {quickManualProductErrors[item.id] ? (
                                    <p className="text-[11px] font-medium text-rose-600">{quickManualProductErrors[item.id]}</p>
                                  ) : null}
                                </div>
                              )}
                            </div>

                            <div className="space-y-1 lg:col-span-2">
                              <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Qtd</label>
                              {usesAllowedQuantities ? (
                                <CustomSelect
                                  options={allowedQuantities.map((value) => ({
                                    value: String(value),
                                    label: formatQuantityLimit(value),
                                  }))}
                                  value={String(selectedAllowedQuantity ?? allowedQuantities[0])}
                                  onChange={(value) => {
                                    const parsed = Number(value);
                                    if (!Number.isFinite(parsed) || parsed <= 0) return;
                                    updateQuickItem(index, { quantity: parsed }, { forceRecalculate: true });
                                  }}
                                />
                              ) : (
                                <Input
                                  type="number"
                                  min={getMinimumItemQuantity(selectedProduct)}
                                  value={String(item.quantity)}
                                  onChange={(e) => {
                                    const minQty = getMinimumItemQuantity(selectedProduct);
                                    updateQuickItem(index, { quantity: Math.max(minQty, Number(e.target.value) || minQty) });
                                  }}
                                  className="[appearance:textfield] [-moz-appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
                                />
                              )}
                            </div>

                            <div className="space-y-1 lg:col-span-2">
                              <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Unidade</label>
                              {item.product_id ? (
                                <div className="h-10 rounded-md border border-zinc-200 bg-zinc-50 px-3 text-sm font-medium text-zinc-700 flex items-center">
                                  {unitLabel(item.unit_type || "unit")}
                                </div>
                              ) : (
                                <CustomSelect
                                  options={[
                                    { value: "unit", label: "Unidade" },
                                    { value: "meter", label: "Metro" },
                                    { value: "linear_meter", label: "Metro Linear" },
                                    { value: "square_meter", label: "Metro Quadrado" },
                                    { value: "box", label: "Caixa" },
                                    { value: "ream", label: "Resma" },
                                  ]}
                                  value={item.unit_type || "unit"}
                                  onChange={(value) =>
                                    updateQuickItem(index, {
                                      unit_type: value,
                                      width_m: value === "square_meter" ? item.width_m : "0,00",
                                      height_m: value === "square_meter" ? item.height_m : "0,00",
                                      length_m: value === "meter" || value === "linear_meter" ? item.length_m : "0,00",
                                    })
                                  }
                                />
                              )}
                            </div>

                            <div className="space-y-1 lg:col-span-2">
                              <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Valor unitario</label>
                              <Input
                                value={item.unit_price}
                                onChange={(e) => updateQuickItem(index, { unit_price: formatMoneyInput(e.target.value) })}
                                placeholder="0,00"
                              />
                            </div>
                          </div>

                          {(item.unit_type === "square_meter" || item.unit_type === "meter" || item.unit_type === "linear_meter") && (
                            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                              {item.unit_type === "square_meter" ? (
                                <>
                                  <div className="space-y-1">
                                    <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Largura (m)</label>
                                    <Input value={item.width_m} onChange={(e) => updateQuickItem(index, { width_m: formatMeasureInput(e.target.value) })} />
                                  </div>
                                  <div className="space-y-1">
                                    <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Altura (m)</label>
                                    <Input value={item.height_m} onChange={(e) => updateQuickItem(index, { height_m: formatMeasureInput(e.target.value) })} />
                                  </div>
                                </>
                              ) : (
                                <div className="space-y-1 sm:col-span-2">
                                  <label className="text-xs font-semibold uppercase tracking-wide text-zinc-500">Comprimento (m)</label>
                                  <Input value={item.length_m} onChange={(e) => updateQuickItem(index, { length_m: formatMeasureInput(e.target.value) })} />
                                </div>
                              )}
                            </div>
                          )}

                          <div className="flex items-center justify-between gap-3">
                            <span className="text-xs text-zinc-500">Total do item: {formatMoney(lineTotal)}</span>
                            <button
                              type="button"
                              onClick={() => removeQuickItem(index)}
                              className="inline-flex h-8 w-8 items-center justify-center rounded-full border border-zinc-200 text-zinc-500 transition hover:border-red-200 hover:bg-red-50 hover:text-red-600"
                              title="Remover item"
                              disabled={quickItems.length === 1}
                            >
                              <Trash2 size={14} />
                            </button>
                          </div>
                          {item.minimo && (
                            <div className="rounded-lg border border-sky-200 bg-sky-50 px-3 py-2 text-xs font-medium text-sky-800">
                              {textoDoMinimoAplicado(item.minimo.minimo, item.minimo.semMinimo)}
                            </div>
                          )}
                          {quantityRuleMessage && (
                            <div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs font-medium text-amber-700">
                              {quantityRuleMessage}
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              </div>
            )}

            {quickQuoteStep === "review" && (
              <div className="space-y-3 rounded-xl border border-zinc-200 bg-zinc-50/60 p-4">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <p className="text-xs uppercase tracking-wide text-zinc-500">Resumo</p>
                    <p className="text-sm font-semibold text-zinc-900">{quickTitle.trim() || "Orcamento rapido"}</p>
                  </div>
                  <span className="rounded-full border border-zinc-200 bg-white px-2.5 py-1 text-xs font-semibold text-zinc-600">
                    Rascunho
                  </span>
                </div>
                <div className="space-y-2">
                  {quickSummaryItems.map((item) => {
                    const lineTotal = totalDoItemRapido(item);
                    return (
                      <div key={item.id} className="rounded-lg border border-zinc-200 bg-white p-3 space-y-1">
                        <p className="text-sm font-semibold text-zinc-900">{item.title}</p>
                        <p className="text-xs text-zinc-500">
                          {quantidadeDoItem(item).pecasTexto}
                          {quantidadeDoItem(item).total ? ` · ${quantidadeDoItem(item).total}` : ""}
                          {item.minimo ? (
                            " · Valor mínimo"
                          ) : (
                            <>
                              {" "}x {formatMoney(parseMoneyInput(item.unit_price))}
                              {quantidadeDoItem(item).unidadeDeVenda !== "un" ? `/${quantidadeDoItem(item).unidadeDeVenda === "m2" ? "m²" : "m"}` : ""}
                            </>
                          )}
                        </p>
                        {item.minimo && (
                          <p className="text-xs text-sky-700">{textoDoMinimoAplicado(item.minimo.minimo, item.minimo.semMinimo)}</p>
                        )}
                        <p className="text-xs font-semibold text-zinc-700">Total: {formatMoney(lineTotal)}</p>
                      </div>
                    );
                  })}
                </div>
                <div className="flex items-center justify-between rounded-lg bg-[rgba(68,37,167,0.08)] border border-[rgba(68,37,167,0.2)] px-3 py-2">
                  <span className="text-sm font-semibold text-zinc-700">Total estimado</span>
                  <span className="text-base font-extrabold text-[var(--ks-color-primary-strong)]">{formatMoney(quickEstimatedTotal)}</span>
                </div>
              </div>
            )}

            {quickQuoteStep === "done" && (
              <div className="relative overflow-hidden rounded-xl border border-emerald-200 bg-emerald-50 p-5 text-center">
                <div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-emerald-500 text-white">
                  <Check size={22} />
                </div>
                <p className="text-base font-bold text-emerald-800">Orcamento rapido criado com sucesso</p>
                <p className="mt-1 text-sm text-emerald-700">
                  {quickCreatedQuote?.number ? `Orcamento #${quickCreatedQuote.number}` : "Rascunho pronto para completar"}
                </p>
                <p className="mt-2 text-xs text-emerald-700/90">
                  Agora complete os dados do cliente para poder aprovar e virar pedido.
                </p>

                <AnimatePresence>
                  {quickConfettiVisible ? (
                    <div className="pointer-events-none absolute inset-0">
                      {quickConfettiPieces.map((piece, index) => (
                        <motion.span
                          key={`${quickConfettiSeed}-${index}`}
                          initial={{ opacity: 0, y: -24, x: 0, rotate: piece.rotate }}
                          animate={{
                            opacity: 1,
                            y: 230,
                            x: piece.xDrift,
                            rotate: piece.rotate + 220,
                          }}
                          exit={{ opacity: 0 }}
                          transition={{ duration: piece.duration, delay: piece.delay, ease: "easeOut" }}
                          style={{
                            left: `${piece.left}%`,
                            width: `${piece.size}px`,
                            height: `${piece.size * 1.4}px`,
                            backgroundColor: piece.color,
                          }}
                          className="absolute top-0 rounded-sm"
                        />
                      ))}
                    </div>
                  ) : null}
                </AnimatePresence>
              </div>
            )}

            {quickQuoteError && (
              <div className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
                {quickQuoteError}
              </div>
            )}
          </div>

          <DialogFooter>
            {quickQuoteStep === "details" && (
              <>
                <Button variant="outline" onClick={closeQuickQuoteModal}>
                  Fechar
                </Button>
                <Button onClick={handleQuickQuoteNextStep} disabled={quickProductsLoading}>
                  Continuar
                </Button>
              </>
            )}

            {quickQuoteStep === "review" && (
              <>
                <Button variant="outline" onClick={() => setQuickQuoteStep("details")} disabled={quickQuoteSaving}>
                  Voltar
                </Button>
                <Button onClick={handleCreateQuickQuote} disabled={quickQuoteSaving}>
                  {quickQuoteSaving ? "Criando..." : "Concluir"}
                </Button>
              </>
            )}

            {quickQuoteStep === "done" && (
              <>
                <Button variant="outline" onClick={closeQuickQuoteModal}>
                  Fechar
                </Button>
                <Button onClick={openQuickCreatedQuote} disabled={!quickCreatedQuote?.id}>
                  Abrir orçamento
                </Button>
              </>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={linkExpiryModal.open} onOpenChange={(open) => !open && setLinkExpiryModal((prev) => ({ ...prev, open: false }))}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Validade do link público</DialogTitle>
            <DialogDescription>
              Defina se o link do orçamento público expira e em quantos dias.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="flex items-center justify-between gap-3 rounded-lg border border-zinc-200 px-3 py-2">
              <div className="min-w-0">
                <div className="text-sm font-semibold text-zinc-900">Sem prazo de validade</div>
                <div className="text-xs text-zinc-500">O link fica ativo até você desativar o compartilhamento.</div>
              </div>
              <Switch
                checked={!linkExpiryModal.enabled}
                onCheckedChange={(checked) => setLinkExpiryModal((prev) => ({ ...prev, enabled: !checked }))}
              />
            </div>

            <div className="space-y-2">
              <div className="text-sm font-semibold text-zinc-900">Com validade</div>
              <div className="text-xs text-zinc-500">Informe a duração em dias.</div>
              <Input
                type="number"
                min={1}
                value={linkExpiryModal.days}
                onChange={(e) => setLinkExpiryModal((prev) => ({ ...prev, days: e.target.value }))}
                disabled={!linkExpiryModal.enabled}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setLinkExpiryModal((prev) => ({ ...prev, open: false }))}>
              Cancelar
            </Button>
            <Button onClick={saveLinkExpiryModal}>Salvar</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Dialog */}
      <Dialog open={errorModal.open} onOpenChange={(open) => !open && setErrorModal(prev => ({ ...prev, open: false }))}>
        <DialogContent>
            <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                    <AlertCircle className="text-destructive" size={20} />
                    {errorModal.title}
                </DialogTitle>
                <DialogDescription>{errorModal.description}</DialogDescription>
            </DialogHeader>
            <DialogFooter>
                <Button variant="outline" onClick={() => setErrorModal(prev => ({ ...prev, open: false }))}>
                    Fechar
                </Button>
                {errorModal.action && (
                    <Button variant="destructive" onClick={() => {
                        errorModal.action?.onClick();
                    }}>
                        {errorModal.action.label}
                    </Button>
                )}
            </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Confirmation Dialog */}
      <Dialog open={confirmModal.open} onOpenChange={(open) => !open && !confirmModal.isLoading && setConfirmModal(prev => ({ ...prev, open: false }))}>
        <DialogContent>
            <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                    <AlertCircle className="text-amber-500" size={20} />
                    {confirmModal.title}
                </DialogTitle>
                <DialogDescription>{confirmModal.description}</DialogDescription>
            </DialogHeader>
            <DialogFooter>
                <Button variant="outline" onClick={() => setConfirmModal(prev => ({ ...prev, open: false }))} disabled={confirmModal.isLoading}>
                    Cancelar
                </Button>
                <Button variant="destructive" onClick={confirmModal.action} disabled={confirmModal.isLoading}>
                    {confirmModal.isLoading ? confirmModal.rotuloEsperando || "Excluindo..." : confirmModal.rotulo || "Excluir"}
                </Button>
            </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
