package server

import (
	"encoding/json"
	"os"
	"path/filepath"
	"sort"
	"sync"
	"time"
)

type ConversionRecord struct {
	Filepath  string   `json:"filepath"`
	Type      string   `json:"type"`
	Outputs   []string `json:"outputs"`
	CSVDir    string   `json:"csv_dir"`
	Timestamp string   `json:"timestamp"`
}

var conversionsMutex sync.Mutex

func conversionsLogPath() string {
	if p := os.Getenv("CONVERSIONS_LOG_PATH"); p != "" {
		return p
	}
	return "/app/data/conversions.json"
}

func logConversion(r ConversionRecord) error {
	conversionsMutex.Lock()
	defer conversionsMutex.Unlock()

	r.Timestamp = time.Now().UTC().Format(time.RFC3339)
	records, err := readConversionsUnlocked()
	if err != nil {
		return err
	}
	records = append(records, r)
	return writeConversionsUnlocked(records)
}

func listConversions(typeFilter string) ([]ConversionRecord, error) {
	conversionsMutex.Lock()
	defer conversionsMutex.Unlock()

	records, err := readConversionsUnlocked()
	if err != nil {
		return nil, err
	}

	out := make([]ConversionRecord, 0)
	for _, r := range records {
		if typeFilter == "" || r.Type == typeFilter {
			out = append(out, r)
		}
	}

	sort.Slice(out, func(i, j int) bool {
		return out[i].Timestamp > out[j].Timestamp
	})
	return out, nil
}

func conversionStatusFor(path string) (bool, string) {
	conversionsMutex.Lock()
	defer conversionsMutex.Unlock()

	records, err := readConversionsUnlocked()
	if err != nil {
		return false, ""
	}

	var latest time.Time
	var converted bool
	var convertedAt string
	for _, r := range records {
		if r.Filepath != path {
			continue
		}
		t, err := time.Parse(time.RFC3339, r.Timestamp)
		if err != nil {
			continue
		}
		if t.After(latest) {
			latest = t
			converted = true
			convertedAt = r.Timestamp
		}
	}
	return converted, convertedAt
}

func readConversionsUnlocked() ([]ConversionRecord, error) {
	p := conversionsLogPath()
	data, err := os.ReadFile(p)
	if err != nil {
		if os.IsNotExist(err) {
			return []ConversionRecord{}, nil
		}
		return nil, err
	}

	var records []ConversionRecord
	if err := json.Unmarshal(data, &records); err != nil {
		return nil, err
	}
	return records, nil
}

func writeConversionsUnlocked(records []ConversionRecord) error {
	p := conversionsLogPath()
	if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
		return err
	}
	data, err := json.MarshalIndent(records, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(p, data, 0644)
}
