# frozen_string_literal: true

require 'release_tools/issuable'
require 'release_tools/issue'
require_relative 'blockers_calculator'

module ReleaseTools
  module Deployments
    class BlockersReport < ReleaseTools::Issue
      include ::SemanticLogger::Loggable

      PROJECT = ReleaseTools::Project::Release::Tasks

      def initialize
        @blockers = ReleaseTools::Deployments::BlockerIssueFetcher.new
      end

      def create
        return create_new_issue unless existing_issue

        update_issue_description
        notify_issue

        existing_issue
      end

      def title
        "Deployment Blockers - Week: #{start_time}-#{end_time}"
      end

      def description
        @blockers.fetch

        calculator = BlockersCalculator.new(deployment_blockers)

        variables = binding
        variables.local_variable_set(:start_time, start_time)
        variables.local_variable_set(:end_time, end_time)
        variables.local_variable_set(:staging_blocked_time, staging_deployment_blocked_time)
        variables.local_variable_set(:production_blocked_time, production_deployment_blocked_time)
        variables.local_variable_set(:deployment_blockers, deployment_blockers)
        variables.local_variable_set(:uncategorized_incidents, uncategorized_incidents)
        variables.local_variable_set(:blocker_types, calculator.blocker_types)
        variables.local_variable_set(:total_blocker_type_gstg, calculator.total_blocker_type_gstg)
        variables.local_variable_set(:total_blocker_type_gprd, calculator.total_blocker_type_gprd)
        variables.local_variable_set(:job_for_blockers_report, job_for_blockers_report)

        ERB
          .new(template, trim_mode: '-')
          .result(variables)
      end

      def assignees
        ReleaseManagers::Schedule.new.active_release_managers.collect(&:id)
      rescue ReleaseManagers::Schedule::VersionNotFoundError
        nil
      end

      def labels
        ''
      end

      private

      def start_time
        @blockers.start_time.strftime('%Y-%m-%d')
      end

      def end_time
        @blockers.end_time.strftime('%Y-%m-%d')
      end

      def production_deployment_blocked_time
        deployment_blockers.sum(&:hours_gprd_blocked)
      end

      def staging_deployment_blocked_time
        deployment_blockers.sum(&:hours_gstg_blocked)
      end

      def deployment_blockers
        @blockers.deployment_blockers
      end

      def uncategorized_incidents
        @blockers.uncategorized_incidents
      end

      def job_for_blockers_report
        ENV.fetch('CI_JOB_URL', nil)
      end

      def template
        template_path = File
          .expand_path('../../../templates/deployment_blockers_report.md.erb', __dir__)

        File.read(template_path)
      end

      def client
        ReleaseTools::GitlabClient
      end

      def existing_issue
        @existing_issue ||=
          Retriable.with_context(:api) do
            client.issues(PROJECT, options).first
          end
      end

      def options
        {
          state: 'opened',
          author_id: ReleaseTools::Bot::GITLAB_COM_ID,
          search: title
        }
      end

      def create_new_issue
        logger.info('Creating new blockers report')

        Retriable.with_context(:api) { client.create_issue(self, PROJECT) }
      end

      def update_issue_description
        logger.info('Updating Deployment Blockers report issue', web_url: existing_issue.web_url)

        Retriable.with_context(:api) do
          client.edit_issue(
            PROJECT.path,
            existing_issue.iid,
            { description: description }
          )
        end
      end

      def notify_issue
        logger.info('Adding comment to Deployment Blockers report issue', web_url: existing_issue.web_url)

        Retriable.with_context(:api) do
          client.create_issue_note(
            PROJECT,
            issue: existing_issue,
            body: "The report has been regenerated with the updated blocker types and hours blocked"
          )
        end
      end
    end
  end
end
