require_relative "../helpers/config"
require "spaceship"

module Fastlane
  module Actions
    class BuildVersionAction < Action
      def self.run(params)
        sha = params[:sha]
        pr_number = params[:pr_number]
        branch = params[:branch]
        build_flavor = params[:build_flavor]
        version_name = params[:version_name]
        version_code = params[:version_code]

        release_version = branch.match(/^release\/v?(?<version>\d+\.\d+\.\d+)$/)&.[](:version)
        if release_version
          UI.message("Detected release version: #{release_version}")
        else
          UI.message("No release version detected from branch. Using latest version from TestFlight or Firebase.")
        end

        if !pr_number && branch
          # check if there are any PRs with the same branch
          matching_prs = Github.list_prs(state: "open", head_ref: branch)
          if matching_prs.count > 1
            UI.important("Multiple PRs were matched for branch #{branch}: #{matching_prs.map { |pr| pr[:number] }.join(", ")}. Using the first one...")
          end
          if matching_prs.any?
            pr_number = matching_prs.first[:number]
          end
        end

        if version_code.nil?
          distribution_channel = if build_flavor == BuildFlavor::PROD && pr_number.nil?
            DistributionChannel::TESTFLIGHT
          else
            DistributionChannel::FIREBASE
          end
          version_code = other_action.max_version_code(
            build_flavor: build_flavor,
            distribution_channel: distribution_channel,
          ) + 1
        end

        if !version_name.nil?
          # Check if it's a simple release version (x.y.z)
          match = version_name.match(/^(?<version>\d+\.\d+\.\d+)(?:[\+-](?<sha>[a-zA-Z0-9]+))?(?:[\+-\.](?:pr(?<pr>\d+))|[\+-\.](?<branch>[a-zA-Z0-9\-_]+))?$/)
          unless match
            UI.user_error!("Unable to parse version name: #{version_name}")
          end
          {
            version: match[:version],
            version_name: version_name,
            version_code: version_code,
            sha: match[:sha],
            branch: match[:branch],
            pr: match[:pr]
          }
        elsif release_version
          UI.message("Detected release branch: #{branch}")
          {
            version: release_version,
            version_code: version_code,
            version_name: release_version,
            sha: sha,
            branch: branch,
            pr: nil
          }
        else
          build_config = BuildConfig.for(build_flavor)
          version = other_action.get_version_number(
            xcodeproj: build_config[:project],
            target: build_config[:target]
          )

          version_name = if pr_number
            UI.message("Detected PR number: #{pr_number}")
            "#{version}+#{sha}.pr#{pr_number}"
          elsif !branch.empty? && branch != Git.default_branch
            UI.message("Detected custom branch: #{branch}")
            "#{version}+#{sha}.#{branch.downcase.gsub(/[^a-zA-Z0-9\-_]/, "")}"
          else
            UI.message("Detected default branch: #{branch}")
            "#{version}+#{sha}"
          end

          {
            version: version,
            version_name: version_name,
            version_code: version_code,
            sha: sha,
            branch: branch,
            pr: pr_number
          }
        end
      end

      def self.description
        "Returns build version metadata"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(key: :build_flavor,
            description: "Build flavor to use (#{BuildFlavor::ALL.join(", ")})",
            type: String,
            default_value: BuildFlavor::PROD,
            verify_block: proc do |value|
              UI.user_error!("Invalid flavor (must be #{BuildFlavor::ALL.join(", ")})") unless BuildFlavor::ALL.include?(value)
            end),
          FastlaneCore::ConfigItem.new(key: :version_name,
            description: "Version name to use",
            type: String,
            optional: true,
            verify_block: proc do |value|
              UI.user_error!("Invalid version name (must be a valid version name)") if value.empty?
            end),
          FastlaneCore::ConfigItem.new(key: :version_code,
            description: "Version code to use",
            type: Integer,
            optional: true,
            verify_block: proc do |value|
              UI.user_error!("Invalid version code (must be a valid version code)") unless value > 0
            end),
          FastlaneCore::ConfigItem.new(key: :sha,
            description: "SHA to use",
            type: String,
            optional: true,
            default_value: Git.current_sha(short: true)),
          FastlaneCore::ConfigItem.new(key: :pr_number,
            description: "Pull request number that triggered the distribution",
            optional: true,
            type: Integer,
            default_value: Github.pr_number,
            verify_block: proc do |value|
              UI.user_error!("Pull request number must be a positive integer") unless value.nil? || value > 0
            end),
          FastlaneCore::ConfigItem.new(key: :branch,
            description: "Branch to use",
            type: String,
            optional: true,
            default_value: Github.branch || Git.current_branch)

        ]
      end

      def self.authors
        ["Suno"]
      end

      def self.is_supported?(platform)
        platform == :ios
      end
    end
  end
end
