import java.io.FileInputStream
import java.util.Properties

plugins {
  id("com.android.application")
  id("kotlin-android")
  // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
  id("dev.flutter.flutter-gradle-plugin")
}

val mpvVersion = "v1.0.7"
val mpvDir = layout.buildDirectory.dir("libmpv").get().asFile
val mpvAar = "libmpv-release.aar"

val downloadLibmpv by tasks.registering {
  val stamp = File(mpvDir, ".version")
  outputs.upToDateWhen { stamp.exists() && stamp.readText().trim() == mpvVersion }
  doLast {
    mpvDir.mkdirs()
    val url = "https://github.com/edde746/libmpv-android/releases/download/$mpvVersion/$mpvAar"
    exec { commandLine("curl", "-sfL", url, "-o", File(mpvDir, mpvAar).absolutePath) }
    stamp.writeText(mpvVersion)
  }
}

val assVersion = "fp-3"
val assDir = layout.buildDirectory.dir("libass").get().asFile
val assAars = listOf("lib_ass-release.aar", "lib_ass_kt-release.aar", "lib_ass_media-release.aar")

val downloadLibass by tasks.registering {
  val stamp = File(assDir, ".version")
  outputs.upToDateWhen { stamp.exists() && stamp.readText().trim() == assVersion }
  doLast {
    assDir.mkdirs()
    val baseUrl = "https://github.com/edde746/libass-android/releases/download/$assVersion"
    assAars.forEach { name ->
      val dest = File(assDir, name)
      exec { commandLine("curl", "-sfL", "$baseUrl/$name", "-o", dest.absolutePath) }
    }
    stamp.writeText(assVersion)
  }
}

val doviVersion = "2.3.1"
val doviDir = layout.buildDirectory.dir("libdovi").get().asFile
val doviAbis = mapOf(
  "arm64-v8a" to "aarch64-linux-android",
  "armeabi-v7a" to "armv7-linux-androideabi",
  "x86" to "i686-linux-android",
  "x86_64" to "x86_64-linux-android"
)

val downloadLibdovi by tasks.registering {
  val stamp = File(doviDir, ".version")
  outputs.upToDateWhen { stamp.exists() && stamp.readText().trim() == doviVersion }
  doLast {
    doviDir.mkdirs()
    val baseUrl = "https://github.com/edde746/libdovi-builds/releases/download/v$doviVersion"
    doviAbis.forEach { (abi, triple) ->
      val archive = File(doviDir, "$triple.tar.gz")
      exec { commandLine("curl", "-sfL", "$baseUrl/libdovi-$triple.tar.gz", "-o", archive.absolutePath) }
      val outDir = File(doviDir, "$abi/lib")
      outDir.mkdirs()
      exec { commandLine("tar", "-xzf", archive.absolutePath, "-C", outDir.absolutePath) }
      archive.delete()
    }
    stamp.writeText(doviVersion)
  }
}

android {
  namespace = "com.edde746.plezy"
  compileSdk = flutter.compileSdkVersion
  ndkVersion = flutter.ndkVersion

  compileOptions {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
  }

  kotlinOptions {
    jvmTarget = JavaVersion.VERSION_11.toString()
  }

  defaultConfig {
    applicationId = "com.edde746.plezy"
    // You can update the following values to match your application needs.
    // For more information, see: https://flutter.dev/to/review-gradle-config.
    minSdk = 25 // Fire OS 6.x (API 25); overrides libmpv-android's minSdk=26
    targetSdk = flutter.targetSdkVersion
    versionCode = flutter.versionCode
    versionName = flutter.versionName

    externalNativeBuild {
      cmake {
        arguments += listOf(
          "-DDOVI_ENABLE_LIBDOVI=ON",
          "-DDOVI_LIBDOVI_PREBUILT_ROOT=${doviDir.absolutePath}"
        )
      }
    }

    if (System.getenv("AMAZON") != null) {
      versionCode = (flutter.versionCode ?: 0) + 3000
      ndk {
        abiFilters += listOf("armeabi-v7a", "arm64-v8a")
      }
    }
  }

  externalNativeBuild {
    cmake {
      path = file("src/main/cpp/CMakeLists.txt")
    }
  }

  signingConfigs {
    create("release") {
      val keystorePropertiesFile = rootProject.file("key.properties")
      if (keystorePropertiesFile.exists()) {
        val keystoreProperties = Properties()
        keystoreProperties.load(FileInputStream(keystorePropertiesFile))

        keyAlias = keystoreProperties["keyAlias"] as String
        keyPassword = keystoreProperties["keyPassword"] as String
        storeFile = file(keystoreProperties["storeFile"] as String)
        storePassword = keystoreProperties["storePassword"] as String
      }
    }
  }

  buildTypes {
    release {
      // Only use release signing if key.properties exists (not in CI/CD)
      val keystorePropertiesFile = rootProject.file("key.properties")
      if (keystorePropertiesFile.exists()) {
        signingConfig = signingConfigs.getByName("release")
      }
      // If key.properties doesn't exist, it will use debug signing for CI builds
      ndk {
        debugSymbolLevel = "FULL"
      }
    }
  }

  packaging {
    jniLibs {
      // Resolve conflict between libass-android and libmpv native libraries
      pickFirsts.add("lib/*/libc++_shared.so")
    }
  }
}

flutter {
  source = "../.."
}

// Download libdovi before any CMake/native build task
tasks.matching { it.name.contains("CMake") || it.name.contains("externalNative") }.configureEach {
  dependsOn(downloadLibdovi)
}

// Download libmpv and libass AARs before compilation
tasks.matching { it.name.startsWith("pre") && it.name.endsWith("Build") }.configureEach {
  dependsOn(downloadLibmpv)
  dependsOn(downloadLibass)
}

dependencies {
  implementation(files(File(mpvDir, mpvAar)))
  implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")

  // Android TV Watch Next integration
  implementation("androidx.tvprovider:tvprovider:1.0.0")

  // Media3 ExoPlayer for Android
  implementation("androidx.media3:media3-exoplayer:1.9.2")
  implementation("androidx.media3:media3-exoplayer-hls:1.9.2")
  implementation("androidx.media3:media3-ui:1.9.2")
  implementation("androidx.media3:media3-common:1.9.2")

  // Cronet for HTTP/2 multiplexing + better connection management
  implementation("androidx.media3:media3-datasource-cronet:1.9.2")
  implementation("org.chromium.net:cronet-embedded:143.7445.0")

  // FFmpeg audio decoder for unsupported codecs (ALAC, DTS, TrueHD, etc.)
  implementation("org.jellyfin.media3:media3-ffmpeg-decoder:1.9.0+1")

  // libass-android for ASS/SSA subtitle rendering
  assAars.forEach { implementation(files(File(assDir, it))) }
}
