package identitynotice

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/desktop/prompts"
)

const FileName = ".identity-notice.json"

const PromptTemplatePath = "notices/identity_notice.md"

type Pending struct {
	CurrentName string `json:"currentName"`
	OldName     string `json:"oldName,omitempty"`
}

func Path(workDir string) string {
	return filepath.Join(workDir, FileName)
}

func Load(workDir string) (Pending, bool, error) {
	data, err := os.ReadFile(Path(workDir))
	if err != nil {
		if os.IsNotExist(err) {
			return Pending{}, false, nil
		}
		return Pending{}, false, err
	}

	var pending Pending
	if err := json.Unmarshal(data, &pending); err != nil {
		return Pending{}, false, err
	}
	pending = normalize(pending)
	if pending.CurrentName == "" {
		return Pending{}, false, nil
	}
	return pending, true, nil
}

func Save(workDir string, pending Pending) error {
	pending = normalize(pending)
	if pending.CurrentName == "" {
		return Clear(workDir)
	}
	if err := os.MkdirAll(workDir, 0755); err != nil {
		return err
	}
	data, err := json.Marshal(pending)
	if err != nil {
		return err
	}
	path := Path(workDir)
	tmpPath := fmt.Sprintf("%s.tmp-%d", path, time.Now().UTC().UnixNano())
	if err := os.WriteFile(tmpPath, data, 0644); err != nil {
		return err
	}
	if err := os.Rename(tmpPath, path); err != nil {
		_ = os.Remove(tmpPath)
		return err
	}
	return nil
}

func Clear(workDir string) error {
	err := os.Remove(Path(workDir))
	if err == nil || os.IsNotExist(err) {
		return nil
	}
	return err
}

func Format(pending Pending) string {
	pending = normalize(pending)
	if pending.CurrentName == "" {
		return ""
	}
	return prompts.MustRender(PromptTemplatePath, map[string]string{
		"CurrentName": pending.CurrentName,
		"OldName":     pending.OldName,
	})
}

func normalize(pending Pending) Pending {
	pending.CurrentName = strings.TrimSpace(pending.CurrentName)
	pending.OldName = strings.TrimSpace(pending.OldName)
	if pending.OldName != "" && pending.OldName == pending.CurrentName {
		pending.OldName = ""
	}
	return pending
}
