package init

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

	"github.com/gethuman-sh/human/errors"
	"github.com/gethuman-sh/human/internal/claude"
)

type projectConfigStep struct {
	state *WizardState
}

// NewProjectConfigStep creates a WizardStep that ensures .humanconfig.yaml
// has a project: field, devcontainer: section, and proxy: section for agent readiness.
func NewProjectConfigStep(state *WizardState) WizardStep {
	return &projectConfigStep{state: state}
}

func (s *projectConfigStep) Name() string { return "project-config" }

func (s *projectConfigStep) Run(w io.Writer, fw claude.FileWriter) ([]string, error) {
	existing, _ := fw.ReadFile(configPath)
	content := string(existing)

	cwd, err := os.Getwd()
	if err != nil {
		return nil, errors.WrapWithDetails(err, "determining working directory")
	}
	absDir, err := filepath.Abs(cwd)
	if err != nil {
		return nil, errors.WrapWithDetails(err, "resolving absolute path")
	}

	var additions []string

	if !hasYAMLKey(content, "project") {
		additions = append(additions, fmt.Sprintf("project: %s", yamlSafeString(filepath.Base(absDir))))
	}

	if !hasYAMLKey(content, "devcontainer") {
		if _, err := fw.ReadFile(devcontainerPath); err == nil {
			additions = append(additions, fmt.Sprintf("devcontainer:\n  configdir: %s", yamlSafeString(absDir)))
		}
	}

	if s.state.VaultProvider != "" && !hasYAMLKey(content, "vault") {
		additions = append(additions, generateVaultYAML(s.state.VaultProvider, s.state.VaultAccount))
	}

	if s.state.ProxyEnabled && !hasYAMLKey(content, "proxy") {
		additions = append(additions, generateProxyYAML(s.state.InterceptEnabled))
	}

	if len(additions) == 0 {
		return nil, nil
	}

	var buf strings.Builder
	if len(content) > 0 {
		buf.WriteString(strings.TrimRight(content, "\n"))
		buf.WriteString("\n\n")
	}
	buf.WriteString(strings.Join(additions, "\n\n"))
	buf.WriteString("\n")

	if err := fw.WriteFile(configPath, []byte(buf.String()), 0o644); err != nil {
		return nil, errors.WrapWithDetails(err, "writing project config", "path", configPath)
	}

	_, _ = fmt.Fprintf(w, "Updated %s with project settings\n", configPath)
	return nil, nil
}

// hasYAMLKey checks if a top-level YAML key exists in the content.
// Uses line-start matching since the config is generated by our own templates.
func hasYAMLKey(content, key string) bool {
	prefix := key + ":"
	for _, line := range strings.Split(content, "\n") {
		if strings.HasPrefix(line, prefix) {
			return true
		}
	}
	return false
}

// generateVaultYAML returns the vault YAML section for .humanconfig.yaml.
func generateVaultYAML(provider, account string) string {
	var buf strings.Builder
	buf.WriteString("vault:\n")
	fmt.Fprintf(&buf, "  provider: %s", provider)
	if account != "" {
		fmt.Fprintf(&buf, "\n  account: %s", yamlSafeString(account))
	}
	return buf.String()
}

// generateProxyYAML returns the proxy YAML section for .humanconfig.yaml.
func generateProxyYAML(intercept bool) string {
	var buf strings.Builder
	buf.WriteString("proxy:\n")
	buf.WriteString("  mode: allowlist\n")
	buf.WriteString("  domains:")
	for _, d := range DefaultProxyDomains {
		fmt.Fprintf(&buf, "\n    - %q", d)
	}
	if intercept {
		buf.WriteString("\n  intercept:")
		buf.WriteString("\n    - \"api.anthropic.com\"")
	}
	return buf.String()
}
