/*
 * Estoque v2 — os formatos que o banco devolve (MOTOR.md, §5) e que as telas
 * usam. Só tipos: pode ser importado de qualquer lado (navegador, servidor,
 * teste).
 */

export type Papel = "insumo" | "pronto";
export type ModoDoProduto = "pronto" | "encomenda" | "nenhum";
export type QuandoSai = "sempre" | "pela_variacao" | "se_opcao" | "so_custo";

export type EixoDaGrade = { nome: string; valores: string[] };
export type Conversao = { unidade: string; fator: number | string };
export type Combinacao = Record<string, string>;

/** A célula como as funções do banco devolvem (`estoque_v2_celula_json`). */
export type Celula = {
  celula_id: string;
  item_id: string;
  nome: string;
  unidade: string;
  papel: Papel;
  valor1: string | null;
  valor2: string | null;
  rotulo: string;
  saldo: number;
  minimo: number | null;
  permite_negativo: boolean;
  controla: boolean;
};

/** Item do estoque (uma linha de `materials` vista pelo estoque novo). */
export type ItemDoEstoque = {
  id: string;
  nome: string;
  unidade: string;
  papel: Papel;
  grade: EixoDaGrade[];
  minimo: number | null;
  perda: number;
  permitir_negativo: boolean;
  conversoes: Conversao[];
  controla: boolean;
  custo_medio: number;
  saldo: number;
  produto_id: string | null;
  ativo: boolean;
  /* Dados de compra que a conta da composição usa (bobina, folha, pacote). */
  formato_de_compra: string | null;
  servico: boolean;
  /* Bobina, folha e embalagem (o modal de insumo de sempre edita). */
  compra: {
    roll_width_m: number | null;
    roll_length_m: number | null;
    package_qty: number | null;
    sheet_width_m: number | null;
    sheet_height_m: number | null;
  };
  celulas: Celula[];
  /* Quem usa: produtos ligados (pronto) e composições (insumo). */
  usos?: UsoDoItem[];
};

export type UsoDoItem = {
  produto_id: string;
  produto: string;
  como: "pronto" | "composicao" | "receita" | "servico";
  quando_sai?: QuandoSai | null;
};

export type ItemQueSai = {
  item_id: string | null;
  celula_id: string | null;
  nome: string | null;
  unidade: string | null;
  papel: Papel | null;
  rotulo: string | null;
  saldo: number;
  precisa: number;
  permite_negativo: boolean;
  sem_celula: boolean;
  falta_escolher: string | null;
  linhas: Array<{ origem: string; linha_id: string | null; quantidade: number }> | null;
};

/** Resposta de `estoque_disponivel`. */
export type Disponibilidade = {
  v2: boolean;
  modo: ModoDoProduto;
  controla: boolean;
  limita: boolean;
  pedido: number;
  cabe: boolean;
  disponivel: number | null;
  motivo: string | null;
  itens: ItemQueSai[];
  erro?: string;
};

export type OrigemDoMovimento = {
  pedido_id?: string;
  pedido_numero?: number;
  item_pedido_id?: string;
  compra_id?: string;
  compra_numero?: number;
  compra_linha_id?: string;
  producao_id?: string;
  perda_id?: string;
  contagem_id?: string;
  estorno_de?: string;
  /* Acrescentados pela rota (para o link): */
  fornecedor_id?: string;
  perda_pedido_id?: string;
  perda_pedido_numero?: number;
  producao_desfeita?: boolean;
  producao_produto_id?: string;
};

export type TipoDeMovimento =
  | "saldo_inicial"
  | "entrada"
  | "compra"
  | "venda"
  | "devolucao"
  | "producao_entrada"
  | "producao_saida"
  | "contagem"
  | "perda"
  | "estorno_perda"
  | "ajuste";

/** Linha da linha do tempo (`estoque_historico`). */
export type Movimento = {
  id: string;
  em: string;
  tipo: TipoDeMovimento;
  quantidade: number;
  saldo_depois: number;
  custo_unitario: number | null;
  item_id: string;
  celula_id: string;
  rotulo: string;
  observacao: string | null;
  por: string | null;
  por_nome?: string | null;
  detalhe: Record<string, unknown> | null;
  origem: OrigemDoMovimento;
};

export type Conferencia = {
  v2: boolean;
  empresa_id: string;
  divergencias: Array<Record<string, unknown> & { tipo: string }>;
  sem_celula: Array<{ tipo: string; produto_id: string; produto: string; combinacao?: Combinacao }>;
  negativos: Celula[];
  no_minimo: Celula[];
  duplicados: Array<{ nome: string; itens: Array<{ item_id: string; nome: string; papel: Papel; saldo: number }>; sugestao: string }>;
  fora_de_composicao: Array<{ item_id: string; nome: string; saldo: number }>;
};

/** Mapa manual variação → célula (`products.estoque_mapa`). */
export type LinhaDoMapa = { combinacao: Combinacao; celula_id: string; quantidade?: number };

/** O que o pedido levou, por item (`estoque_do_item_do_pedido`). */
export type BaixaDoItem = {
  celula: Celula | null;
  baixado: number | null;
  movimentos: Array<{ id: string; tipo: TipoDeMovimento; quantidade: number; saldo_depois: number; em: string; observacao: string | null }>;
};

/** O atributo do produto como o editor conhece (opções com id e rótulo). */
export type AtributoDoProduto = {
  id?: string;
  name: string;
  allow_multiple?: boolean;
  options: Array<{ id?: string; label: string }>;
};

/** O estoque de um produto na lista de produtos (rota /api/estoque/produtos). */
export type EstoqueDoProdutoNaLista = {
  modo: ModoDoProduto;
  saldo: number | null;
  daPara: number | null;
  limita: boolean;
  dependeDaVariacao: boolean;
  zeradas: number;
  unidade: string | null;
};
