/*
  O formato do código do serviço em cada prefeitura.

  Não existe formato único no Brasil: em Goiânia o código do serviço no
  município é "1.01", em Santos "9700500", em São Bernardo "1.01/102301" e em
  Campinas "181309900" (a atividade, o CNAE, com mais dois números no fim). A
  Spedy guarda, para cada cidade, uma nota de verdade que foi autorizada — o
  "exemplo". Daqui saem a dica embaixo do campo e os avisos quando o que a
  empresa digitou não tem a cara do que a cidade aceita.

  Nasceu da MK5 (Campinas, 21/09/2026): primeiro "13.05" (o item da lista
  nacional), depois o código copiado de um exemplo de outra atividade, e a
  atividade de comércio escolhida. A prefeitura não achava a regra do imposto
  e recusava com "tipoIncidencia is null". São avisos, não bloqueio: o exemplo
  é UMA nota que passou, não a regra inteira da cidade.
*/

export type ExemploDaCidade = { codigoMunicipal: string | null; cnae: string | null; itemLc116: string | null };

export type AvisoDoCodigo = {
  tipo: "formato" | "fora-das-atividades" | "outra-atividade";
  texto: string;
  /* A atividade da empresa que combina com o código digitado. */
  cnaeSugerido?: string;
};

const soDigitos = (valor: unknown) => String(valor ?? "").replace(/\D/g, "");
const texto = (valor: unknown) => (typeof valor === "string" && valor.trim() ? valor.trim() : null);

/* Onde a prefeitura publica a própria tabela de códigos, quando publica. */
export const CONSULTA_DA_PREFEITURA: Record<string, string> = {
  /* Campinas/SP: CNAE, item da lista, código e alíquota de cada atividade. */
  "3509502": "https://drm-codae.campinas.sp.gov.br/cnae.php",
};

/** Os três códigos do exemplo da Spedy para a cidade. */
export function lerExemploDaCidade(payload: unknown): ExemploDaCidade | null {
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) return null;
  const p = payload as Record<string, unknown>;
  const exemplo = { codigoMunicipal: texto(p.cityServiceCode), cnae: texto(p.cnaeCode), itemLc116: texto(p.federalServiceCode) };
  return exemplo.codigoMunicipal || exemplo.cnae || exemplo.itemLc116 ? exemplo : null;
}

export function formatarCnae(cnae: unknown) {
  const d = soDigitos(cnae);
  return d.length === 7 ? `${d.slice(0, 4)}-${d.slice(4, 5)}/${d.slice(5)}` : String(cnae ?? "");
}

/* A cidade monta o código a partir da atividade? Em Campinas,
   802000102 = atividade 8020-0/01 + "02". */
export function codigoComecaPelaAtividade(exemplo: ExemploDaCidade | null) {
  const codigo = soDigitos(exemplo?.codigoMunicipal);
  const cnae = soDigitos(exemplo?.cnae);
  return cnae.length === 7 && codigo.length > 7 && codigo.startsWith(cnae) && /^\d+$/.test(exemplo?.codigoMunicipal ?? "");
}

/* O que não é letra nem número, na ordem em que aparece: "1.01/102301" → "./". */
const separadores = (codigo: string) => codigo.replace(/[0-9A-Za-z]/g, "");

/**
 * A dica que vai embaixo do campo: o FORMATO que a cidade aceita. Quando o
 * código começa pela atividade, a dica já mostra o começo do código da
 * atividade escolhida, para ninguém copiar o exemplo de outra empresa.
 */
export function dicaDoCodigo(exemplo: ExemploDaCidade | null, cidade: string | null, cnaeEscolhido: string | null): string | null {
  const modelo = exemplo?.codigoMunicipal;
  if (!modelo) return null;
  const onde = cidade ? `Em ${cidade}` : "Nesta cidade";
  if (codigoComecaPelaAtividade(exemplo)) {
    const cnae = soDigitos(cnaeEscolhido);
    const extra = modelo.length - 7;
    const comeco = cnae.length === 7 ? ` Para a atividade ${formatarCnae(cnae)}, ele começa por ${cnae}, se ela for uma atividade de serviço na prefeitura.` : "";
    return `${onde}, o código é a atividade (CNAE) com mais ${extra} ${extra === 1 ? "número" : "números"} no fim: ${modelo.length} números, sem ponto.${comeco} O fim está no cadastro da empresa na prefeitura.`;
  }
  return `${onde}, o código tem este formato: ${modelo}. É só um exemplo de formato, não o código da sua empresa.`;
}

/** O que não bate entre o que foi digitado e o que a cidade aceita. */
export function conferirCodigoDoServico(input: {
  codigo: string | null;
  cnae: string | null;
  exemplo: ExemploDaCidade | null;
  cnaesDaEmpresa: string[];
  cidade: string | null;
}): AvisoDoCodigo[] {
  const avisos: AvisoDoCodigo[] = [];
  const codigo = String(input.codigo ?? "").trim();
  const modelo = input.exemplo?.codigoMunicipal?.trim() ?? "";
  if (!codigo || !modelo) return avisos;
  const onde = input.cidade ? `em ${input.cidade}` : "nesta cidade";

  const modeloSoNumeros = /^\d+$/.test(modelo);
  const formatoCerto = modeloSoNumeros ? /^\d+$/.test(codigo) && codigo.length === modelo.length : separadores(codigo) === separadores(modelo);
  if (!formatoCerto) {
    avisos.push({
      tipo: "formato",
      texto: modeloSoNumeros
        ? `O código ${onde} tem ${modelo.length} números, sem ponto. "${codigo}" é de outro formato: o item da lista nacional (como 13.05) não serve aqui.`
        : `O código ${onde} segue o formato ${modelo}. Confira se "${codigo}" está escrito do mesmo jeito.`,
    });
    return avisos;
  }

  if (codigoComecaPelaAtividade(input.exemplo)) {
    const atividadeDoCodigo = codigo.slice(0, 7);
    const escolhida = soDigitos(input.cnae);
    const daEmpresa = input.cnaesDaEmpresa.map(soDigitos);
    if (!daEmpresa.includes(atividadeDoCodigo)) {
      avisos.push({
        tipo: "fora-das-atividades",
        texto: `O código ${codigo} é da atividade ${formatarCnae(atividadeDoCodigo)}, que não é uma atividade da empresa. ${onde[0].toUpperCase()}${onde.slice(1)}, o código começa pela atividade: use o de uma atividade de serviço que a empresa tem.`,
      });
    } else if (escolhida && escolhida !== atividadeDoCodigo) {
      avisos.push({
        tipo: "outra-atividade",
        texto: `O código ${codigo} é da atividade ${formatarCnae(atividadeDoCodigo)}, mas a atividade escolhida é ${formatarCnae(escolhida)}. As duas precisam combinar.`,
        cnaeSugerido: atividadeDoCodigo,
      });
    }
  }
  return avisos;
}
