"use client";

import { ArrowDown, ArrowUp, History, Lock, Unlock } from "lucide-react";
import { CustomSelect } from "@/components/ui/custom-select";
import { formatMoney, formatMoneyInput } from "@/utils/formatters";
import {
  descricaoDoMovimento,
  ehReversaoDeVenda,
  rotuloDoMovimento,
  type CashMovement,
  type CashSession,
  type CashSessionTotals,
} from "@/lib/pdv/carrinho";
import { Modal } from "./modais";

/*
  O caixa físico, num canto só.

  Abrir, suprir, sangrar, fechar e ver o histórico moravam numa fileira de
  botões na cabeça da página. Aqui viram um menu que cai do segmento "Caixa"
  da barra — junto com a escolha do caixa físico e da conta bancária, que são
  a mesma decisão: onde o dinheiro desta máquina vai parar.
*/

export type AcaoDoCaixa = "open" | "supply" | "withdrawal" | "close";

export function MenuDoCaixa({
  cashSession,
  cashTotals,
  cashRecentSessions,
  bankAccountOptions,
  selectedBankAccountId,
  setSelectedBankAccountId,
  electronicBankAccountOptions,
  selectedElectronicBankAccountId,
  setSelectedElectronicBankAccountId,
  aoAgir,
  aoHistorico,
}: {
  cashSession: CashSession | null;
  cashTotals: CashSessionTotals | null;
  cashRecentSessions: CashSession[];
  bankAccountOptions: Array<{ value: string; label: string }>;
  selectedBankAccountId: string;
  setSelectedBankAccountId: (valor: string) => void;
  electronicBankAccountOptions: Array<{ value: string; label: string }>;
  selectedElectronicBankAccountId: string;
  setSelectedElectronicBankAccountId: (valor: string) => void;
  aoAgir: (acao: AcaoDoCaixa) => void;
  aoHistorico: (sessionId?: string) => void;
}) {
  const aberto = Boolean(cashSession?.id && cashSession.status === "open");

  return (
    <div className="pdv-menu" onClick={(evento) => evento.stopPropagation()}>
      <div className="pdv-menu-rotulo">Caixa físico</div>
      <div className="pdv-menu-campo">
        <CustomSelect
          options={bankAccountOptions}
          value={selectedBankAccountId}
          onChange={setSelectedBankAccountId}
          className="pdv-select-campo"
          placeholder="Escolha o caixa físico"
          portal={false}
        />
      </div>
      {aberto ? (
        <div className="pdv-menu-saldo">
          <span>Saldo esperado</span>
          <strong>{formatMoney(cashTotals?.expected_balance || 0)}</strong>
        </div>
      ) : null}
      {aberto ? (
        <>
          <button type="button" className="pdv-menu-item" onClick={() => aoAgir("supply")}>
            <ArrowUp size={15} />
            Suprimento
          </button>
          <button type="button" className="pdv-menu-item" onClick={() => aoAgir("withdrawal")}>
            <ArrowDown size={15} />
            Sangria
          </button>
          <button type="button" className="pdv-menu-item" onClick={() => aoHistorico()}>
            <History size={15} />
            Histórico da sessão
          </button>
          <button type="button" className="pdv-menu-item pdv-menu-item-perigo" onClick={() => aoAgir("close")}>
            <Lock size={15} />
            Fechar caixa
          </button>
        </>
      ) : (
        <>
          <button type="button" className="pdv-menu-item" onClick={() => aoAgir("open")} disabled={!selectedBankAccountId}>
            <Unlock size={15} />
            Abrir caixa
          </button>
          {cashRecentSessions[0] ? (
            <button type="button" className="pdv-menu-item" onClick={() => aoHistorico(cashRecentSessions[0].id)}>
              <History size={15} />
              Histórico
            </button>
          ) : null}
        </>
      )}
      <div className="pdv-menu-sep" />
      <div className="pdv-menu-rotulo">Conta bancária (Pix e cartão)</div>
      <div className="pdv-menu-campo">
        <CustomSelect
          options={electronicBankAccountOptions}
          value={selectedElectronicBankAccountId}
          onChange={setSelectedElectronicBankAccountId}
          className="pdv-select-campo"
          placeholder="Escolha a conta"
          portal={false}
        />
      </div>
    </div>
  );
}

