package log

import (
	"encoding/json"
	"os"
	"sync"
	"time"
)

type ResumoExecucao struct {
	ID            string    `json:"id"`
	Inicio        time.Time `json:"inicio"`
	Fim           time.Time `json:"fim"`
	DuracaoSeg    float64   `json:"duracao_seg"`
	Gerados       int       `json:"gerados"`
	Erros         int       `json:"erros"`
	Ignorados       int `json:"ignorados"`
	RemovidosOrfaos int `json:"removidos_orfaos,omitempty"`
	TotalFeeds      int `json:"total_feeds"`
	UltimoErro    string    `json:"ultimo_erro,omitempty"`
}

type Arquivo struct {
	mu          sync.Mutex
	errosPath   string
	resumoPath  string
	ultimoErro  string
}

func NovoArquivo(errosPath, resumoPath string) *Arquivo {
	return &Arquivo{errosPath: errosPath, resumoPath: resumoPath}
}

func (a *Arquivo) RegistrarErro(feedID int, hash string, err error) {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.ultimoErro = err.Error()
	f, openErr := os.OpenFile(a.errosPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
	if openErr != nil {
		return
	}
	defer f.Close()
	ts := time.Now().Format("2006-01-02 15:04:05")
	_, _ = f.WriteString(ts + " feed=" + itoa(feedID) + " hash=" + hash + " err=" + err.Error() + "\n")
}

func (a *Arquivo) SalvarResumo(r ResumoExecucao) error {
	a.mu.Lock()
	defer a.mu.Unlock()
	if r.UltimoErro == "" && a.ultimoErro != "" {
		r.UltimoErro = a.ultimoErro
	}
	b, err := json.MarshalIndent(r, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(a.resumoPath, b, 0o644)
}

func itoa(n int) string {
	if n == 0 {
		return "0"
	}
	var b [20]byte
	i := len(b)
	neg := n < 0
	if neg {
		n = -n
	}
	for n > 0 {
		i--
		b[i] = byte('0' + n%10)
		n /= 10
	}
	if neg {
		i--
		b[i] = '-'
	}
	return string(b[i:])
}
