package user

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"gopkg.in/yaml.v3"
)

type Config struct {
	Name          string   `yaml:"name"`
	Description   string   `yaml:"description"`
	Provider      string   `yaml:"provider"`
	Model         string   `yaml:"model"`
	APIKeyEnv     string   `yaml:"api_key_env"`
	AvatarColor   string   `yaml:"avatar_color"`
	Preferences   Preferences `yaml:"preferences"`
}

type Preferences struct {
	Language string `yaml:"language"`
	Tone     string `yaml:"tone"`
}

type User struct {
	Config  Config
	Profile string // content from PROFILE.md
	Dir     string // users/<name>/
}

const DefaultUser = "default"

func Load(dir string) (*User, error) {
	userDir := filepath.Join(dir, DefaultUser)
	
	userMD, err := os.ReadFile(filepath.Join(userDir, "USER.md"))
	if err != nil {
		return nil, fmt.Errorf("read USER.md: %w", err)
	}
	
	cfg, err := parseFrontmatter(userMD)
	if err != nil {
		return nil, fmt.Errorf("parse USER.md: %w", err)
	}
	
	profile, _ := os.ReadFile(filepath.Join(userDir, "PROFILE.md"))
	
	if cfg.Provider == "" {
		cfg.Provider = "deepseek"
	}
	if cfg.APIKeyEnv == "" {
		cfg.APIKeyEnv = "DEEPSEEK_API_KEY"
	}
	if cfg.AvatarColor == "" {
		cfg.AvatarColor = "#5865F2"
	}
	
	return &User{Config: cfg, Profile: string(profile), Dir: userDir}, nil
}

func parseFrontmatter(data []byte) (Config, error) {
	var cfg Config
	if !bytes.HasPrefix(data, []byte("---")) {
		return cfg, fmt.Errorf("missing frontmatter")
	}
	parts := bytes.SplitN(data, []byte("---"), 3)
	if len(parts) < 3 {
		return cfg, fmt.Errorf("invalid frontmatter")
	}
	return cfg, yaml.Unmarshal(parts[1], &cfg)
}

func (u *User) SaveProfile(content string) error {
	return os.WriteFile(filepath.Join(u.Dir, "PROFILE.md"), []byte(content), 0644)
}

func (u *User) SaveConfig(cfg Config) error {
	u.Config = cfg
	var buf bytes.Buffer
	buf.WriteString("---\n")
	enc := yaml.NewEncoder(&buf)
	enc.Encode(cfg)
	buf.WriteString("---\n")
	return os.WriteFile(filepath.Join(u.Dir, "USER.md"), buf.Bytes(), 0644)
}

func (u *User) BuildUserXML() string {
	var xml strings.Builder
	xml.WriteString("<user_info>\n")
	xml.WriteString(fmt.Sprintf("  <name>%s</name>\n", u.Config.Name))
	xml.WriteString(fmt.Sprintf("  <description>%s</description>\n", u.Config.Description))
	if u.Profile != "" {
		xml.WriteString("  <profile>\n")
		xml.WriteString(u.Profile)
		xml.WriteString("  </profile>\n")
	}
	xml.WriteString("</user_info>")
	return xml.String()
}

func (u *User) GetProvider() string {
	return u.Config.Provider
}

func (u *User) GetModel() string {
	return u.Config.Model
}

func (u *User) GetAPIKeyEnv() string {
	return u.Config.APIKeyEnv
}

func (u *User) GetName() string {
	return u.Config.Name
}

func (u *User) GetAvatarColor() string {
	return u.Config.AvatarColor
}

func Exists(dir string) bool {
	_, err := os.Stat(filepath.Join(dir, DefaultUser, "USER.md"))
	return err == nil
}
