package android

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

	"github.com/titansys/appy-builder/internal/models"
)

// ConfigureSigning configures Gradle signing for release builds
func ConfigureSigning(baseDir, keystorePath string, config models.BuildConfig) error {
	buildGradlePath := filepath.Join(baseDir, "app", "build.gradle.kts")

	// Read existing build.gradle.kts
	content, err := os.ReadFile(buildGradlePath)
	if err != nil {
		return fmt.Errorf("failed to read build.gradle.kts: %w", err)
	}

	buildGradle := string(content)

	// Check if signing config already exists
	if strings.Contains(buildGradle, "signingConfigs {") {
		// Already has signing config, update it
		return updateSigningConfig(buildGradlePath, buildGradle, keystorePath, config)
	}

	// Add signing config
	return addSigningConfig(buildGradlePath, buildGradle, keystorePath, config)
}

func addSigningConfig(filePath, content, keystorePath string, config models.BuildConfig) error {
	// Find the android block
	androidIndex := strings.Index(content, "android {")
	if androidIndex == -1 {
		return fmt.Errorf("could not find 'android {' block in build.gradle.kts")
	}

	// Construct signing config
	signingConfig := fmt.Sprintf(`
    signingConfigs {
        create("release") {
            storeFile = file("%s")
            storePassword = "%s"
            keyAlias = "%s"
            keyPassword = "%s"
        }
    }
`, keystorePath, config.KeystorePassword, config.KeyAlias, config.KeyPassword)

	// Insert signing config after android {
	insertPos := androidIndex + len("android {")
	newContent := content[:insertPos] + "\n" + signingConfig + content[insertPos:]

	// Find buildTypes and add signingConfig to release
	buildTypesIndex := strings.Index(newContent, "buildTypes {")
	if buildTypesIndex != -1 {
		releaseIndex := strings.Index(newContent[buildTypesIndex:], "release {")
		if releaseIndex != -1 {
			releasePos := buildTypesIndex + releaseIndex + len("release {")
			signingLine := "\n            signingConfig = signingConfigs.getByName(\"release\")"
			newContent = newContent[:releasePos] + signingLine + newContent[releasePos:]
		}
	}

	// Write updated content
	return os.WriteFile(filePath, []byte(newContent), 0644)
}

func updateSigningConfig(filePath, content, keystorePath string, config models.BuildConfig) error {
	// For simplicity, replace the entire signingConfigs block
	// Find signingConfigs block
	startIndex := strings.Index(content, "signingConfigs {")
	if startIndex == -1 {
		return fmt.Errorf("signingConfigs block not found")
	}

	// Find the closing brace
	depth := 0
	endIndex := startIndex + len("signingConfigs {")
	for i := startIndex; i < len(content); i++ {
		if content[i] == '{' {
			depth++
		} else if content[i] == '}' {
			depth--
			if depth == 0 {
				endIndex = i + 1
				break
			}
		}
	}

	// Construct new signing config
	newSigningConfig := fmt.Sprintf(`signingConfigs {
        create("release") {
            storeFile = file("%s")
            storePassword = "%s"
            keyAlias = "%s"
            keyPassword = "%s"
        }
    }`, keystorePath, config.KeystorePassword, config.KeyAlias, config.KeyPassword)

	// Replace old config with new
	newContent := content[:startIndex] + newSigningConfig + content[endIndex:]

	// Write updated content
	return os.WriteFile(filePath, []byte(newContent), 0644)
}
