require 'json'
require 'shellwords'
require_relative '../helpers/github'

module Fastlane
  module Actions
    class SubtreePushAction < Action
      def self.run(params)
        subtree = params[:subtree]
        repo_name = params[:repo]
        branch = params[:branch]
        pr_number = params[:pr_number]
        label = params[:label]

        # Build full repo URL from repo name
        repo_url = Github.repo_url(repo: repo_name)

        status = other_action.subtree_status(
          subtree: subtree,
          repo: repo_name,
          branch: branch,
          pr_number: pr_number,
        )

        # Check if working directory is clean
        other_action.ensure_git_status_clean

        actions_performed = []

        if !status[:commits_to_push] || status[:commits_to_push].count == 0
          UI.success("No changes to push to '#{subtree}' repo.")
          if status[:pr_number]
            Actions.sh("gh --repo #{Github.org}/#{repo_name} pr close #{status[:pr_number]}", log: true)
            UI.success("⚠️ Successfully closed PR #{status[:pr_number]}")
            actions_performed << "⚠️ Closed PR #{status[:pr_number]}"
          end
        elsif !pr_number
          UI.user_error!("Unable to push #{subtree} changes. No PR number provided.")
        else
          UI.message("📤 Pushing #{status[:commits_to_push].count} commits to '#{subtree}' repo (head_ref: #{status[:pr_head_ref]})...")

          # Use git subtree split + force push to handle existing branches
          UI.message("🔀 Splitting subtree commits...")
          Actions.sh("git subtree split --prefix #{subtree} -b #{status[:pr_head_ref]}", log: true)
          UI.message("🚀 Force pushing to remote branch #{status[:pr_head_ref]}...")
          Actions.sh("git push --force #{repo_url} #{status[:pr_head_ref]}:#{status[:pr_head_ref]}", log: true)

          UI.success("✅ Successfully pushed changes to '#{subtree}' repo (head_ref: #{status[:pr_head_ref]})")

          # Create label if it doesn't exist
          if !Github.label_exists?(label: label, repo: repo_name)
            Actions.sh(
              "gh --repo #{Github.org}/#{repo_name} label create #{label} \
              --description 'Label for subtree PRs' --color '000000'",
              log: true
            )
            actions_performed << "✅ Created label '#{label}'"
          end

          # Check for existing open PRs with this specific branch name
          if status[:pr_number] && status[:pr_url]
            UI.message("🔄 Found existing subtree PR: #{status[:pr_url]}. Updating...")
            Actions.sh("gh --repo #{Github.org}/#{repo_name} pr edit #{status[:pr_number]} \
              --title #{Shellwords.escape(status[:pr_title])} \
              --body #{Shellwords.escape(status[:pr_body])} \
              --add-label #{label}",
              log: true
            )
            UI.success("✅ Successfully updated existing subtree PR: #{status[:pr_url]}")
            actions_performed << "✅ Updated existing subtree PR: #{status[:pr_url]}"
          else
            UI.message("🔀 No existing subtree PR found, creating new one...")
            Actions.sh(
              "gh --repo #{Github.org}/#{repo_name} pr create " \
              "--title #{Shellwords.escape(status[:pr_title])} " \
              "--body #{Shellwords.escape(status[:pr_body])} " \
              "--head #{status[:pr_head_ref]} " \
              "--base #{branch} " \
              "--label #{label}",
              log: true
            )

            subtree_pr = Github.lookup_pr_by_head_ref(head_ref: status[:pr_head_ref], repo: repo_name, state: "open", fields: "number,url")
            unless subtree_pr
              UI.user_error!("Failed to create PR for subtree: #{status[:pr_head_ref]}")
            end
            UI.success("✅ Successfully created subtree PR: #{subtree_pr["url"]}")
            actions_performed << "✅ Created subtree PR: #{subtree_pr["url"]}"
          end

          actions_performed
        end
      end

      def self.description
        "Push commits from local subtree to upstream repository"
      end

      def self.authors
        ["Suno"]
      end

      def self.details
        "Pushes local commits from subtree to upstream repository"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(
            key: :repo,
            description: "Repository name (e.g., 'app-android' - org 'suno-ai' will be added automatically)",
            type: String,
            verify_block: proc do |value|
              UI.user_error!(':repo option cannot be empty') if value.to_s.empty?
            end
          ),
          FastlaneCore::ConfigItem.new(
            key: :branch,
            description: "The remote branch to sync with",
            type: String,
            verify_block: proc do |value|
              UI.user_error!(':branch option cannot be empty') if value.to_s.empty?
            end
          ),
          FastlaneCore::ConfigItem.new(
            key: :subtree,
            description: "Subtree path (e.g., 'android', 'ios')",
            type: String,
            verify_block: proc do |value|
              UI.user_error!(':subtree option cannot be empty') if value.to_s.empty?
            end
          ),
          FastlaneCore::ConfigItem.new(
            key: :pr_number,
            description: "PR number from mobile repo to sync (defaults to GITHUB environment if available)",
            type: String,
            verify_block: proc do |value|
              UI.user_error!(':pr_number option cannot be empty') if value.to_s.empty?
            end
          ),
          FastlaneCore::ConfigItem.new(
            key: :label,
            description: "Label to use for subtree PRs",
            type: String,
            default_value: "mobile-repo-sync",
            verify_block: proc do |value|
              UI.user_error!(':label option cannot be empty') if value.to_s.empty?
            end
          ),
        ]
      end

      def self.is_supported?(platform)
        true
      end
    end
  end
end
