package intellij

import (
	"Sithego/themer"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"text/template"
)

type Adapter struct {
	OutputDir string
}

type Option func(*Adapter)

func WithOutputDir(dir string) Option {
	abs, err := filepath.Abs(dir)
	if err != nil {
		panic(err)
	}
	return func(a *Adapter) {
		a.OutputDir = abs
	}
}

func New(opt ...Option) *Adapter {
	home, _ := os.UserHomeDir()
	a := &Adapter{
		OutputDir: home + "/.themes/",
	}
	for _, o := range opt {
		o(a)
	}
	return a
}

func (a *Adapter) Name() string {
	return "IntelliJ"
}

func (a *Adapter) Generate(t themer.Theme) error {
	// 1. Create temporary directory structure for JAR bundling
	tmpDir, err := os.MkdirTemp("", "intellij-theme-*")
	if err != nil {
		return err
	}
	defer func(path string) {
		err := os.RemoveAll(path)
		if err != nil {

		}
	}(tmpDir)

	metaInfDir := filepath.Join(tmpDir, "META-INF")
	if err := os.MkdirAll(metaInfDir, 0775); err != nil {
		return err
	}

	funcMap := template.FuncMap{
		"lower": strings.ToLower,
	}

	// 2. Generate plugin.xml
	pluginTempl := template.New("template.plugin.xml").Funcs(funcMap)
	pluginTempl, err = pluginTempl.ParseFiles("themer/adapters/intellij/template.plugin.xml")
	if err != nil {
		return err
	}
	pluginFile, err := os.Create(filepath.Join(metaInfDir, "plugin.xml"))
	if err != nil {
		return err
	}
	if err := pluginTempl.Execute(pluginFile, struct{ Theme themer.Theme }{Theme: t}); err != nil {
		_ = pluginFile.Close()
		return err
	}
	_ = pluginFile.Close()

	// 3. Generate .theme.json
	themeTempl, err := template.ParseFiles("themer/adapters/intellij/template.theme.json")
	if err != nil {
		return err
	}
	themeName := t.Meta.Name + ".theme.json"
	themeFile, err := os.Create(filepath.Join(tmpDir, themeName))
	if err != nil {
		return err
	}
	if err := themeTempl.Execute(themeFile, struct{ Theme themer.Theme }{Theme: t}); err != nil {
		_ = themeFile.Close()
		return err
	}
	_ = themeFile.Close()

	// 4. Bundle everything into a JAR (using zip)
	jarName := t.Meta.Name + ".jar"
	outputDir := filepath.Join(a.OutputDir, t.Meta.Name, "intellij")
	if err := os.MkdirAll(outputDir, 0775); err != nil {
		return err
	}
	jarPath := filepath.Join(outputDir, jarName)
	_ = os.Remove(jarPath) // Remove old JAR if exists
	cmd := exec.Command("zip", "-r", jarPath, ".")
	cmd.Dir = tmpDir
	if err := cmd.Run(); err != nil {
		return err
	}

	return nil
}
