"""Especificação das abas da planilha de importação (modelo para preencher). Usada pelo gerador do modelo
(`importacao_modelo.py`) e pelo importador (`importacao.py`): uma só fonte de verdade para nomes de aba, colunas,
tipos, obrigatoriedade e valores aceitos."""

from dataclasses import dataclass, field

# tipos de coluna
TEXTO = "texto"
DECIMAL = "decimal"  # número >= 0 (6 casas)
PCT = "pct"  # porcentagem (célula em %, "18%" ou fração 0-1) — guardada como fração (4 casas)
MES = "mes"  # AAAA-MM / MM/AAAA / data do Excel — dia 1 do mês
INTEIRO = "inteiro"
OPCAO = "opcao"  # uma entre `opcoes` (rótulo -> valor interno)

# obrigatoriedade
SEMPRE = "sempre"  # chave: obrigatória em toda linha
CRIAR = "criar"  # obrigatória só quando o registro ainda não existe
OPCIONAL = ""


@dataclass(frozen=True)
class Coluna:
    chave: str
    rotulo: str
    tipo: str = TEXTO
    obrigatoria: str = OPCIONAL
    ajuda: str = ""
    opcoes: dict[str, str] = field(default_factory=dict)  # texto aceito (sem acento/caixa) -> valor interno
    exemplo: str | float | int | None = None


@dataclass(frozen=True)
class Aba:
    chave: str  # identificador interno
    nome: str  # nome da aba na planilha
    descricao: str
    colunas: tuple[Coluna, ...]

    def coluna(self, chave: str) -> Coluna:
        return next(c for c in self.colunas if c.chave == chave)


_ATUALIZADO_EM = Coluna(
    "atualizado_em", "Atualizado em", MES, OPCIONAL,
    "Mês (AAAA-MM) a partir do qual os valores de custo desta linha valem. Vazio: registro novo = 'desde o início'; "
    "registro existente = mês atual (a versão antiga fica no histórico).",
    exemplo="2026-10",
)
_CLASSIFICACAO = Coluna(
    "classificacao", "Classificação", OPCAO, CRIAR, "fixo ou variável (obrigatório ao criar).",
    {"fixo": "fixo", "variavel": "variavel"}, "fixo",
)

TIPO_GASTO = {
    "instalacao": "ambiente", "ambiente": "ambiente", "maquina": "maquina", "outros": "outros", "mao de obra": "funcionario", "funcionario": "funcionario",
}  # os nomes antigos (Ambiente, Funcionário) continuam valendo
TIPO_ROTEIRO = {
    "maquina": "maquina", "outros": "outros", "instalacao": "ambiente", "ambiente": "ambiente", "mao de obra": "mao-de-obra", "mao-de-obra": "mao-de-obra",
    "funcionario": "mao-de-obra", "insumo": "insumo", "semiacabado": "semiacabado", "semi acabado": "semiacabado",
}
TIPO_INSUMO = {"ingrediente": "ingrediente", "embalagem": "embalagem"}
TIPO_PRODUTO = {"acabado": "acabado", "semiacabado": "semi_acabado", "semi_acabado": "semi_acabado", "semi acabado": "semi_acabado", "revenda": "revenda"}
SIM_NAO = {"sim": "sim", "s": "sim", "nao": "nao", "n": "nao"}
TIPO_PLANO = {"receita": "receita", "custo": "custo", "despesa": "despesa", "imposto": "imposto"}
BASE_DIRECIONADOR = {
    "tempo": "tempo", "quantidade produzida": "quantidade_produzida", "quantidade_produzida": "quantidade_produzida",
    "custo primário": "custo_primario", "custo primario": "custo_primario", "custo_primario": "custo_primario",
}
TIPO_PREMISSA = {"comercial": "comercial", "operacional": "operacional", "despesas": "despesas", "financeiro": "financeiro"}
TIPO_DESPESA = {"fixa": "fixa", "fixo": "fixa", "variavel": "variavel"}
TIPO_ALIQUOTA = {"cbs": "cbs", "ir/csll": "ir_csll", "ir csll": "ir_csll", "ir_csll": "ir_csll", "irpj/csll": "ir_csll"}
ORIGEM_ICMS = {  # origem da compra / faixa de destino do ICMS
    "bahia": "BA", "ba": "BA", "dentro da bahia": "BA",
    "sul/sudeste": "SUL_SUDESTE", "sul sudeste": "SUL_SUDESTE", "sul_sudeste": "SUL_SUDESTE", "sul e sudeste": "SUL_SUDESTE",
    "n/ne/co/es": "NORTE_NE_CO_ES", "norte_ne_co_es": "NORTE_NE_CO_ES", "norte/nordeste/centro-oeste/es": "NORTE_NE_CO_ES", "demais": "NORTE_NE_CO_ES",
}

