export type LiquidationMethod = "pix" | "cash" | "credit_card" | "debit_card" | "transfer";

export type LiquidationAccountLike = {
  id?: string | null;
  bank_account_id?: string | null;
  name?: string | null;
  bank_name?: string | null;
  type?: string | null;
  active?: boolean | null;
};

export function normalizeLiquidationMethod(value: unknown): LiquidationMethod | null {
  if (typeof value !== "string") return null;
  const normalized = value.trim().toLowerCase();
  if (normalized === "pix") return "pix";
  if (normalized === "cash" || normalized === "dinheiro") return "cash";
  if (normalized === "credit_card" || normalized === "credit" || normalized === "card" || normalized === "cartao") {
    return "credit_card";
  }
  if (normalized === "debit_card" || normalized === "debit") return "debit_card";
  if (normalized === "transfer" || normalized === "transferencia") return "transfer";
  return null;
}

export function normalizeLiquidationAccountType(value: unknown) {
  if (typeof value !== "string") return null;
  const normalized = value.trim().toUpperCase();
  if (normalized === "CAIXA") return "CAIXA";
  if (normalized === "CONTA_CORRENTE") return "CONTA_CORRENTE";
  if (normalized === "CONTA_POUPANCA") return "CONTA_POUPANCA";
  return null;
}

export function getLiquidationAccountId(account: LiquidationAccountLike | null | undefined) {
  if (!account) return "";
  if (typeof account.bank_account_id === "string" && account.bank_account_id.trim()) return account.bank_account_id.trim();
  if (typeof account.id === "string" && account.id.trim()) return account.id.trim();
  return "";
}

export function isCashAccountType(value: unknown) {
  return normalizeLiquidationAccountType(value) === "CAIXA";
}

export function isCashAccount(account: LiquidationAccountLike | null | undefined) {
  return isCashAccountType(account?.type);
}

export function isElectronicLiquidationMethod(method: LiquidationMethod | null | undefined) {
  return Boolean(method) && method !== "cash";
}

export function requiresCashSession(methods: Array<LiquidationMethod | null | undefined>) {
  return methods.some((method) => method === "cash");
}

export function getLiquidationAccountDisplayName(account: LiquidationAccountLike | null | undefined) {
  if (!account) return "Conta";
  const name = typeof account.name === "string" ? account.name.trim() : "";
  if (name) return name;
  const bankName = typeof account.bank_name === "string" ? account.bank_name.trim() : "";
  if (bankName) return bankName;
  return isCashAccount(account) ? "Caixa físico" : "Conta bancária";
}

export function getLiquidationRequirementLabel(method: LiquidationMethod | null | undefined) {
  return method === "cash" ? "caixa físico" : "conta bancária";
}

export function isLiquidationAccountCompatible(
  method: LiquidationMethod | null | undefined,
  account: LiquidationAccountLike | null | undefined
) {
  if (!method || !account) return false;
  if (method === "cash") return isCashAccount(account);
  return !isCashAccount(account);
}

export function getLiquidationCompatibilityError(
  method: LiquidationMethod | null | undefined,
  account: LiquidationAccountLike | null | undefined,
  options?: { prefix?: string }
) {
  if (!method) return "Forma de pagamento inválida.";
  if (!account) {
    return `${options?.prefix || "Selecione"} ${getLiquidationRequirementLabel(method)}.`;
  }
  if (account.active === false) {
    return `${getLiquidationAccountDisplayName(account)} está inativa.`;
  }
  if (isLiquidationAccountCompatible(method, account)) return null;
  if (method === "cash") {
    return "Pagamentos em dinheiro devem ser liquidados em um caixa físico.";
  }
  return "Pix, transferência e cartões devem ser liquidados em uma conta bancária, não em caixa físico.";
}

export function filterAccountsByLiquidationMethod<T extends LiquidationAccountLike>(
  accounts: T[],
  method: LiquidationMethod | null | undefined
) {
  if (!method) return accounts;
  return accounts.filter((account) => isLiquidationAccountCompatible(method, account));
}

export function splitLiquidationAccounts<T extends LiquidationAccountLike>(accounts: T[]) {
  return {
    cashAccounts: accounts.filter((account) => isCashAccount(account)),
    bankAccounts: accounts.filter((account) => !isCashAccount(account)),
  };
}
