package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"time"

	"gitlab.com/sistema-pro/xmlcolibex/internal/banco"
	"gitlab.com/sistema-pro/xmlcolibex/internal/configuracao"
	"gitlab.com/sistema-pro/xmlcolibex/internal/log"
	"gitlab.com/sistema-pro/xmlcolibex/internal/pipeline"
)

func main() {
	if len(os.Args) < 2 {
		uso()
		os.Exit(1)
	}
	switch os.Args[1] {
	case "executar-tudo":
		executarTudo()
	case "executar-feed":
		executarFeed(os.Args[2:])
	case "status":
		status()
	case "versao":
		fmt.Println("gerador-xml", configuracao.Versao)
	default:
		uso()
		os.Exit(1)
	}
}

func uso() {
	fmt.Fprintf(os.Stderr, `gerador-xml — exportação XML Colibex em disco

Comandos:
  executar-tudo [--force]    Gera feeds ativos (incremental: 1x/dia por feed)
  executar-feed --hash=XXX   Gera um único feed (sempre regera)
  status                     Última execução (resumo JSON)
  versao                     Versão do build

Configure .env ou .env.server (MySQL socket).
`)
}

func executarTudo() {
	fs := flag.NewFlagSet("executar-tudo", flag.ExitOnError)
	force := fs.Bool("force", false, "regenera todos os feeds mesmo se já gerados hoje")
	_ = fs.Parse(os.Args[2:])

	_, exec, err := montarExecutor()
	if err != nil {
		fatal(err)
	}
	exec.ForcarRegeneracao = *force
	defer exec.Gerenciador.Fechar()
	ctx := context.Background()
	res, err := exec.ExecutarTudo(ctx)
	if err != nil {
		fatal(err)
	}
	msg := fmt.Sprintf("Concluído: %d gerados, %d ignorados, %d erros", res.Gerados, res.Ignorados, res.Erros)
	if res.RemovidosOrfaos > 0 {
		msg += fmt.Sprintf(", %d órfãos removidos", res.RemovidosOrfaos)
	}
	fmt.Printf("%s em %s\n", msg, res.Duracao.Round(time.Second))
	if res.Erros > 0 {
		os.Exit(1)
	}
}

func executarFeed(args []string) {
	fs := flag.NewFlagSet("executar-feed", flag.ExitOnError)
	hash := fs.String("hash", "", "hash do xml_config")
	_ = fs.Parse(args)
	if *hash == "" {
		fatal(fmt.Errorf("use --hash=XXX"))
	}
	_, exec, err := montarExecutor()
	if err != nil {
		fatal(err)
	}
	defer exec.Gerenciador.Fechar()
	if err := exec.ExecutarFeed(context.Background(), *hash); err != nil {
		fatal(err)
	}
	fmt.Println("OK — feed gerado.")
}

func status() {
	cfg, err := configuracao.Carregar()
	if err != nil {
		fatal(err)
	}
	b, err := os.ReadFile(cfg.ResumoExecucaoPath)
	if err != nil {
		fatal(fmt.Errorf("sem resumo: %w", err))
	}
	var pretty json.RawMessage
	if err := json.Unmarshal(b, &pretty); err == nil {
		out, _ := json.MarshalIndent(pretty, "", "  ")
		fmt.Println(string(out))
		return
	}
	fmt.Println(string(b))
}

func montarExecutor() (*configuracao.Config, *pipeline.Executor, error) {
	cfg, err := configuracao.Carregar()
	if err != nil {
		return nil, nil, err
	}
	gm := banco.NovoGerenciador(cfg.MySQLDSN, cfg.MaxConexoesDB())
	return cfg, &pipeline.Executor{
		Cfg:         cfg,
		Gerenciador: gm,
		LogVisual:   log.Padrao,
		LogArquivo:  log.NovoArquivo(cfg.LogErrosPath, cfg.ResumoExecucaoPath),
	}, nil
}

func fatal(err error) {
	fmt.Fprintf(os.Stderr, "ERRO: %v\n", err)
	os.Exit(1)
}