_CREDITOS = (
    Coluna("credito_icms", "Crédito ICMS", OPCAO, OPCIONAL, "Sim = o item gera crédito de ICMS; Não = deixa de gerar; vazio = não mexe.", SIM_NAO, "Sim"),
    Coluna("aliquota_icms", "Alíquota própria ICMS (%)", PCT, OPCIONAL, "Opcional: vazio = a padrão da origem da compra. Vale para item com Crédito ICMS = Sim (ou já marcado).", exemplo=None),
    Coluna("origem_icms", "Origem da compra (ICMS)", OPCAO, OPCIONAL, "Bahia, Sul/Sudeste ou N/NE/CO/ES. Vazio = não mexe (item novo = Bahia).", ORIGEM_ICMS, "Bahia"),
    Coluna("credito_cbs", "Crédito CBS", OPCAO, OPCIONAL, "Sim, Não ou vazio (não mexe).", SIM_NAO, "Não"),
    Coluna("aliquota_cbs", "Alíquota própria CBS (%)", PCT, OPCIONAL, "Opcional: vazio = a padrão da aba Alíquotas.", exemplo=None),
    Coluna("credito_ir_csll", "Crédito IR/CSLL", OPCAO, OPCIONAL, "Sim, Não ou vazio (não mexe).", SIM_NAO, "Não"),
    Coluna("aliquota_ir_csll", "Alíquota própria IR/CSLL (%)", PCT, OPCIONAL, "Opcional: vazio = a padrão da aba Alíquotas.", exemplo=None),
)

