# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do
  # Constants
  TEAM_ID = "2F67MQ8R79"
  CODE_SIGN_IDENTITY = "Apple Distribution: Hau Tran (#{TEAM_ID})"
  BASE_BUNDLE_ID = "app.alextran.immich"
  
  # Helper method to get App Store Connect API key
  def get_api_key
    app_store_connect_api_key(
      key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],
      issuer_id: ENV["APP_STORE_CONNECT_API_KEY_ISSUER_ID"],
      key_filepath: "#{Dir.home}/.appstoreconnect/private_keys/AuthKey_#{ENV['APP_STORE_CONNECT_API_KEY_ID']}.p8",
      duration: 1200,
      in_house: false
    )
  end
  
  # Helper method to get version from pubspec.yaml
def get_version_from_pubspec
  require 'yaml'
  
  pubspec_path = File.join(Dir.pwd, "../..", "pubspec.yaml")
  pubspec = YAML.load_file(pubspec_path)
  
  version_string = pubspec['version']
  version_string ? version_string.split('+').first : nil
end
  
  # Helper method to configure code signing for all targets
  def configure_code_signing(bundle_id_suffix: "", profile_name_main:, profile_name_share:, profile_name_widget:)
    bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
    
    # Runner (main app)
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}",
      profile_name: profile_name_main,
      targets: ["Runner"]
    )
    
    # ShareExtension
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.ShareExtension",
      profile_name: profile_name_share,
      targets: ["ShareExtension"]
    )
    
    # WidgetExtension
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: "#{BASE_BUNDLE_ID}#{bundle_suffix}.Widget",
      profile_name: profile_name_widget,
      targets: ["WidgetExtension"]
    )
  end
  
  # Helper method to build and upload to TestFlight
  def build_and_upload(
    api_key:,
    bundle_id_suffix: "",
    configuration: "Release",
    distribute_external: true,
    version_number: nil,
    profile_name_main:,
    profile_name_share:,
    profile_name_widget:
  )
    bundle_suffix = bundle_id_suffix.empty? ? "" : ".#{bundle_id_suffix}"
    app_identifier = "#{BASE_BUNDLE_ID}#{bundle_suffix}"
    
    # Set version number if provided
    if version_number
      increment_version_number(version_number: version_number)
    end
    
    # Increment build number
    increment_build_number(
      build_number: latest_testflight_build_number(
        api_key: api_key,
        app_identifier: app_identifier
      ) + 1,
      xcodeproj: "./Runner.xcodeproj"
    )
    
    # Build the app
    build_app(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: configuration,
      export_method: "app-store",
      xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
      export_options: {
        provisioningProfiles: {
          "#{app_identifier}" => profile_name_main,
          "#{app_identifier}.ShareExtension" => profile_name_share,
          "#{app_identifier}.Widget" => profile_name_widget
        },
        signingStyle: "manual",
        signingCertificate: CODE_SIGN_IDENTITY
      }
    )
    
    # Upload to TestFlight
    upload_to_testflight(
      api_key: api_key,
      skip_waiting_for_build_processing: true,
      distribute_external: distribute_external
    )
  end
  
  desc "iOS Development Build to TestFlight (requires separate bundle ID)"
  lane :gha_testflight_dev do
    api_key = get_api_key
    
    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    # Capture profile names after each sigh call
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    # Configure code signing for dev bundle IDs using the downloaded profile names
    configure_code_signing(
      bundle_id_suffix: "development",
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )
    
    # Build and upload
    build_and_upload(
      api_key: api_key,
      bundle_id_suffix: "development",
      configuration: "Profile",
      distribute_external: false,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )
  end

  desc "iOS Release to TestFlight"
  lane :gha_release_prod do
    api_key = get_api_key
    
    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    sigh(api_key: api_key, app_identifier: BASE_BUNDLE_ID, force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    
    # Configure code signing for production bundle IDs
    configure_code_signing(
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )

    # Build and upload with version number
    build_and_upload(
      api_key: api_key,
      version_number: get_version_from_pubspec,
      distribute_external: false,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )
  end

  desc "iOS Manual Release"
  lane :release_manual do
    enable_automatic_code_signing(
      path: "./Runner.xcodeproj",
      targets: ["Runner", "ShareExtension", "WidgetExtension"]
    )

    increment_version_number(
      version_number: get_version_from_pubspec
    )
    increment_build_number(
      build_number: latest_testflight_build_number + 1,
    )
    
    # Build archive with automatic signing
    gym(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: "Release",
      export_method: "app-store",
      skip_package_ipa: false,
      xcargs: "-skipMacroValidation -allowProvisioningUpdates",
      export_options: {
        method: "app-store",
        signingStyle: "automatic",
        uploadBitcode: false,
        uploadSymbols: true,
        compileBitcode: false
      }
    )
    
    upload_to_testflight(
      skip_waiting_for_build_processing: true
    )
  end

  desc "iOS Build Only (no TestFlight upload)"
  lane :gha_build_only do
    # Use the same build process as production, just skip the upload
    # This ensures PR builds validate the same way as production builds
    
    api_key = get_api_key
    
    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development", force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.development.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    # Configure code signing for dev bundle IDs
    configure_code_signing(
      bundle_id_suffix: "development",
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )
    
    # Build the app (same as gha_testflight_dev but without upload)
    build_app(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: "Release",
      export_method: "app-store",
      skip_package_ipa: true,
      xcargs: "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual",
      export_options: {
        provisioningProfiles: {
          "#{BASE_BUNDLE_ID}.development" => main_profile_name,
          "#{BASE_BUNDLE_ID}.development.ShareExtension" => share_profile_name,
          "#{BASE_BUNDLE_ID}.development.Widget" => widget_profile_name
        },
        signingStyle: "manual",
        signingCertificate: CODE_SIGN_IDENTITY
      }
    )
  end

end
