require 'octokit'

module CodeHealer
  class PullRequestCreator
    class << self
      def create_pull_request(branch_name, class_name, method_name, error, fix_description, file_path)
        puts "🔍 PR Creation Debug:"
        puts "  - Auto create PR: #{ConfigManager.auto_create_pr?}"
        puts "  - PR enabled: #{ConfigManager.pull_request_settings['enabled']}"
        
        return false unless ConfigManager.auto_create_pr?
        return false unless ConfigManager.pull_request_settings['enabled']

        begin
          client = create_github_client
          if client.nil?
            puts "❌ Failed to create GitHub client - GitHub token not configured"
            puts "💡 To enable PR creation, set GITHUB_TOKEN in your .env file"
            puts "   Run: ./setup_github_token.sh"
            return false
          end

          title = generate_title(class_name, method_name, error)
          body = generate_body(class_name, method_name, error, fix_description, file_path)
          labels = ConfigManager.pull_request_settings['labels'] || []

          puts "Creating pull request for branch: #{branch_name}"
          
          # Get target branch from configuration
          target_branch = ConfigManager.pr_target_branch
          puts "📋 Target branch for PR: #{target_branch}"
          
          pr = client.create_pull_request(
            repository_name,
            target_branch,
            branch_name,
            title,
            body,
            labels: labels
          )

          puts "✅ Pull request created successfully!"
          puts "🔗 PR URL: #{pr.html_url}"
          
          # Store PR info for tracking
          store_pr_info(pr.number, branch_name, class_name, method_name, error)
          
          return pr.html_url
        rescue => e
          puts "❌ Failed to create pull request: #{e.message}"
          Rails.logger.error "Pull request creation failed: #{e.message}"
          return false
        end
      end

      private

      def create_github_client
        # Try environment variable first
        token = ENV['GITHUB_TOKEN']
        
        # Fallback to Rails credentials
        if token.nil? && defined?(Rails.application.credentials)
          token = Rails.application.credentials.dig(:github, :token)
        end
        
        return nil unless token

        Octokit::Client.new(access_token: token)
      rescue => e
        puts "❌ Failed to create GitHub client: #{e.message}"
        nil
      end

      def repository_name
        # Extract from git remote
        remote_url = `git config --get remote.origin.url`.strip
        if remote_url =~ /github\.com[:\/]([^\/]+\/[^\/]+?)(?:\.git)?$/
          $1
        else
          'deepan-g2/patchbot' # fallback
        end
      end

      def generate_title(class_name, method_name, error)
        template = ConfigManager.pull_request_settings['title_template'] || 
                   'Fix \{class_name\}##\{method_name\}: Handle \{error_type\}'
        
        template.gsub('\{class_name\}', class_name.to_s)
                .gsub('\{method_name\}', method_name.to_s)
                .gsub('\{error_type\}', error.class.name.to_s)
      end

      def generate_body(class_name, method_name, error, fix_description, file_path)
        template = ConfigManager.pull_request_settings['body_template'] || default_body_template
        
        template.gsub('{class_name}', class_name.to_s)
                .gsub('{method_name}', method_name.to_s)
                .gsub('{error_type}', error.class.name.to_s)
                .gsub('{error_message}', error.message.to_s)
                .gsub('{file_path}', file_path.to_s)
                .gsub('{fix_description}', fix_description.to_s)
      end

      def default_body_template
        # Simple string with placeholders - no interpolation
        '## Auto-generated fix for {error_type}

        **Error:** {error_message}
        **Method:** {class_name}##{method_name}
        **File:** {file_path}

        ### Changes Made:
        {fix_description}

        ### Testing:
        - [x] Error case handled gracefully
        - [x] Normal functionality preserved
        - [x] Tests generated automatically

        Generated by Self-Evolving Ruby System 🤖'
      end

      def store_pr_info(pr_number, branch_name, class_name, method_name, error)
        # Store PR information for tracking
        pr_info = {
          pr_number: pr_number,
          branch_name: branch_name,
          class_name: class_name,
          method_name: method_name,
          error_type: error.class.name,
          created_at: Time.current,
          status: 'open'
        }

        # Could store in database or cache
        Rails.cache.write("pr_#{pr_number}", pr_info, expires_in: 30.days)
        
        puts "📊 PR ##{pr_number} stored for tracking"
      end
    end
  end
end 