require "json"

default_platform(:android)

platform :android do
  aab_file = "./apps/readest-app/src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab"

  desc "Upload AAB to Google Play Production"
  lane :upload_production do
    upload_to_play_store(
      aab: aab_file,
      track: "production",
      skip_upload_apk: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      skip_upload_changelogs: false
    )
  end
  
  desc "Upload AAB to Google Play Internal Testing"
  lane :upload_internal do
    upload_to_play_store(
      aab: aab_file,
      track: "internal",
      skip_upload_apk: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      skip_upload_changelogs: true
    )
  end
  
  desc "Upload AAB to Google Play Beta"
  lane :upload_beta do
    upload_to_play_store(
      aab: aab_file,
      track: "beta",
      skip_upload_apk: true,
      skip_upload_metadata: true,
      skip_upload_images: true,
      skip_upload_screenshots: true,
      skip_upload_changelogs: true
    )
  end
end

# fastlane executes lanes from the ./fastlane folder, so paths are anchored to the
# repo root (its parent) to stay independent of the caller's working directory.
def repo_path(relative)
  File.expand_path(relative, File.expand_path("..", __dir__))
end

def asc_api_key
  key_id = ENV["APPLE_API_KEY"]
  # APPLE_API_KEY_PATH is deliberately kept OUT of the App Store build env: with the
  # full key_id/issuer/path trio present, `tauri build` notarizes the App Store binary,
  # which fails (App Store apps use an Apple Distribution cert, not Developer ID).
  # Derive the .p8 path from the key id (same convention altool uses); honor an
  # explicit APPLE_API_KEY_PATH when set (e.g. the iOS build env).
  app_store_connect_api_key(
    key_id: key_id,
    issuer_id: ENV["APPLE_API_ISSUER"],
    key_filepath: ENV["APPLE_API_KEY_PATH"] || repo_path("apps/readest-app/private_keys/AuthKey_#{key_id}.p8"),
  )
end

# Release notes from the latest version in release-notes.json, excluding notes
# that mention Android, Windows, or Linux. Used for both the TestFlight changelog
# and the App Store "What's New" text.
def release_notes_text
  releases = JSON.parse(File.read(repo_path("apps/readest-app/release-notes.json")))["releases"]
  latest = releases.keys.max_by { |version| Gem::Version.new(version) }
  releases[latest]["notes"]
    .reject { |note| note =~ /\b(?:Android|Windows|Linux)\b/i }
    .map { |note| "– #{note}" }
    .join("\n")
end

# App Store "Promotional Text". All other metadata fields keep their
# existing App Store Connect values.
PROMOTIONAL_TEXT = "Experience the Ultimate Ebook Reader Across All Your Devices for Avid Readers"

# iOS and macOS are one App Store Connect app (com.bilingify.readest), built from
# separate binaries and submitted independently. Each lane acts only on a build
# already uploaded by altool (skip_binary_upload / distribute_only) — it never
# builds or uploads a binary. For its platform it submits the build for App Store
# review AND distributes it to TestFlight. The App Store submit runs first because
# it waits for build processing, which the TestFlight distribute then relies on.
#   pnpm run submit-appstore-ios     # iOS
#   pnpm run submit-appstore-macos   # macOS
def submit_apple_build(deliver_opts, testflight_opts)
  api_key = asc_api_key
  upload_to_app_store({
    api_key: api_key,
    app_identifier: "com.bilingify.readest",
    skip_binary_upload: true, # use the altool-uploaded build; read version from the binary
    submit_for_review: true,
    automatic_release: true,
    force: true,              # skip the HTML metadata preview prompt
    skip_screenshots: true,
    skip_metadata: false,     # upload What's New + Promotional Text; other fields stay as-is
    release_notes: { "en-US" => release_notes_text },
    promotional_text: { "en-US" => PROMOTIONAL_TEXT },
    precheck_include_in_app_purchases: false,
    submission_information: { add_id_info_uses_idfa: false },
  }.merge(deliver_opts))
  upload_to_testflight({
    api_key: api_key,
    app_identifier: "com.bilingify.readest",
    distribute_only: true,    # use the already-uploaded build; do not upload
    distribute_external: true,
    groups: ["Beta Testers"],
    changelog: release_notes_text,
  }.merge(testflight_opts))
end

desc "Submit the uploaded iOS build for App Store review and to TestFlight"
lane :release_ios do
  submit_apple_build(
    { platform: "ios", ipa: repo_path("apps/readest-app/src-tauri/gen/apple/build/arm64/Readest.ipa") },
    { app_platform: "ios" }
  )
end

desc "Submit the uploaded macOS build for App Store review and to TestFlight"
lane :release_macos do
  submit_apple_build(
    { platform: "osx", pkg: repo_path("target/universal-apple-darwin/release/bundle/macos/Readest.pkg") },
    { app_platform: "osx" }
  )
end
