package l4g

import (
	"fmt"
	"os"
	"path/filepath"
	"time"
)

type FileLogger struct {
	filePath string
}

func NewFileLogger(filePath string) *FileLogger {
	return &FileLogger{filePath: filePath}
}

func (f *FileLogger) Write(entry Entry) error {
	err := f.ensureLogFileExists()
	if err != nil {
		return err
	}

	file, err := os.OpenFile(f.filePath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("failed to open log file: %w", err)
	}
	defer file.Close()

	timestamp := entry.Timestamp.Format(time.RFC3339)

	var category string
	switch entry.Category {
	case CATEGORY_SYSTEM:
		category = "SYSTEM"
	case CATEGORY_ADMIN:
		category = "ADMIN"
	case CATEGORY_USER:
		category = "USER"
	case CATEGORY_ORG:
		category = "ORG"
	case CATEGORY_AUDIT:
		category = "AUDIT"
	case CATEGORY_AUTH:
		category = "AUTH"
	default:
		category = "UNKNOWN"
	}

	var logType string
	switch entry.LogType {
	case TYPE_DEBUG:
		logType = "DEBUG"
	case TYPE_INFO:
		logType = "INFO"
	case TYPE_WARN:
		logType = "WARN"
	case TYPE_ERROR:
		logType = "ERROR"
	default:
		logType = "UNKNOWN"
	}

	content := ""
	if entry.Content != nil {
		content = *entry.Content
	}

	logLine := fmt.Sprintf("[%s] %s/%s: %s", timestamp, category, logType, content)

	if entry.StructuredContent != nil {
		logLine += fmt.Sprintf(" | Details: %s", *entry.StructuredContent)
	}

	logLine += "\n"

	_, err = file.WriteString(logLine)
	if err != nil {
		return fmt.Errorf("failed to write to log file: %w", err)
	}

	return nil
}

func (f *FileLogger) Fatal(entry Entry) error {
	err := f.Write(entry)
	if err != nil {
		return err
	}
	os.Exit(1)
	return nil
}

func (f *FileLogger) ensureLogFileExists() error {
	dir := filepath.Dir(f.filePath)
	if err := os.MkdirAll(dir, 0755); err != nil {
		return fmt.Errorf("failed to create log directory: %w", err)
	}

	if _, err := os.Stat(f.filePath); os.IsNotExist(err) {
		file, err := os.Create(f.filePath)
		if err != nil {
			return fmt.Errorf("failed to create log file: %w", err)
		}
		file.Close()
	}

	return nil
}