ABAS: tuple[Aba, ...] = (
    Aba("planos", "Plano de Contas", "Natureza contábil em árvore (receita, custo, despesa, imposto).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Código hierárquico (2, 2.1, 2.1.01...): o pai é o código sem o último trecho e precisa existir (no sistema ou antes na planilha). Código existente atualiza.", exemplo="#2.1.01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Salários"),
        Coluna("tipo", "Tipo", OPCAO, OPCIONAL, "Só na conta raiz (as filhas herdam do pai): receita, custo, despesa ou imposto.", TIPO_PLANO, "Custo"),
    )),
    Aba("centros", "Centros de Custo", "Onde o custo é incorrido (ex.: Fábrica, Administrativo).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Código hierárquico (1, 1.1, 1.1.01...): o pai é o código sem o último trecho e precisa existir (no sistema ou antes na planilha). Código existente atualiza.", exemplo="#1.1"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Fábrica"),
        Coluna("produtivo", "Produtivo (custo)", OPCAO, OPCIONAL, "Sim = centro produtivo (custo): a ociosidade dos seus elementos entra no custo dos produtos. Não = despesa (ex.: Administrativo). Vazio: novo = Sim; existente não muda.", SIM_NAO, "Sim"),
    )),
    Aba("funcionarios", "Mão de obra", "Colaboradores (identificados pelo código da folha). Eles se agrupam sozinhos em grupos Depto-Cargo (Centro de Custo × cargo × classificação), que são o que se aloca aos produtos.", (
        Coluna("codigo_fopag", "Código FOPAG", TEXTO, SEMPRE, "Código da folha de pagamento (até 20 caracteres).", exemplo="#F001"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Maria Souza"),
        Coluna("cargo", "Cargo", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Auxiliar de produção"),
        Coluna("centro_de_custo", "Centro de Custo", TEXTO, CRIAR, "Código de um Centro de Custo (obrigatório ao criar).", exemplo="CC01"),
        _CLASSIFICACAO,
        Coluna("subordinado_a", "Subordinado a", TEXTO, OPCIONAL, "Código FOPAG do gestor (pode estar na mesma aba).", exemplo=None),
        Coluna("horas_semanais", "Horas semanais", DECIMAL, OPCIONAL, "Informativo.", exemplo=44),
        Coluna("horas_contratadas_mensais", "Horas contratadas/mês", DECIMAL, OPCIONAL, "Base do custo/hora.", exemplo=220),
        Coluna("absenteismo_pct", "Absenteísmo (%)", PCT, OPCIONAL, "Ex.: 3%.", exemplo=0.03),
        _ATUALIZADO_EM,
    )),
    Aba("ambientes", "Instalações", "Instalações (sala de produção, câmara fria…).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Código hierárquico (1, 1.1, 1.2...): o pai é o código sem o último trecho e precisa existir (no sistema ou antes na planilha); quem ganha filho vira sintético e só agrupa. Código existente atualiza.", exemplo="#1.1"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Sala de produção"),
        Coluna("centro_de_custo", "Centro de Custo", TEXTO, OPCIONAL, "Código de um Centro de Custo analítico.", exemplo="1.1"),
        _CLASSIFICACAO,
        Coluna("horas_uteis_mensais", "Horas úteis/mês", DECIMAL, OPCIONAL, "Capacidade em horas por mês (custo/hora).", exemplo=176),
        _ATUALIZADO_EM,
    )),
    Aba("maquinas", "Máquinas", "Máquinas e equipamentos.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#MAQ01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Misturador"),
        Coluna("ambiente", "Instalação", TEXTO, OPCIONAL, "Código de uma Instalação (pode estar na aba Instalações).", exemplo="AMB01"),
        Coluna("centro_de_custo", "Centro de Custo", TEXTO, OPCIONAL, "Código de um Centro de Custo.", exemplo="CC01"),
        _CLASSIFICACAO,
        Coluna("horas_uteis_mensais", "Horas úteis/mês", DECIMAL, OPCIONAL, "Capacidade em horas por mês.", exemplo=176),
        _ATUALIZADO_EM,
    )),
    Aba("outros", "Outros", "Outros elementos de custo, alocados como a máquina (por direcionador e horas por bacia).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres (não pode repetir o código de uma Máquina).", exemplo="#OUT01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Utilidades da fábrica"),
        Coluna("ambiente", "Instalação", TEXTO, OPCIONAL, "Código de uma Instalação (pode estar na aba Instalações).", exemplo="AMB01"),
        Coluna("centro_de_custo", "Centro de Custo", TEXTO, OPCIONAL, "Código de um Centro de Custo.", exemplo="CC01"),
        _CLASSIFICACAO,
        Coluna("horas_uteis_mensais", "Horas úteis/mês", DECIMAL, OPCIONAL, "Capacidade em horas por mês.", exemplo=176),
        _ATUALIZADO_EM,
    )),
    Aba("gastos", "Gastos", "Gastos mensais de Mão de obra, Instalações, Máquinas e Outros (uma linha por Plano de Contas).", (
        Coluna("tipo", "Tipo de recurso", OPCAO, SEMPRE, "Mão de obra, Instalação, Máquina ou Outros.", TIPO_GASTO, "Instalação"),
        Coluna("recurso", "Recurso", TEXTO, SEMPRE, "Código da Instalação/Máquina/Outros ou código FOPAG da Mão de obra.", exemplo="AMB01"),
        Coluna("plano_de_contas", "Plano de Contas", TEXTO, SEMPRE, "Código de uma conta analítica do Plano de Contas (veja a aba Referência; conta sintética só agrupa). Campos da tela Alterar gastos — Funcionário: 2.1.01 a 2.1.08 (2.1.08 = provisões, retenção); Máquina: 2.2.01 (depreciação, retenção) a 2.2.05; Ambiente: 2.3.01 a 2.3.07 (2.3.07 = depreciação, retenção). Os códigos antigos PC-... continuam valendo.", exemplo="PC-INSTAL-ALUGUEL"),
        Coluna("desembolso", "Desembolso (R$/mês)", DECIMAL, CRIAR, "Valor mensal pago (obrigatório ao criar).", exemplo=2500),
        Coluna("retencao", "Retenção (R$/mês)", DECIMAL, OPCIONAL, "Encargos/retenções do mês.", exemplo=0),
        _ATUALIZADO_EM,
        *_CREDITOS,
    )),
    Aba("areas", "Áreas", "Dicionário de processos — nível 1.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#AR-01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Finalísticos"),
    )),
    Aba("macroprocessos", "Macroprocessos", "Dicionário de processos — nível 2.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#MP-01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Produção"),
        Coluna("area", "Área", TEXTO, CRIAR, "Código da Área (obrigatório ao criar).", exemplo="AR-01"),
    )),
    Aba("processos", "Processos", "Dicionário de processos — nível 3.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#PR-01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Mistura"),
        Coluna("macroprocesso", "Macroprocesso", TEXTO, CRIAR, "Código do Macroprocesso (obrigatório ao criar).", exemplo="MP-01"),
    )),
    Aba("atividades", "Atividades", "Dicionário de processos — nível 4 (a etapa da formulação).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#AT-01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Pesagem de Insumos"),
        Coluna("processo", "Processo", TEXTO, CRIAR, "Código do Processo (obrigatório ao criar).", exemplo="PR-01"),
    )),
    Aba("direcionadores", "Direcionadores", "Direcionadores de custo: uma Atividade + a base de medida.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#DIR-01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Horas de mistura"),
        Coluna("atividade", "Atividade", TEXTO, CRIAR, "Código da Atividade (obrigatório ao criar).", exemplo="AT-01"),
        Coluna("base", "Base", OPCAO, CRIAR, "Tempo (horas do roteiro × volume), Quantidade produzida ou Custo primário (custo do produto × volume).", BASE_DIRECIONADOR, "Tempo"),
    )),
    Aba("insumos", "Insumos", "Matérias-primas e embalagens com preço de compra.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#ING01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Aveia em flocos"),
        Coluna("tipo", "Tipo", OPCAO, CRIAR, "Ingrediente ou Embalagem.", TIPO_INSUMO, "Ingrediente"),
        Coluna("unidade", "Unidade", TEXTO, OPCIONAL, "Unidade do preço de compra (kg, l, un, cx…); vazio = kg ao criar.", exemplo="kg"),
        Coluna("valor_compra_unitario", "Valor de compra (R$/kg ou un)", DECIMAL, OPCIONAL, "Preço unitário de compra.", exemplo=10),
        Coluna("frete", "Frete (R$)", DECIMAL, OPCIONAL, "Frete por unidade.", exemplo=0.5),
        Coluna("ipi_pct", "IPI (%)", PCT, OPCIONAL, "Ex.: 5%.", exemplo=0.05),
        Coluna("icms_pct", "ICMS (%)", PCT, OPCIONAL, "Ex.: 12% (crédito).", exemplo=0.12),
        _ATUALIZADO_EM,
        *_CREDITOS,
    )),
    Aba("produtos", "Produtos", "Cadastro de itens de produção: produtos acabados, semiacabados e de revenda (ficha técnica).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#PROD01"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Granola 1 kg"),
        Coluna("tipo", "Tipo", OPCAO, CRIAR, "Acabado, Semiacabado ou Revenda.", TIPO_PRODUTO, "Acabado"),
        Coluna("rendimento_kg", "Rendimento (kg)", DECIMAL, OPCIONAL, "Quanto rende um lote, em kg.", exemplo=None),
        Coluna("rendimento_un", "Rendimento (un)", DECIMAL, OPCIONAL, "Quanto rende um lote, em unidades.", exemplo=100),
        Coluna("qtd_estimada_producao_mes", "Produção estimada/mês", DECIMAL, OPCIONAL, "Usada no rateio de despesas.", exemplo=1000),
        Coluna("unidade", "Unidade", TEXTO, OPCIONAL, "Unidade em que o produto é consumido como insumo de outro (kg, un, l…); vazio = kg ao criar.", exemplo="kg"),
        Coluna("base_quantidade", "Base da formulação", DECIMAL, OPCIONAL, "A bacia: quanto a formulação processa, na Unidade do produto (rendimento real = base × (1 − perda)).", exemplo=None),
        Coluna("perda_pct", "Perda do processo (%)", PCT, OPCIONAL, "Evaporação/desperdício do processo (menor que 100%).", exemplo=None),
        Coluna("custo_compra", "Custo de compra (R$)", DECIMAL, OPCIONAL, "Só revenda: custo de compra por unidade.", exemplo=None),
        Coluna("tabela_de_precos", "Tabela de Preços", OPCAO, OPCIONAL, "Sim = produto cabeça da Tabela de Preços: o custeio parte dele e da estrutura que ele usa. Vazio: novo = Sim para Acabado/Revenda e Não para Semiacabado; existente não muda.", SIM_NAO, "Sim"),
        _ATUALIZADO_EM,
        *_CREDITOS,
    )),
    Aba("roteiros", "Roteiros", "Estrutura de cada Produto: as linhas do roteiro de produção (elementos de custo, insumos e semiacabados).", (
        Coluna("produto", "Produto", TEXTO, SEMPRE, "Código do Produto (pode estar na aba Produtos).", exemplo="PROD01"),
        Coluna("atividade", "Atividade", TEXTO, SEMPRE, "Código da Atividade (veja a aba Referência).", exemplo="AT-01"),
        Coluna("tipo", "Tipo de linha", OPCAO, SEMPRE, "Mão de obra, Instalação, Máquina, Outros, Insumo ou Semiacabado.", TIPO_ROTEIRO, "Insumo"),
        Coluna("recurso", "Recurso / Insumo", TEXTO, SEMPRE, "Código do grupo de Mão de obra (Depto-Cargo, ex.: 1.1-CG01-F; o FOPAG de um colaborador vale como o grupo dele), da Instalação/Máquina/Outros, do Insumo ou do Produto semiacabado.", exemplo="ING01"),
        Coluna("quantidade", "Quantidade (h ou kg)", DECIMAL, CRIAR, "Horas por lote (mão de obra/instalação/máquina/outros) ou, nos insumos e semiacabados, a quantidade na Unidade da linha (kg se vazia).", exemplo=25),
        Coluna("direcionador", "Direcionador", TEXTO, OPCIONAL, "Só mão de obra, instalação, máquina e outros: código do Direcionador (base tempo) pelo qual o elemento é alocado ao produto; a Atividade tem de ser a dele.", exemplo="DIR-01"),
        Coluna("unidade", "Unidade", TEXTO, OPCIONAL, "Só insumo e semiacabado: unidade da quantidade (kg, l, un…); vazio = não mexe (nova linha = kg).", exemplo="kg"),
        Coluna("perda_pct", "Perda (%)", PCT, OPCIONAL, "Só insumo e semiacabado: perda própria da linha.", exemplo=None),
        Coluna("ordem", "Ordem", INTEIRO, OPCIONAL, "Posição da linha dentro da Atividade (vazio = não mexe).", exemplo=None),
        _ATUALIZADO_EM,
    )),
    Aba("cenarios", "Centros de Resultados", "Centros de Resultados: canais de venda e desconto comercial (despesas adicionais na aba Despesas; destino das vendas na aba Mix de Destinos).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#VAREJO"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Varejo"),
        Coluna("descricao", "Descrição", TEXTO, OPCIONAL, "Descrição adicional do Centro de Resultados.", exemplo="Redes de supermercados"),
        Coluna("percentual_desconto", "Desconto (%)", PCT, OPCIONAL, "Desconto comercial do Centro.", exemplo=0.05),
    )),
    Aba("planejamentos", "Planejamentos", "Planejamentos (orçamentos).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#PLAN27"),
        Coluna("nome", "Nome", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Orçamento 2027"),
    )),
    Aba("volumes", "Volumes", "Volume projetado por Planejamento, Cenário e Produto.", (
        Coluna("planejamento", "Planejamento", TEXTO, SEMPRE, "Código do Planejamento.", exemplo="PLAN27"),
        Coluna("cenario", "Cenário", TEXTO, SEMPRE, "Código do Cenário.", exemplo="VAREJO"),
        Coluna("produto", "Produto", TEXTO, SEMPRE, "Código do Produto.", exemplo="PROD01"),
        Coluna("quantidade", "Quantidade", DECIMAL, SEMPRE, "Unidades projetadas.", exemplo=5000),
    )),
    Aba("despesas", "Despesas", "Despesas do Planejamento (fixas e variáveis) e as adicionais de cada Centro de Resultados.", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#DESP01"),
        Coluna("titulo", "Título", TEXTO, CRIAR, "Obrigatório ao criar.", exemplo="Aluguel da fábrica"),
        Coluna("tipo", "Tipo", OPCAO, CRIAR, "Fixa (valor mensal, rateada pelo Direcionador) ou Variável (% da receita bruta).", TIPO_DESPESA, "Fixa"),
        Coluna("plano_de_contas", "Plano de Contas", TEXTO, CRIAR, "Código de uma conta analítica (veja a aba Referência).", exemplo="3.1.01"),
        Coluna("centro_de_custo", "Centro de Custo", TEXTO, CRIAR, "Código de um Centro de Custo.", exemplo="1.1"),
        Coluna("direcionador", "Direcionador", TEXTO, OPCIONAL, "Só fixa (obrigatório ao criar): o critério de rateio entre os produtos.", exemplo="DIR-01"),
        Coluna("valor", "Valor (R$/mês)", DECIMAL, OPCIONAL, "Só fixa: valor mensal.", exemplo=5000),
        Coluna("percentual_receita", "% da receita", PCT, OPCIONAL, "Só variável: % sobre a receita bruta (maior que 0).", exemplo=0.03),
        Coluna("cenario", "Centro de Resultados", TEXTO, OPCIONAL, "Vazio = despesa do Planejamento; com o código de um Centro de Resultados = despesa adicional só dele (não muda depois de criada).", exemplo=None),
        Coluna("descricao", "Descrição", TEXTO, OPCIONAL, "Observação livre.", exemplo=None),
        *_CREDITOS,
    )),
    Aba("aliquotas", "Alíquotas", "CBS e IR/CSLL por vigência (mês a partir do qual a alíquota vale).", (
        Coluna("imposto", "Imposto", OPCAO, SEMPRE, "CBS ou IR/CSLL.", TIPO_ALIQUOTA, "CBS"),
        Coluna("vigencia", "Vigência (mês)", MES, SEMPRE, "Mês (AAAA-MM) de início da alíquota.", exemplo="2027-01"),
        Coluna("aliquota", "Alíquota (%)", PCT, SEMPRE, "Ex.: 8,8%.", exemplo=0.088),
        Coluna("nota", "Nota", TEXTO, OPCIONAL, "Observação livre (vazio = não mexe).", exemplo=None),
    )),
    Aba("icms_destinos", "ICMS Destinos", "ICMS da venda por UF de destino (as 27 UFs já existem; informe só o que mudar).", (
        Coluna("uf", "UF", TEXTO, SEMPRE, "Sigla da UF (BA, SP, PE…).", exemplo="SP"),
        Coluna("aliquota", "Alíquota de venda (%)", PCT, OPCIONAL, "Alíquota do ICMS nessa UF (vazio = não mexe).", exemplo=0.07),
        Coluna("reducao_base", "Redução de base (%)", PCT, OPCIONAL, "Redução da base de cálculo (vazio = não mexe).", exemplo=0),
    )),
    Aba("icms_compras", "ICMS Compras", "Alíquota do crédito de ICMS das compras, por origem.", (
        Coluna("origem", "Origem da compra", OPCAO, SEMPRE, "Bahia, Sul/Sudeste ou N/NE/CO/ES.", ORIGEM_ICMS, "Bahia"),
        Coluna("aliquota", "Alíquota de crédito (%)", PCT, SEMPRE, "Ex.: 20,5%.", exemplo=0.205),
    )),
    Aba("mix", "Mix de Destinos", "Destino das vendas de cada Centro de Resultados (% da receita por UF). As linhas de um Centro SUBSTITUEM o mix dele e precisam somar 100%.", (
        Coluna("cenario", "Centro de Resultados", TEXTO, SEMPRE, "Código do Centro de Resultados.", exemplo="VAREJO"),
        Coluna("uf", "UF", TEXTO, SEMPRE, "Sigla da UF de destino.", exemplo="BA"),
        Coluna("percentual", "% da receita", PCT, SEMPRE, "Parte da receita do Centro vendida para essa UF.", exemplo=0.7),
    )),
    Aba("desenvolve", "Desenvolve-BA", "Parâmetros do benefício Desenvolve-BA (uma linha só; campo vazio = não mexe).", (
        Coluna("ativo", "Ativo", OPCAO, OPCIONAL, "Sim liga o benefício.", SIM_NAO, "Não"),
        Coluna("pct_dilatado", "% dilatado", PCT, OPCIONAL, "% do saldo devedor de ICMS dilatado.", exemplo=0.9),
        Coluna("pct_pago_a_vista", "% pago à vista", PCT, OPCIONAL, "% do saldo dilatado pago à vista.", exemplo=0.2),
        Coluna("pct_fundo_pobreza", "% Fundo de Pobreza", PCT, OPCIONAL, "% de Fundo de Pobreza.", exemplo=0),
        Coluna("plano_de_contas", "Conta da reserva", TEXTO, OPCIONAL, "Conta analítica do Plano de Contas que recebe a reserva de incentivo fiscal.", exemplo=None),
        Coluna("observacao", "Observação", TEXTO, OPCIONAL, "Observação livre.", exemplo=None),
    )),
    Aba("premissas", "Premissas", "Premissas dos Planejamentos (o porquê dos números).", (
        Coluna("codigo", "Código", TEXTO, SEMPRE, "Até 20 caracteres.", exemplo="#PR01"),
        Coluna("planejamento", "Planejamento", TEXTO, CRIAR, "Código do Planejamento.", exemplo="PLAN27"),
        Coluna("tipo", "Tipo", OPCAO, CRIAR, "Comercial, Operacional, Despesas ou Financeiro.", TIPO_PREMISSA, "Comercial"),
        Coluna("texto", "Texto", TEXTO, CRIAR, "Até 1.000 caracteres.", exemplo="Crescimento de 8% no varejo"),
    )),
)

