import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.ByteArrayOutputStream

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.composeMultiplatform)
    alias(libs.plugins.composeCompiler)
    //alias(libs.plugins.composeHotReload)
    alias(libs.plugins.kotlinSerialization)
}

val gitVersionCode = getGitCommitCount()
val gitVersionName = getGVN()
val desktopVersionName = getCleanDesktopVersion(gitVersionName)
kotlin {
    /*linuxX64 {
        binaries {
            executable {

            }
        }
    }*/
    androidTarget {
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_11)
        }
    }

    jvm("desktop")

    afterEvaluate {
        afterEvaluate {
            tasks.configureEach {
                if (
                    name.startsWith("compile")
                    && name.endsWith("KotlinMetadata")
                ) {
                    println("disabling $name")
                    enabled = false
                }
            }
        }
    }
    sourceSets {
        val desktopMain by getting

        androidMain.dependencies {
            implementation(compose.preview)
            implementation(libs.androidx.activity.compose)
            implementation(libs.koin.android) // Koin Android-specific extensions
            implementation(libs.koin.androidx.compose)
            implementation("com.google.zxing:core:3.5.4")
            implementation("com.github.billthefarmer:mididriver:1.25")
            implementation("com.tom-roush:pdfbox-android:2.0.27.0")
        }
        commonMain.dependencies {
//            implementation(compose.components.resources)
            implementation(compose.runtime)
            implementation(compose.foundation)
            implementation(compose.material3)
            implementation(compose.ui)
            implementation(compose.components.resources)
            implementation(compose.components.uiToolingPreview)
            implementation(libs.androidx.lifecycle.viewmodel)
            implementation(libs.androidx.lifecycle.runtimeCompose)
            implementation(libs.koin.core) // Koin core for shared logic
            implementation(libs.koin.compose) // Koin for Compose Multiplatform UI
            implementation(libs.koin.compose.viewmodel) // Koin for KMP ViewModels

            implementation(libs.kotlinx.serialization.json)
            implementation(libs.bundles.voyager)
            implementation(libs.cafe.voyager.koin)
            implementation(libs.multiplatform.settings)
            implementation(compose.materialIconsExtended)
            //implementation(kotlin("stdlib-jdk8"))
            //implementation("org.jetbrains.compose.foundation:foundation-desktop")
            implementation("com.russhwolf:multiplatform-settings-no-arg:1.3.0")
            implementation("io.github.pdvrieze.xmlutil:serialization:0.91.3") // Dépendance sous-jacente pour XML
            //implementation(libs.ktmidi)
        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
        desktopMain.dependencies {
            implementation(compose.desktop.currentOs)
            implementation(libs.kotlinx.coroutinesSwing)
            implementation("com.google.zxing:core:3.5.4")
            implementation("com.google.zxing:javase:3.5.4")
            implementation("org.apache.pdfbox:pdfbox:3.0.7")
        }
    }
    targets.all {
        compilations.all {
            compileTaskProvider.configure {
                compilerOptions {
                    freeCompilerArgs.add("-Xexpect-actual-classes")
                }
            }
        }
    }
}

compose.resources {
    publicResClass = true
}
android {
    namespace = "mg.dot.feufaro"
    compileSdk = libs.versions.android.compileSdk.get().toInt()

    defaultConfig {
        applicationId = "mg.dot.feufaro"
        minSdk = libs.versions.android.minSdk.get().toInt()
        targetSdk = libs.versions.android.targetSdk.get().toInt()
        versionCode = gitVersionCode
        versionName = gitVersionName
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

dependencies {
    debugImplementation(compose.uiTooling)
}

compose.desktop {
    application {
        mainClass = "mg.dot.feufaro.MainKt"

        nativeDistributions {
            targetFormats(TargetFormat.Exe, TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "Feufaro"
            packageVersion = desktopVersionName
            jvmArgs("-Dapp.version=$gitVersionName")
            modules("java.base", "java.desktop", "jdk.unsupported", "java.naming")

            windows {
                iconFile.set(project.file("icons/icon.ico"))
            }
            linux {
                iconFile.set(project.file("icons/icon-linux.png"))
            }
            buildTypes.release.proguard {
                isEnabled.set(false)
            }
        }
    }
}
val generateFilesIndex = tasks.register("generateFilesIndex") {
    val resourcesDir = file("src/commonMain/composeResources/files")
    val outputFile = file("src/commonMain/composeResources/files/feuList.json")

    inputs.dir(resourcesDir)
    outputs.file(outputFile)

    doLast {
        if (resourcesDir.exists()) {
            val files = resourcesDir.listFiles()
                ?.filter { it.extension == "txt" && it.name != "feuList.json" }
                ?.sortedBy { it.name } ?: emptyList()

            val jsonContent = buildString {
                append("{\n")
                append("  \"internalFeu\": [\n")

                files.forEachIndexed { index, file ->
                    var title = "Sans titre"
                    file.useLines { lines ->
                        for (l in lines) {
                            if (l.contains("|t:")) {
                                title = l.substringAfter("|t:").substringBefore("|").trim()
                                title = title.replace("\"", "\\\"")
                                break
                            }
                        }
                    }

                    append("    {\n")
                    append("      \"id\": ${index + 1},\n")
                    append("      \"fileName\": \"${file.name}\",\n")
                    append("      \"title\": \"$title\",\n")
                    append("      \"path\": \"assets://${file.name}\"\n")
                    append("    }${if (index < files.size - 1) "," else ""}\n")
                }

                append("  ]\n")
                append("}")
            }

            outputFile.writeText(jsonContent)
            println("Index JSON généré : ${files.size} fichiers.")
        }
    }
}
tasks.configureEach {
    if (name.startsWith("copyNonXmlValueResources") ||
        name.startsWith("generateComposeResClass")) {
        dependsOn(generateFilesIndex)
    }
}
tasks.register<Copy>("exportLibs") {
    group = "distribution"
    description = "Copie les bibliothèques partagées pour le Thin JAR"

    // On utilise named("...") pour éviter l'erreur de compilation du script
    // Dans un projet KMP, la configuration s'appelle généralement "desktopRuntimeClasspath" 
    // ou "jvmRuntimeClasspath" selon le nom de votre cible.
    
    val configName = if (configurations.findByName("desktopRuntimeClasspath") != null) {
        "desktopRuntimeClasspath"
    } else {
        "jvmRuntimeClasspath"
    }

    from(configurations.named(configName))
    into(layout.buildDirectory.dir("libs/shared"))
    
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

fun getGitCommitCount(): Int {
    return try {
        val execResult = providers.exec {
            commandLine("git", "rev-list", "--count", "HEAD")
        }
        val countStr = execResult.standardOutput.asText.get().trim()
        val count = countStr.toIntOrNull() ?: 1
        if (count > 0) count else 1
    } catch (e: Exception) {
        1
    }
}

fun getGVN(): String {
    val execResult = providers.exec {
        commandLine("git", "describe", "--tags", "--always", "--abbrev=0")
    }
    val rawVersion = execResult.standardOutput.asText.get().trim()

    return if (rawVersion.isNotEmpty()) {
        rawVersion
    } else {
        "v1.0.0"
    }
}

fun getCleanDesktopVersion(versionName: String): String {
    val regex = Regex("""^\d+(\.\d+)*""")
    return regex.find(versionName)?.value ?: "1.0.0"
}