import { useMemo, useState } from "react";

import { z } from "zod";
import { toast } from "sonner";
import {
  ArrowLeft,
  ArrowRight,
  Check,
  CheckCircle2,
  Plus,
  Trash2,
  User,
  Package,
  FileText,
  CreditCard,
  Calendar,
  Eye,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { cn } from "@/lib/utils";
import { mockServices, categoryLabel } from "@/lib/mock/services";
import { formatBRL, formatDate } from "@/lib/format";
import type { ProposalStatus } from "@/lib/mock/types";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";

// ---------------- Types & schemas ----------------

export type ProposalItem = {
  serviceId: string;
  name: string;
  unitPrice: number;
  quantity: number;
  recurring: "mensal" | "anual" | null;
};

export type PaymentMethod = "pix" | "boleto" | "cartao";

export type ProposalDraft = {
  // Cliente
  clientName: string;
  contactName: string;
  email: string;
  whatsapp: string;
  website: string;
  // Proposta
  title: string;
  items: ProposalItem[];
  scope: string;
  deliverables: string[];
  observations: string;
  deadlineDays: number;
  validUntil: string;
  paymentMethods: PaymentMethod[];
  installments: number;
  // Apenas no modo edição
  status: ProposalStatus;
};

const clientSchema = z.object({
  clientName: z.string().trim().min(2, "Informe o nome do cliente").max(120),
  contactName: z.string().trim().min(2, "Informe o responsável").max(120),
  email: z.string().trim().email("E-mail inválido").max(180),
  whatsapp: z.string().trim().min(8, "WhatsApp inválido").max(30),
  website: z.string().trim().max(180).optional().or(z.literal("")),
  title: z.string().trim().min(3, "Informe o título da proposta").max(140),
});

const proposalSchema = z.object({
  items: z
    .array(
      z.object({
        serviceId: z.string(),
        name: z.string(),
        unitPrice: z.number().min(0),
        quantity: z.number().min(1),
        recurring: z.union([z.literal("mensal"), z.literal("anual"), z.null()]),
      }),
    )
    .min(1, "Selecione ao menos 1 serviço"),
});

const scopeSchema = z.object({
  scope: z.string().trim().min(10, "Descreva o escopo (mín. 10 caracteres)").max(2000),
  deliverables: z
    .array(z.string().trim().min(1).max(160))
    .min(1, "Adicione pelo menos uma entrega"),
  observations: z.string().trim().max(2000).optional().or(z.literal("")),
});

const paymentSchema = z.object({
  paymentMethods: z
    .array(z.enum(["pix", "boleto", "cartao"]))
    .min(1, "Selecione ao menos uma forma de pagamento"),
  installments: z.number().int().min(1).max(12),
});

const deadlineSchema = z.object({
  deadlineDays: z.number().int().min(1).max(365),
  validUntil: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Data inválida"),
});

const STEPS = [
  { id: 1, title: "Cliente", icon: User },
  { id: 2, title: "Serviços", icon: Package },
  { id: 3, title: "Escopo", icon: FileText },
  { id: 4, title: "Pagamento", icon: CreditCard },
  { id: 5, title: "Prazo", icon: Calendar },
  { id: 6, title: "Revisão", icon: Eye },
] as const;

export type ProposalWizardTotals = { oneTime: number; recurring: number };

export type ProposalWizardProps = {
  mode: "create" | "edit";
  title: string;
  subtitle?: string;
  initial: ProposalDraft;
  submitLabel: string;
  onSubmit: (draft: ProposalDraft, totals: ProposalWizardTotals) => void;
  backSlot: React.ReactNode;
  summaryHint?: string;
};

export function ProposalWizard({
  mode,
  title,
  subtitle,
  initial,
  submitLabel,
  onSubmit,
  backSlot,
  summaryHint,
}: ProposalWizardProps) {

  const [step, setStep] = useState(1);
  const [draft, setDraft] = useState<ProposalDraft>(initial);
  const [confirmOpen, setConfirmOpen] = useState(false);

  const update = <K extends keyof ProposalDraft>(key: K, value: ProposalDraft[K]) =>
    setDraft((d) => ({ ...d, [key]: value }));

  const totals = useMemo<ProposalWizardTotals>(() => {
    const oneTime = draft.items
      .filter((i) => !i.recurring)
      .reduce((s, i) => s + i.unitPrice * i.quantity, 0);
    const recurring = draft.items
      .filter((i) => i.recurring === "mensal")
      .reduce((s, i) => s + i.unitPrice * i.quantity, 0);
    return { oneTime, recurring };
  }, [draft.items]);

  const validateStep = (s: number): string[] => {
    const errs: string[] = [];
    const collect = (r: z.SafeParseReturnType<unknown, unknown>) => {
      if (!r.success) r.error.issues.forEach((i) => errs.push(i.message));
    };
    if (s === 1) collect(clientSchema.safeParse(draft));
    if (s === 2) collect(proposalSchema.safeParse(draft));
    if (s === 3)
      collect(
        scopeSchema.safeParse({
          scope: draft.scope,
          deliverables: draft.deliverables.filter((d) => d.trim() !== ""),
          observations: draft.observations,
        }),
      );
    if (s === 4) collect(paymentSchema.safeParse(draft));
    if (s === 5) collect(deadlineSchema.safeParse(draft));
    return errs;
  };

  const next = () => {
    const errs = validateStep(step);
    if (errs.length) {
      toast.error(errs[0]);
      return;
    }
    setStep((s) => Math.min(6, s + 1));
  };
  const prev = () => setStep((s) => Math.max(1, s - 1));

  const doSubmit = () => {
    onSubmit(
      {
        ...draft,
        deliverables: draft.deliverables.filter((d) => d.trim() !== ""),
      },
      totals,
    );
  };

  const handleSave = () => {
    for (let s = 1; s <= 5; s++) {
      const errs = validateStep(s);
      if (errs.length) {
        setStep(s);
        toast.error(errs[0]);
        return;
      }
    }
    if (mode === "edit") {
      setConfirmOpen(true);
      return;
    }
    doSubmit();
  };



  return (
    <div className="space-y-6">
      {backSlot}



      <div className="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
        <div>
          <h1 className="font-display text-2xl font-semibold sm:text-3xl">{title}</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            {subtitle ? `${subtitle} · ` : ""}Etapa {step} de {STEPS.length} ·{" "}
            {STEPS[step - 1].title}
          </p>
        </div>
      </div>

      <Stepper current={step} onSelect={setStep} />

      <div className="grid gap-6 lg:grid-cols-[1fr_340px]">
        <Card className="border-border/60 shadow-soft">
          <CardContent className="p-6 sm:p-8">
            {step === 1 && <StepClient draft={draft} update={update} />}
            {step === 2 && <StepServices draft={draft} update={update} />}
            {step === 3 && <StepScope draft={draft} update={update} />}
            {step === 4 && <StepPayment draft={draft} update={update} totals={totals} />}
            {step === 5 && <StepDeadline draft={draft} update={update} />}
            {step === 6 && (
              <StepReview draft={draft} update={update} totals={totals} mode={mode} />
            )}

            <div className="mt-8 flex items-center justify-between gap-3 border-t border-border/60 pt-6">
              <Button variant="outline" onClick={prev} disabled={step === 1} className="gap-1">
                <ArrowLeft className="h-4 w-4" /> Anterior
              </Button>
              {step < 6 ? (
                <Button onClick={next} className="gap-1 bg-gradient-brand text-white">
                  Próximo <ArrowRight className="h-4 w-4" />
                </Button>
              ) : (
                <Button
                  onClick={handleSave}
                  className="gap-1 bg-gradient-brand text-white"
                >
                  <Check className="h-4 w-4" /> {submitLabel}
                </Button>
              )}
            </div>
          </CardContent>
        </Card>

        <SummaryPanel draft={draft} totals={totals} mode={mode} hint={summaryHint} />
      </div>

      <AlertDialog open={confirmOpen} onOpenChange={setConfirmOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Salvar alterações?</AlertDialogTitle>
            <AlertDialogDescription>
              Deseja salvar as alterações desta proposta?
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancelar</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => {
                setConfirmOpen(false);
                doSubmit();
              }}
              className="bg-gradient-brand text-white hover:opacity-95"
            >
              Salvar alterações
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}

// ---------------- Stepper ----------------

function Stepper({
  current,
  onSelect,
}: {
  current: number;
  onSelect: (n: number) => void;
}) {
  return (
    <ol className="flex flex-wrap gap-2">
      {STEPS.map((s) => {
        const active = s.id === current;
        const done = s.id < current;
        return (
          <li key={s.id}>
            <button
              type="button"
              onClick={() => onSelect(s.id)}
              className={cn(
                "flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs font-medium transition",
                active && "border-primary bg-primary/10 text-primary shadow-soft",
                done && !active && "border-success/40 bg-success/10 text-success-foreground",
                !active &&
                  !done &&
                  "border-border/60 bg-card text-muted-foreground hover:text-foreground",
              )}
            >
              <span
                className={cn(
                  "flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold",
                  active && "bg-primary text-primary-foreground",
                  done && !active && "bg-success text-success-foreground",
                  !active && !done && "bg-muted text-muted-foreground",
                )}
              >
                {done ? <Check className="h-3 w-3" /> : s.id}
              </span>
              <span>{s.title}</span>
            </button>
          </li>
        );
      })}
    </ol>
  );
}

// ---------------- Steps ----------------

type StepProps = {
  draft: ProposalDraft;
  update: <K extends keyof ProposalDraft>(k: K, v: ProposalDraft[K]) => void;
};

function StepClient({ draft, update }: StepProps) {
  return (
    <div className="space-y-5">
      <StepHeading title="Dados do cliente e da proposta" desc="Quem vai receber esta proposta e qual o título." />
      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Cliente / Empresa" required>
          <Input
            value={draft.clientName}
            onChange={(e) => update("clientName", e.target.value)}
            placeholder="Padaria Pão Dourado"
            maxLength={120}
          />
        </Field>
        <Field label="Responsável" required>
          <Input
            value={draft.contactName}
            onChange={(e) => update("contactName", e.target.value)}
            placeholder="João da Silva"
            maxLength={120}
          />
        </Field>
        <Field label="E-mail" required>
          <Input
            type="email"
            value={draft.email}
            onChange={(e) => update("email", e.target.value)}
            placeholder="contato@empresa.com.br"
            maxLength={180}
          />
        </Field>
        <Field label="WhatsApp" required>
          <Input
            value={draft.whatsapp}
            onChange={(e) => update("whatsapp", e.target.value)}
            placeholder="(55) 99999-0000"
            maxLength={30}
          />
        </Field>
        <Field label="Site atual (opcional)" className="sm:col-span-2">
          <Input
            value={draft.website}
            onChange={(e) => update("website", e.target.value)}
            placeholder="https://"
            maxLength={180}
          />
        </Field>
        <Field label="Título da proposta" required className="sm:col-span-2">
          <Input
            value={draft.title}
            onChange={(e) => update("title", e.target.value)}
            placeholder="Site Institucional + Hospedagem"
            maxLength={140}
          />
        </Field>
      </div>
    </div>
  );
}

function StepServices({ draft, update }: StepProps) {
  const isSelected = (id: string) => draft.items.some((i) => i.serviceId === id);

  const toggle = (id: string) => {
    if (isSelected(id)) {
      update(
        "items",
        draft.items.filter((i) => i.serviceId !== id),
      );
    } else {
      const svc = mockServices.find((s) => s.id === id);
      if (!svc) return;
      update("items", [
        ...draft.items,
        {
          serviceId: svc.id,
          name: svc.name,
          unitPrice: svc.basePrice,
          quantity: 1,
          recurring: svc.recurring,
        },
      ]);
    }
  };

  const patchItem = (id: string, patch: Partial<ProposalItem>) =>
    update(
      "items",
      draft.items.map((i) => (i.serviceId === id ? { ...i, ...patch } : i)),
    );

  return (
    <div className="space-y-6">
      <StepHeading
        title="Serviços da proposta"
        desc="Escolha do catálogo X3. Valores ficam editáveis só nesta proposta."
      />

      <div className="grid gap-3 sm:grid-cols-2">
        {mockServices.map((s) => {
          const selected = isSelected(s.id);
          return (
            <button
              key={s.id}
              type="button"
              onClick={() => toggle(s.id)}
              className={cn(
                "group relative rounded-xl border bg-card p-4 text-left transition hover:-translate-y-0.5 hover:shadow-soft",
                selected
                  ? "border-primary shadow-soft ring-1 ring-primary/30"
                  : "border-border/60",
              )}
            >
              <div className="flex items-start justify-between gap-2">
                <div>
                  <Badge
                    variant="outline"
                    className="mb-1 border-primary/30 bg-primary/5 text-primary"
                  >
                    {categoryLabel[s.category]}
                  </Badge>
                  <div className="font-display font-semibold leading-tight">{s.name}</div>
                </div>
                <div
                  className={cn(
                    "flex h-5 w-5 shrink-0 items-center justify-center rounded-full border",
                    selected
                      ? "border-primary bg-primary text-primary-foreground"
                      : "border-border",
                  )}
                >
                  {selected && <Check className="h-3 w-3" />}
                </div>
              </div>
              <div className="mt-3 text-sm text-muted-foreground">
                A partir de{" "}
                <span className="font-semibold text-foreground">{formatBRL(s.basePrice)}</span>
                {s.recurring && (
                  <span className="ml-1 text-xs">
                    /{s.recurring === "mensal" ? "mês" : "ano"}
                  </span>
                )}
              </div>
            </button>
          );
        })}
      </div>

      {draft.items.length > 0 && (
        <div className="rounded-xl border border-border/60 bg-muted/30 p-4">
          <div className="mb-3 text-xs font-medium uppercase tracking-wider text-muted-foreground">
            Itens selecionados ({draft.items.length})
          </div>
          <div className="space-y-3">
            {draft.items.map((it) => (
              <div
                key={it.serviceId}
                className="grid gap-3 rounded-lg border border-border/60 bg-card p-3 sm:grid-cols-[1fr_100px_140px_40px] sm:items-end"
              >
                <div>
                  <div className="text-xs text-muted-foreground">Serviço</div>
                  <div className="font-medium">{it.name}</div>
                  {it.recurring && (
                    <Badge
                      variant="outline"
                      className="mt-1 border-brand-cyan/30 bg-brand-cyan/10 text-foreground"
                    >
                      Recorrente
                    </Badge>
                  )}
                </div>
                <Field label="Qtd">
                  <Input
                    type="number"
                    min={1}
                    value={it.quantity}
                    onChange={(e) =>
                      patchItem(it.serviceId, {
                        quantity: Math.max(1, parseInt(e.target.value || "1", 10)),
                      })
                    }
                  />
                </Field>
                <Field label="Valor unitário">
                  <Input
                    type="number"
                    min={0}
                    step={1}
                    value={it.unitPrice}
                    onChange={(e) =>
                      patchItem(it.serviceId, {
                        unitPrice: Math.max(0, parseFloat(e.target.value || "0")),
                      })
                    }
                  />
                </Field>
                <Button
                  variant="ghost"
                  size="icon"
                  className="h-9 w-9 text-muted-foreground hover:text-destructive"
                  onClick={() => toggle(it.serviceId)}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

function StepScope({ draft, update }: StepProps) {
  const setDeliverable = (idx: number, val: string) => {
    const list = [...draft.deliverables];
    list[idx] = val;
    update("deliverables", list);
  };
  const addDeliverable = () => update("deliverables", [...draft.deliverables, ""]);
  const removeDeliverable = (idx: number) =>
    update(
      "deliverables",
      draft.deliverables.filter((_, i) => i !== idx),
    );

  return (
    <div className="space-y-5">
      <StepHeading
        title="Escopo, entregas e observações"
        desc="Descreva o que será feito e o que o cliente receberá."
      />
      <Field label="Escopo" required>
        <Textarea
          rows={5}
          value={draft.scope}
          onChange={(e) => update("scope", e.target.value)}
          placeholder="Descreva o projeto em algumas frases..."
          maxLength={2000}
        />
      </Field>
      <div>
        <Label className="mb-2 block text-sm font-medium">
          Entregas <span className="text-destructive">*</span>
        </Label>
        <div className="space-y-2">
          {draft.deliverables.map((d, idx) => (
            <div key={idx} className="flex gap-2">
              <Input
                value={d}
                onChange={(e) => setDeliverable(idx, e.target.value)}
                placeholder={`Entrega ${idx + 1}`}
                maxLength={160}
              />
              <Button
                variant="ghost"
                size="icon"
                onClick={() => removeDeliverable(idx)}
                disabled={draft.deliverables.length === 1}
                className="text-muted-foreground hover:text-destructive"
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          ))}
          <Button variant="outline" size="sm" onClick={addDeliverable} className="gap-1">
            <Plus className="h-3.5 w-3.5" /> Adicionar entrega
          </Button>
        </div>
      </div>
      <Field label="Observações (opcional)">
        <Textarea
          rows={3}
          value={draft.observations}
          onChange={(e) => update("observations", e.target.value)}
          placeholder="Condições adicionais, notas internas, etc."
          maxLength={2000}
        />
      </Field>
    </div>
  );
}

function StepPayment({
  draft,
  update,
  totals,
}: StepProps & { totals: ProposalWizardTotals }) {
  const methods: { id: PaymentMethod; label: string; desc: string }[] = [
    { id: "pix", label: "Pix", desc: "À vista, com desconto sugerido." },
    { id: "boleto", label: "Boleto", desc: "Pagamento via boleto bancário." },
    { id: "cartao", label: "Cartão de crédito", desc: "Parcelável em até 12x." },
  ];

  const selected = draft.paymentMethods;
  const hasCard = selected.includes("cartao");

  const toggleMethod = (id: PaymentMethod) => {
    const next = selected.includes(id)
      ? selected.filter((m) => m !== id)
      : [...selected, id];
    update("paymentMethods", next);
    if (!next.includes("cartao") && draft.installments > 1) {
      update("installments", 1);
    }
  };

  return (
    <div className="space-y-6">
      <StepHeading
        title="Investimento e pagamento"
        desc="Total calculado a partir dos serviços. Selecione uma ou mais formas de pagamento."
      />

      <div className="grid gap-3 sm:grid-cols-3">
        {methods.map((m) => {
          const active = selected.includes(m.id);
          return (
            <button
              key={m.id}
              type="button"
              onClick={() => toggleMethod(m.id)}
              className={cn(
                "relative rounded-xl border p-4 text-left transition hover:-translate-y-0.5",
                active
                  ? "border-primary bg-primary/5 shadow-soft ring-1 ring-primary/30"
                  : "border-border/60 bg-card",
              )}
            >
              <div className="flex items-start justify-between gap-2">
                <div className="font-display font-semibold">{m.label}</div>
                <div
                  className={cn(
                    "flex h-5 w-5 shrink-0 items-center justify-center rounded-md border",
                    active
                      ? "border-primary bg-primary text-primary-foreground"
                      : "border-border",
                  )}
                >
                  {active && <Check className="h-3 w-3" />}
                </div>
              </div>
              <p className="mt-1 text-xs text-muted-foreground">{m.desc}</p>
            </button>
          );
        })}
      </div>

      <p className="text-xs text-muted-foreground">
        Selecione uma ou mais formas de pagamento que serão exibidas na proposta.
      </p>

      <div className="grid gap-4 sm:grid-cols-2">
        {hasCard && (
          <Field label="Parcelamento máximo no cartão">
            <Select
              value={String(draft.installments)}
              onValueChange={(v) => update("installments", parseInt(v, 10))}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {Array.from({ length: 12 }, (_, i) => i + 1).map((n) => (
                  <SelectItem key={n} value={String(n)}>
                    {n}x {n === 1 ? "à vista" : `de ${formatBRL(totals.oneTime / n)}`}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-xs text-muted-foreground">
              Número máximo de parcelas oferecidas ao cliente.
            </p>
          </Field>
        )}
        <div className={cn("rounded-xl border border-border/60 bg-muted/30 p-4", !hasCard && "sm:col-span-2")}>
          <div className="text-xs text-muted-foreground">Total único</div>
          <div className="font-display text-2xl font-semibold">
            {formatBRL(totals.oneTime)}
          </div>
          {totals.recurring > 0 && (
            <div className="mt-1 text-xs text-muted-foreground">
              + {formatBRL(totals.recurring)}/mês recorrente
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function StepDeadline({ draft, update }: StepProps) {
  return (
    <div className="space-y-5">
      <StepHeading
        title="Prazos e validade"
        desc="Quanto tempo levará e até quando esta proposta é válida."
      />
      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Prazo de entrega (dias)" required>
          <Input
            type="number"
            min={1}
            max={365}
            value={draft.deadlineDays}
            onChange={(e) =>
              update("deadlineDays", Math.max(1, parseInt(e.target.value || "1", 10)))
            }
          />
        </Field>
        <Field label="Válida até" required>
          <Input
            type="date"
            value={draft.validUntil}
            onChange={(e) => update("validUntil", e.target.value)}
          />
        </Field>
      </div>
    </div>
  );
}

const statusOptions: { value: ProposalStatus; label: string }[] = [
  { value: "rascunho", label: "Rascunho" },
  { value: "enviada", label: "Enviada" },
  { value: "aprovada", label: "Aprovada" },
];

function StepReview({
  draft,
  update,
  totals,
  mode,
}: {
  draft: ProposalDraft;
  update: <K extends keyof ProposalDraft>(k: K, v: ProposalDraft[K]) => void;
  totals: ProposalWizardTotals;
  mode: "create" | "edit";
}) {
  const hasCard = draft.paymentMethods.includes("cartao");
  return (
    <div className="space-y-6">
      <StepHeading
        title="Revisão final"
        desc={
          mode === "edit"
            ? "Confira as alterações e ajuste o status, se necessário."
            : "Confira tudo antes de salvar como rascunho."
        }
      />

      {mode === "edit" && (
        <div className="rounded-xl border border-primary/30 bg-primary/5 p-4">
          <Label className="mb-2 block text-sm font-medium">Status da proposta</Label>
          <Select
            value={draft.status === "expirada" ? "rascunho" : draft.status}
            onValueChange={(v) => update("status", v as ProposalStatus)}
          >
            <SelectTrigger className="bg-card">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {statusOptions.map((s) => (
                <SelectItem key={s.value} value={s.value}>
                  {s.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <p className="mt-2 text-xs text-muted-foreground">
            Propostas com validade vencida aparecem automaticamente como
            <strong className="font-semibold"> Vencida</strong> na listagem.
          </p>
        </div>
      )}

      <div className="grid gap-4 md:grid-cols-2">
        <ReviewBlock title="Proposta">
          <ReviewRow label="Título" value={draft.title || "—"} />
          <ReviewRow label="Total único" value={formatBRL(totals.oneTime)} />
          {totals.recurring > 0 && (
            <ReviewRow label="Recorrente" value={`${formatBRL(totals.recurring)}/mês`} />
          )}
          <ReviewRow label="Prazo de entrega" value={`${draft.deadlineDays} dias`} />
          <ReviewRow
            label="Válida até"
            value={
              /^\d{4}-\d{2}-\d{2}$/.test(draft.validUntil)
                ? formatDate(draft.validUntil)
                : draft.validUntil || "—"
            }
          />
        </ReviewBlock>

        <ReviewBlock title="Cliente">
          <ReviewRow label="Empresa" value={draft.clientName || "—"} />
          <ReviewRow label="Responsável" value={draft.contactName || "—"} />
          <ReviewRow label="E-mail" value={draft.email || "—"} />
          <ReviewRow label="WhatsApp" value={draft.whatsapp || "—"} />
          {draft.website && <ReviewRow label="Site atual" value={draft.website} />}
        </ReviewBlock>
      </div>

      <ReviewBlock title="Serviços">
        {draft.items.length === 0 ? (
          <p className="text-sm text-muted-foreground">Nenhum serviço selecionado.</p>
        ) : (
          <ul className="space-y-1.5">
            {draft.items.map((i) => (
              <li
                key={i.serviceId}
                className="flex items-center justify-between gap-3 border-b border-border/40 pb-1.5 last:border-0 last:pb-0"
              >
                <span>
                  {i.quantity}× {i.name}
                  {i.recurring && (
                    <span className="ml-2 text-xs text-muted-foreground">
                      ({i.recurring})
                    </span>
                  )}
                </span>
                <span className="font-medium">{formatBRL(i.unitPrice * i.quantity)}</span>
              </li>
            ))}
          </ul>
        )}
      </ReviewBlock>

      <ReviewBlock title="Pagamento">
        <ReviewRow
          label="Formas"
          value={
            draft.paymentMethods.length > 0
              ? draft.paymentMethods.map(labelPayment).join(" · ")
              : "—"
          }
        />
        {hasCard && (
          <ReviewRow
            label="Parcelamento"
            value={
              draft.installments > 1
                ? `Em até ${draft.installments}x no cartão`
                : "À vista no cartão"
            }
          />
        )}
      </ReviewBlock>

      <ReviewBlock title="Escopo & entregas">
        <ReviewRow label="Escopo" value={<p className="whitespace-pre-line">{draft.scope}</p>} />
        <ReviewRow
          label="Entregas"
          value={
            <ul className="list-disc space-y-0.5 pl-4">
              {draft.deliverables.filter(Boolean).map((d, i) => (
                <li key={i}>{d}</li>
              ))}
            </ul>
          }
        />
        {draft.observations && (
          <ReviewRow
            label="Observações"
            value={<p className="whitespace-pre-line">{draft.observations}</p>}
          />
        )}
      </ReviewBlock>
    </div>
  );
}

// ---------------- Summary panel ----------------

function SummaryPanel({
  draft,
  totals,
  mode,
  hint,
}: {
  draft: ProposalDraft;
  totals: ProposalWizardTotals;
  mode: "create" | "edit";
  hint?: string;
}) {
  return (
    <aside className="lg:sticky lg:top-20 lg:self-start">
      <Card className="overflow-hidden border-border/60 shadow-soft">
        <div className="bg-gradient-dark p-5 text-white">
          <div className="text-xs uppercase tracking-wider text-white/60">Resumo</div>
          <div className="mt-1 font-display text-lg font-semibold">
            {draft.title || "Proposta sem título"}
          </div>
          <div className="mt-0.5 text-sm text-white/70">
            {draft.clientName || "Cliente não definido"}
          </div>
        </div>
        <CardContent className="space-y-4 p-5 text-sm">
          <div className="space-y-1">
            <div className="text-xs uppercase tracking-wider text-muted-foreground">
              Serviços
            </div>
            {draft.items.length === 0 ? (
              <p className="text-muted-foreground">Nenhum serviço selecionado.</p>
            ) : (
              <ul className="space-y-1">
                {draft.items.map((i) => (
                  <li key={i.serviceId} className="flex items-center justify-between gap-2">
                    <span className="truncate">
                      {i.quantity}× {i.name}
                    </span>
                    <span className="shrink-0 font-medium">
                      {formatBRL(i.unitPrice * i.quantity)}
                    </span>
                  </li>
                ))}
              </ul>
            )}
          </div>

          <div className="border-t border-border/60 pt-3">
            <div className="flex items-center justify-between">
              <span className="text-muted-foreground">Total único</span>
              <span className="font-display text-lg font-semibold">
                {formatBRL(totals.oneTime)}
              </span>
            </div>
            {totals.recurring > 0 && (
              <div className="mt-1 flex items-center justify-between text-xs text-muted-foreground">
                <span>Recorrente</span>
                <span>{formatBRL(totals.recurring)}/mês</span>
              </div>
            )}
          </div>

          <div className="space-y-1.5 border-t border-border/60 pt-3 text-xs text-muted-foreground">
            <div className="flex justify-between">
              <span>Pagamento</span>
              <span className="text-foreground">
                {formatPaymentMethods(draft.paymentMethods, draft.installments)}
              </span>
            </div>
            <div className="flex justify-between">
              <span>Prazo</span>
              <span className="text-foreground">{draft.deadlineDays} dias</span>
            </div>
            <div className="flex justify-between">
              <span>Válida até</span>
              <span className="text-foreground">{draft.validUntil}</span>
            </div>
            {mode === "edit" && (
              <div className="flex justify-between">
                <span>Status</span>
                <span className="text-foreground capitalize">{draft.status}</span>
              </div>
            )}
          </div>

          <div className="flex items-center gap-2 rounded-lg bg-success/10 p-3 text-xs text-foreground/80">
            <CheckCircle2 className="h-4 w-4 text-success" />
            {hint ?? (
              <span>
                Salvará como <strong className="font-semibold">rascunho</strong>.
              </span>
            )}
          </div>
        </CardContent>
      </Card>
    </aside>
  );
}

// ---------------- Helpers UI ----------------

function StepHeading({ title, desc }: { title: string; desc?: string }) {
  return (
    <div>
      <h2 className="font-display text-xl font-semibold">{title}</h2>
      {desc && <p className="mt-1 text-sm text-muted-foreground">{desc}</p>}
    </div>
  );
}

function Field({
  label,
  required,
  children,
  className,
}: {
  label: string;
  required?: boolean;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={cn("space-y-1.5", className)}>
      <Label className="text-sm font-medium">
        {label} {required && <span className="text-destructive">*</span>}
      </Label>
      {children}
    </div>
  );
}

function ReviewBlock({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className="rounded-xl border border-border/60 bg-muted/20 p-4">
      <div className="mb-3 text-xs font-semibold uppercase tracking-wider text-primary">
        {title}
      </div>
      <div className="space-y-2 text-sm">{children}</div>
    </div>
  );
}

function ReviewRow({ label, value }: { label: string; value: React.ReactNode }) {
  return (
    <div className="grid gap-1 sm:grid-cols-[140px_1fr] sm:gap-3">
      <div className="text-xs uppercase tracking-wider text-muted-foreground sm:normal-case sm:tracking-normal sm:text-[13px]">
        {label}
      </div>
      <div className="text-foreground">{value}</div>
    </div>
  );
}

function labelPayment(m: PaymentMethod) {
  return m === "pix" ? "Pix" : m === "boleto" ? "Boleto" : "Cartão de crédito";
}

export function formatPaymentMethods(methods: PaymentMethod[], installments: number) {
  if (methods.length === 0) return "—";
  return methods
    .map((m) =>
      m === "cartao"
        ? `Cartão de crédito${installments > 1 ? ` em até ${installments}x` : ""}`
        : labelPayment(m),
    )
    .join(" · ");
}