ROTULOS_OPCAO = {  # valor interno -> como aparece na lista suspensa do modelo
    "fixo": "Fixo", "variavel": "Variável", "ambiente": "Instalação", "maquina": "Máquina", "outros": "Outros", "funcionario": "Mão de obra",
    "mao-de-obra": "Mão de obra", "insumo": "Insumo", "semiacabado": "Semiacabado", "semi_acabado": "Semiacabado",
    "ingrediente": "Ingrediente",
    "embalagem": "Embalagem", "acabado": "Acabado", "comercial": "Comercial", "operacional": "Operacional",
    "despesas": "Despesas", "financeiro": "Financeiro", "receita": "Receita", "custo": "Custo", "imposto": "Imposto",
    "sim": "Sim", "nao": "Não", "tempo": "Tempo", "quantidade_produzida": "Quantidade produzida", "revenda": "Revenda",
    "fixa": "Fixa", "cbs": "CBS", "ir_csll": "IR/CSLL", "BA": "Bahia", "SUL_SUDESTE": "Sul/Sudeste", "NORTE_NE_CO_ES": "N/NE/CO/ES",
}


def rotulos_da_coluna(coluna: "Coluna") -> list[str]:
    """Rótulos de exibição (sem repetir) das opções de uma coluna do tipo OPCAO, na ordem de declaração."""
    vistos: list[str] = []
    for valor in coluna.opcoes.values():
        rotulo = ROTULOS_OPCAO.get(valor, valor)
        if rotulo not in vistos:
            vistos.append(rotulo)
    return vistos


ABAS_POR_NOME = {a.nome: a for a in ABAS}
# Planilhas antigas: as abas "Ambientes" e "Funcionários" foram renomeadas para "Instalações" e "Mão de obra" e continuam sendo lidas.
ABAS_POR_NOME |= {"Ambientes": ABAS_POR_NOME["Instalações"], "Funcionários": ABAS_POR_NOME["Mão de obra"], "Cenários": ABAS_POR_NOME["Centros de Resultados"]}
ABAS_AUXILIARES = ("Instruções", "Referência")  # existem no modelo, mas não são importadas
