package topdata

import (
	"encoding/json"
	"os"
	"path/filepath"
)

func importLegacyCreaturespeed(referenceBuilderDir, dataDir string, legacyTLK *legacyTLKData) (int, error) {
	_ = legacyTLK

	legacyDir := filepath.Join(referenceBuilderDir, "data", "creaturespeed")
	if _, err := os.Stat(legacyDir); err != nil {
		if os.IsNotExist(err) {
			return 0, nil
		}
		return 0, err
	}

	targetDir := filepath.Join(dataDir, "creaturespeed")
	targetPath := filepath.Join(targetDir, "creaturespeed.json")
	if _, err := os.Stat(targetPath); err == nil {
		obj, err := loadJSONObject(targetPath)
		if err == nil && countLegacyTLKRefsInValue(obj) == 0 {
			return 0, nil
		}
	}

	baseObj, err := loadJSONObject(filepath.Join(legacyDir, "base.json"))
	if err != nil {
		return 0, err
	}
	rows, err := mergeCreaturespeedRows(baseObj, filepath.Join(legacyDir, "modules"))
	if err != nil {
		return 0, err
	}
	if err := os.MkdirAll(targetDir, 0o755); err != nil {
		return 0, err
	}

	if err := removePathIfExists(filepath.Join(targetDir, "base.json")); err != nil {
		return 0, err
	}
	if err := removePathIfExists(filepath.Join(targetDir, "lock.json")); err != nil {
		return 0, err
	}
	if err := removePathIfExists(filepath.Join(targetDir, "modules")); err != nil {
		return 0, err
	}

	out := map[string]any{
		"output":  "creaturespeed.2da",
		"columns": baseObj["columns"],
		"rows":    rows,
	}

	raw, err := json.MarshalIndent(out, "", "  ")
	if err != nil {
		return 0, err
	}
	raw = append(raw, '\n')
	if err := os.WriteFile(targetPath, raw, 0o644); err != nil {
		return 0, err
	}
	return 1, nil
}

func mergeCreaturespeedRows(baseObj map[string]any, modulesDir string) ([]any, error) {
	rawRows, ok := baseObj["rows"].([]any)
	if !ok {
		return nil, nil
	}
	rows := make([]map[string]any, 0, len(rawRows))
	byID := map[int]map[string]any{}
	for _, raw := range rawRows {
		row, ok := deepCopyValue(raw).(map[string]any)
		if !ok {
			continue
		}
		delete(row, "key")
		rows = append(rows, row)
		if rawID, ok := row["id"]; ok {
			id, err := asInt(rawID)
			if err != nil {
				return nil, err
			}
			byID[id] = row
		}
	}

	modulePaths, err := collectModulePaths(modulesDir)
	if err != nil {
		return nil, err
	}
	for _, path := range modulePaths {
		obj, err := loadJSONObject(path)
		if err != nil {
			return nil, err
		}
		overrideList, ok := obj["overrides"].([]any)
		if !ok {
			continue
		}
		for _, raw := range overrideList {
			override, ok := raw.(map[string]any)
			if !ok {
				continue
			}
			rawID, ok := override["id"]
			if !ok {
				continue
			}
			id, err := asInt(rawID)
			if err != nil {
				return nil, err
			}
			row := byID[id]
			if row == nil {
				continue
			}
			for key, value := range override {
				if key == "id" || key == "key" || key == "_tlk" {
					continue
				}
				row[key] = deepCopyValue(value)
			}
		}
	}

	out := make([]any, 0, len(rows))
	for _, row := range rows {
		out = append(out, row)
	}
	return out, nil
}

func removePathIfExists(path string) error {
	if _, err := os.Stat(path); err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	return os.RemoveAll(path)
}
