import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { categoriasDe } from "@/features/plano-contas/mei";
import type { Escopo, Lancamento, MeioPagamento, Tipo } from "../types";
import { adicionarLancamento, atualizarLancamento } from "../api/repo";
import { hojeISO } from "@/lib/format";
import { X } from "lucide-react";

const schema = z.object({
  data: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Data inválida"),
  tipo: z.enum(["entrada", "saida"]),
  categoria: z.string().min(1, "Selecione uma categoria"),
  valor: z.coerce.number().positive("Valor deve ser maior que zero"),
  descricao: z.string().default(""),
  fornecedorCliente: z.string().default(""),
  meioPagamento: z
    .enum(["dinheiro", "pix", "debito", "credito", "transferencia", "boleto"])
    .optional(),
});

interface LancamentoFormProps {
  escopo: Escopo;
  inicial: Lancamento | null;
  onClose: () => void;
}

const MEIOS: { v: MeioPagamento; l: string }[] = [
  { v: "pix", l: "PIX" },
  { v: "dinheiro", l: "Dinheiro" },
  { v: "debito", l: "Débito" },
  { v: "credito", l: "Crédito" },
  { v: "transferencia", l: "Transferência" },
  { v: "boleto", l: "Boleto" },
];

export function LancamentoForm({ escopo, inicial, onClose }: LancamentoFormProps) {
  const [tipo, setTipo] = useState<Tipo>(inicial?.tipo ?? "saida");
  const [data, setData] = useState(inicial?.data ?? hojeISO());
  const [categoria, setCategoria] = useState(inicial?.categoria ?? "");
  const [valor, setValor] = useState<string>(inicial ? String(inicial.valor) : "");
  const [descricao, setDescricao] = useState(inicial?.descricao ?? "");
  const [fornecedorCliente, setFornecedorCliente] = useState(
    inicial?.fornecedorCliente ?? "",
  );
  const [meioPagamento, setMeioPagamento] = useState<MeioPagamento | "">(
    inicial?.meioPagamento ?? "",
  );
  const [salvando, setSalvando] = useState(false);

  const categorias = useMemo(() => categoriasDe(escopo, tipo), [escopo, tipo]);

  useEffect(() => {
    if (!categorias.find((c) => c.nome === categoria)) {
      setCategoria(categorias[0]?.nome ?? "");
    }
  }, [categorias, categoria]);

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    const result = schema.safeParse({
      data,
      tipo,
      categoria,
      valor,
      descricao,
      fornecedorCliente,
      meioPagamento: meioPagamento || undefined,
    });
    if (!result.success) {
      toast.error(result.error.issues[0]?.message ?? "Dados inválidos");
      return;
    }
    setSalvando(true);
    try {
      const payload: Lancamento = {
        ...result.data,
        escopo,
        fornecedorCliente: result.data.fornecedorCliente || undefined,
      };
      if (inicial?.id != null) {
        await atualizarLancamento(inicial.id, payload);
        toast.success("Lançamento atualizado");
      } else {
        await adicionarLancamento(payload);
        toast.success("Lançamento adicionado");
      }
      onClose();
    } catch (err) {
      toast.error("Falha ao salvar", { description: String(err) });
    } finally {
      setSalvando(false);
    }
  }

  return (
    <form onSubmit={onSubmit} className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-base font-semibold text-foreground">
          {inicial ? "Editar lançamento" : "Novo lançamento"}
        </h2>
        <button
          type="button"
          onClick={onClose}
          aria-label="Fechar"
          className="rounded-md p-1.5 text-muted-foreground hover:bg-secondary"
        >
          <X className="size-4" />
        </button>
      </div>

      <div className="grid grid-cols-2 gap-2 rounded-xl bg-secondary p-1">
        {(["entrada", "saida"] as const).map((t) => (
          <button
            key={t}
            type="button"
            onClick={() => setTipo(t)}
            className={
              "rounded-lg py-2 text-sm font-medium transition " +
              (tipo === t
                ? t === "entrada"
                  ? "bg-success text-success-foreground shadow"
                  : "bg-destructive text-destructive-foreground shadow"
                : "text-muted-foreground")
            }
          >
            {t === "entrada" ? "Entrada" : "Saída"}
          </button>
        ))}
      </div>

      <div className="space-y-1.5">
        <Label htmlFor="valor">Valor (R$)</Label>
        <Input
          id="valor"
          inputMode="decimal"
          step="0.01"
          type="number"
          value={valor}
          onChange={(e) => setValor(e.target.value)}
          placeholder="0,00"
          required
        />
      </div>

      <div className="space-y-1.5">
        <Label>Categoria</Label>
        <Select value={categoria} onValueChange={setCategoria}>
          <SelectTrigger>
            <SelectValue placeholder="Selecione" />
          </SelectTrigger>
          <SelectContent>
            {categorias.map((c) => (
              <SelectItem key={c.nome} value={c.nome}>
                {c.nome}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div className="space-y-1.5">
        <Label htmlFor="data">Data</Label>
        <Input
          id="data"
          type="date"
          value={data}
          onChange={(e) => setData(e.target.value)}
          required
        />
      </div>

      <div className="space-y-1.5">
        <Label htmlFor="forn">{tipo === "entrada" ? "Cliente" : "Fornecedor"} (opcional)</Label>
        <Input
          id="forn"
          value={fornecedorCliente}
          onChange={(e) => setFornecedorCliente(e.target.value)}
        />
      </div>

      <div className="space-y-1.5">
        <Label>Meio de pagamento (opcional)</Label>
        <Select
          value={meioPagamento}
          onValueChange={(v) => setMeioPagamento(v as MeioPagamento)}
        >
          <SelectTrigger>
            <SelectValue placeholder="—" />
          </SelectTrigger>
          <SelectContent>
            {MEIOS.map((m) => (
              <SelectItem key={m.v} value={m.v}>
                {m.l}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div className="space-y-1.5">
        <Label htmlFor="desc">Descrição (opcional)</Label>
        <Textarea
          id="desc"
          value={descricao}
          onChange={(e) => setDescricao(e.target.value)}
          rows={2}
        />
      </div>

      <div className="flex gap-2 pt-2">
        <Button type="button" variant="outline" onClick={onClose} className="flex-1">
          Cancelar
        </Button>
        <Button type="submit" disabled={salvando} className="flex-1">
          {salvando ? "Salvando..." : "Salvar"}
        </Button>
      </div>
    </form>
  );
}