export function ModalDoCaixa({
  acao,
  aoFechar,
  saldoEsperado,
  cashAmountInput,
  setCashAmountInput,
  cashCountedInput,
  setCashCountedInput,
  cashNotesInput,
  setCashNotesInput,
  ocupado,
  aoConfirmar,
}: {
  acao: AcaoDoCaixa | null;
  aoFechar: () => void;
  saldoEsperado: number;
  cashAmountInput: string;
  setCashAmountInput: (valor: string) => void;
  cashCountedInput: string;
  setCashCountedInput: (valor: string) => void;
  cashNotesInput: string;
  setCashNotesInput: (valor: string) => void;
  ocupado: boolean;
  aoConfirmar: () => void;
}) {
  const titulo =
    acao === "open" ? "Abrir caixa" : acao === "supply" ? "Suprimento" : acao === "withdrawal" ? "Sangria" : "Fechar caixa";
  const sub =
    acao === "open"
      ? "Quanto tem de fundo de troco na gaveta agora."
      : acao === "close"
        ? "Conte o que está na gaveta. A diferença para o esperado fica registrada."
        : acao === "supply"
          ? "Dinheiro que entra na gaveta sem ser venda."
          : "Dinheiro que sai da gaveta sem ser troco.";

  return (
    <Modal
      aberto={Boolean(acao)}
      aoFechar={aoFechar}
      titulo={titulo}
      sub={sub}
      acoes={
        <>
          <button type="button" className="pdv-botao" onClick={aoFechar}>
            Voltar
          </button>
          <button type="button" className="pdv-botao pdv-botao-cheio" onClick={aoConfirmar} disabled={ocupado}>
            {ocupado ? "Registrando…" : "Confirmar"}
          </button>
        </>
      }
    >
      <div className="grid gap-3">
        {acao === "close" ? (
          <>
            <div className="pdv-aviso pdv-aviso-neutro">Saldo esperado: {formatMoney(saldoEsperado)}</div>
            <div>
              <label className="pdv-rotulo">Valor contado</label>
              <input
                value={cashCountedInput}
                onChange={(evento) => setCashCountedInput(formatMoneyInput(evento.target.value))}
                placeholder="0,00"
                className="pdv-campo pdv-campo-num"
                autoFocus
              />
            </div>
          </>
        ) : (
          <div>
            <label className="pdv-rotulo">{acao === "open" ? "Fundo inicial" : "Valor"}</label>
            <input
              value={cashAmountInput}
              onChange={(evento) => setCashAmountInput(formatMoneyInput(evento.target.value))}
              placeholder="0,00"
              className="pdv-campo pdv-campo-num"
              autoFocus
            />
          </div>
        )}
        <div>
          <label className="pdv-rotulo">Observação (opcional)</label>
          <input
            value={cashNotesInput}
            onChange={(evento) => setCashNotesInput(evento.target.value)}
            placeholder="Ex.: troco para o fim de semana"
            className="pdv-campo"
          />
        </div>
      </div>
    </Modal>
  );
}

