package models

import (
	"regexp"
	"strings"
)

var anthropicToCursor = map[string]string{
	"claude-opus-4-6":            "opus-4.6",
	"claude-opus-4.6":            "opus-4.6",
	"claude-sonnet-4-6":          "sonnet-4.6",
	"claude-sonnet-4.6":          "sonnet-4.6",
	"claude-opus-4-5":            "opus-4.5",
	"claude-opus-4.5":            "opus-4.5",
	"claude-sonnet-4-5":          "sonnet-4.5",
	"claude-sonnet-4.5":          "sonnet-4.5",
	"claude-opus-4":              "opus-4.6",
	"claude-sonnet-4":            "sonnet-4.6",
	"claude-haiku-4-5-20251001":  "sonnet-4.5",
	"claude-haiku-4-5":           "sonnet-4.5",
	"claude-haiku-4-6":           "sonnet-4.6",
	"claude-haiku-4":             "sonnet-4.5",
	"claude-opus-4-6-thinking":   "opus-4.6-thinking",
	"claude-sonnet-4-6-thinking": "sonnet-4.6-thinking",
	"claude-opus-4-5-thinking":   "opus-4.5-thinking",
	"claude-sonnet-4-5-thinking": "sonnet-4.5-thinking",
}

type ModelAlias struct {
	CursorID    string
	AnthropicID string
	Name        string
}

var cursorToAnthropicAlias = []ModelAlias{
	{"opus-4.6", "claude-opus-4-6", "Claude 4.6 Opus"},
	{"opus-4.6-thinking", "claude-opus-4-6-thinking", "Claude 4.6 Opus (Thinking)"},
	{"sonnet-4.6", "claude-sonnet-4-6", "Claude 4.6 Sonnet"},
	{"sonnet-4.6-thinking", "claude-sonnet-4-6-thinking", "Claude 4.6 Sonnet (Thinking)"},
	{"opus-4.5", "claude-opus-4-5", "Claude 4.5 Opus"},
	{"opus-4.5-thinking", "claude-opus-4-5-thinking", "Claude 4.5 Opus (Thinking)"},
	{"sonnet-4.5", "claude-sonnet-4-5", "Claude 4.5 Sonnet"},
	{"sonnet-4.5-thinking", "claude-sonnet-4-5-thinking", "Claude 4.5 Sonnet (Thinking)"},
}

// cursorModelPattern matches cursor model IDs like "opus-4.6", "sonnet-4.7-thinking".
var cursorModelPattern = regexp.MustCompile(`^([a-zA-Z]+)-(\d+)\.(\d+)(-thinking)?$`)

// reverseDynamicPattern matches dynamically generated anthropic aliases
// like "claude-opus-4-7", "claude-sonnet-4-7-thinking".
var reverseDynamicPattern = regexp.MustCompile(`^claude-([a-zA-Z]+)-(\d+)-(\d+)(-thinking)?$`)

func generateDynamicAlias(cursorID string) (AnthropicAlias, bool) {
	m := cursorModelPattern.FindStringSubmatch(cursorID)
	if m == nil {
		return AnthropicAlias{}, false
	}
	family := m[1]
	major := m[2]
	minor := m[3]
	thinking := m[4]

	anthropicID := "claude-" + family + "-" + major + "-" + minor + thinking
	capFamily := strings.ToUpper(family[:1]) + family[1:]
	name := capFamily + " " + major + "." + minor
	if thinking == "-thinking" {
		name += " (Thinking)"
	}
	return AnthropicAlias{ID: anthropicID, Name: name}, true
}

func reverseDynamicAlias(anthropicID string) (string, bool) {
	m := reverseDynamicPattern.FindStringSubmatch(anthropicID)
	if m == nil {
		return "", false
	}
	return m[1] + "-" + m[2] + "." + m[3] + m[4], true
}

func ResolveToCursorModel(requested string) string {
	if strings.TrimSpace(requested) == "" {
		return ""
	}
	key := strings.ToLower(strings.TrimSpace(requested))
	if v, ok := anthropicToCursor[key]; ok {
		return v
	}
	if v, ok := reverseDynamicAlias(key); ok {
		return v
	}
	return strings.TrimSpace(requested)
}

type AnthropicAlias struct {
	ID   string
	Name string
}

func GetAnthropicModelAliases(availableCursorIDs []string) []AnthropicAlias {
	set := make(map[string]bool, len(availableCursorIDs))
	for _, id := range availableCursorIDs {
		set[id] = true
	}

	staticSet := make(map[string]bool, len(cursorToAnthropicAlias))
	var result []AnthropicAlias
	for _, a := range cursorToAnthropicAlias {
		if set[a.CursorID] {
			staticSet[a.CursorID] = true
			result = append(result, AnthropicAlias{ID: a.AnthropicID, Name: a.Name})
		}
	}

	for _, id := range availableCursorIDs {
		if staticSet[id] {
			continue
		}
		if alias, ok := generateDynamicAlias(id); ok {
			result = append(result, alias)
		}
	}
	return result
}