export function ModalDoHistorico({
  aberto,
  aoFechar,
  carregando,
  sessao,
  totais,
  movimentos,
  sessoesRecentes,
  aoEscolherSessao,
}: {
  aberto: boolean;
  aoFechar: () => void;
  carregando: boolean;
  sessao: CashSession | null;
  totais: CashSessionTotals | null;
  movimentos: CashMovement[];
  sessoesRecentes: CashSession[];
  aoEscolherSessao: (sessionId: string) => void;
}) {
  const fechada = Boolean(sessao && sessao.status !== "open");
  const diferenca = Number(sessao?.difference_amount || 0);
  /* O estorno de uma venda cancelada é gravado como ajuste, então ele já está
     dentro do saldo esperado mas não aparecia em lugar nenhum: a conta batia e
     ninguém conseguia ver por quê. */
  const estornos = movimentos
    .filter((movimento) => ehReversaoDeVenda(movimento.description) && movimento.direction === "OUT")
    .reduce((soma, movimento) => soma + Number(movimento.amount || 0), 0);

  return (
    <Modal
      aberto={aberto}
      aoFechar={aoFechar}
      titulo="Histórico do caixa"
      /* Dizia "Sessão aberta em..." mesmo numa sessão já fechada, e quem olhava
         entendia que a gaveta continuava aberta. */
      sub={
        sessao
          ? sessao.status === "open"
            ? `Aberta em ${new Date(sessao.opened_at).toLocaleString("pt-BR")} · em aberto`
            : `Aberta em ${new Date(sessao.opened_at).toLocaleString("pt-BR")} · fechada em ${
                sessao.closed_at ? new Date(sessao.closed_at).toLocaleString("pt-BR") : "data não registrada"
              }`
          : "Escolha uma sessão para ver os movimentos."
      }
      larga
    >
      <div className="pdv-historico">
        <div className="pdv-historico-sessoes">
          {sessoesRecentes.map((item) => {
            const ativa = sessao?.id === item.id;
            return (
              <button
                key={item.id}
                type="button"
                className={`pdv-historico-sessao ${ativa ? "pdv-historico-sessao-ativa" : ""}`}
                onClick={() => aoEscolherSessao(item.id)}
              >
                Abertura {new Date(item.opened_at).toLocaleString("pt-BR")}
                <small>{item.closed_at ? `Fechado ${new Date(item.closed_at).toLocaleString("pt-BR")}` : "Em aberto"}</small>
              </button>
            );
          })}
          {sessoesRecentes.length === 0 ? (
            <div className="px-2 py-3 text-[12px] font-semibold text-[var(--ks-color-text-soft)]">Nenhuma sessão ainda.</div>
          ) : null}
        </div>
        <div className="pdv-historico-movimentos">
          {/* Antes eram três números soltos — saldo, vendas e troco — que não
              explicavam o saldo: faltavam abertura, suprimento e sangria, e
              quem conferia a gaveta pela tela não fechava a conta. Aqui está
              tudo o que entra, tudo o que sai, e o resultado. */}
          <div className="pdv-historico-totais">
            <div className="pdv-historico-total">
              Abertura e suprimentos
              <strong>{formatMoney(totais?.supplies || 0)}</strong>
            </div>
            <div className="pdv-historico-total">
              Vendas em dinheiro
              <strong>{formatMoney(totais?.cash_sales || 0)}</strong>
            </div>
            <div className="pdv-historico-total">
              Troco dado
              <strong>− {formatMoney(totais?.change || 0)}</strong>
            </div>
            <div className="pdv-historico-total">
              Sangrias
              <strong>− {formatMoney(totais?.withdrawals || 0)}</strong>
            </div>
            {estornos > 0.004 ? (
              <div className="pdv-historico-total">
                Estornos de venda
                <strong>− {formatMoney(estornos)}</strong>
              </div>
            ) : null}
            <div className="pdv-historico-total pdv-historico-total-forte">
              Saldo esperado
              <strong>{formatMoney(totais?.expected_balance || 0)}</strong>
            </div>
            {fechada ? (
              <>
                <div className="pdv-historico-total">
                  Contado no fechamento
                  <strong>{formatMoney(Number(sessao?.closing_counted_amount || 0))}</strong>
                </div>
                <div className={`pdv-historico-total ${diferenca > 0.004 || diferenca < -0.004 ? "pdv-historico-total-alerta" : ""}`}>
                  Diferença
                  <strong>
                    {diferenca > 0.004 ? "+" : ""}
                    {formatMoney(diferenca)}
                  </strong>
                </div>
              </>
            ) : null}
          </div>
          {carregando ? (
            <div className="py-8 text-center text-[13px] font-semibold text-[var(--ks-color-text-soft)]">Carregando…</div>
          ) : (
            <div>
              {movimentos.map((movimento) => (
                <div key={movimento.id} className="pdv-movimento">
                  <div className="pdv-movimento-quando">{new Date(movimento.created_at).toLocaleString("pt-BR")}</div>
                  <div className="pdv-movimento-oque">
                    {rotuloDoMovimento(movimento)}
                    {descricaoDoMovimento(movimento.description) ? ` · ${descricaoDoMovimento(movimento.description)}` : ""}
                  </div>
                  <div className={`pdv-movimento-valor ${movimento.direction === "IN" ? "pdv-movimento-entrada" : "pdv-movimento-saida"}`}>
                    {movimento.direction === "IN" ? "+" : "−"}
                    {formatMoney(Number(movimento.amount || 0))}
                  </div>
                </div>
              ))}
              {movimentos.length === 0 ? (
                <div className="py-8 text-center text-[13px] font-semibold text-[var(--ks-color-text-soft)]">
                  Sem movimentos nesta sessão.
                </div>
              ) : null}
            </div>
          )}
        </div>
      </div>
    </Modal>
  );
}
