class Api::V1::Projects::SyncRepositories::CreateService < ApplicationService

  include ActiveModel::Model

  attr_reader :project, :type, :external_token, :external_repo_address, :sync_granularity, :external_branch_name, :gitlink_branch_name, :first_sync_direction
  attr_accessor :sync_repository1, :sync_repository2, :sync_repository_branch1, :sync_repository_branch2, :gitea_webhook

  validates :type, inclusion: {in: %w(SyncRepositories::Gitee SyncRepositories::Github)}
  validates :external_repo_address, format: { with: CustomRegexp::URL_REGEX, multiline: true, message: "地址格式不正确" }
  validates :sync_granularity, :first_sync_direction, inclusion: {in: [1,2]}
  # validate :check_gitlink_branch_name

  def initialize(project, params)
    @project = project 
    @type = params[:type]
    @external_token = params[:external_token]
    @external_repo_address = params[:external_repo_address]
    @sync_granularity = params[:sync_granularity].to_i
    @external_branch_name = params[:external_branch_name]
    @gitlink_branch_name = params[:gitlink_branch_name]
    @first_sync_direction = params[:first_sync_direction].to_i
  end

  def call 
    raise Error, errors.full_messages.join(",") unless valid?

    create_webhook
    if sync_granularity == 2
      # 创建两个不同方向的同步仓库
      create_sync_repository
      # 创建两个不同方向的同步分支
      create_sync_repository_branch
      # 第一次同步
      touch_first_sync_branch
    else 
      create_sync_repository
      touch_first_sync
    end

    [@sync_repository1, @sync_repository2, @sync_repository_branch1, @sync_repository_branch2]
  end

  # def check_gitlink_branch_name
  #   if sync_granularity == 2
  #     result = $gitea_hat_client.get_repos_branch_name_set_by_owner_repo(project&.owner&.login, project&.identifier) rescue nil
  #     raise Error, '分支不存在' if !result.include?(gitlink_branch_name)
  #   end
  # end

  private 
  def create_sync_repository
    repository1 = Reposync::CreateSyncRepoService.call(repo_name(1), gitlink_repo_address, gitlink_token, external_repo_address, external_token, sync_granularity, 1)
    repository2 = Reposync::CreateSyncRepoService.call(repo_name(2), gitlink_repo_address, gitlink_token, external_repo_address, external_token, sync_granularity, 2)
    raise Error, '创建同步仓库失败' if repository1[0].to_i > 0 || repository2[0].to_i > 0
    @sync_repository1 = SyncRepository.create!(project: project, type: type, repo_name: repo_name(1), external_repo_address: external_repo_address, external_token: external_token, sync_granularity: sync_granularity, sync_direction: 1, webhook_gid: @gitea_webhook["id"])
    @sync_repository2 = SyncRepository.create!(project: project, type: type, repo_name: repo_name(2), external_repo_address: external_repo_address, external_token: external_token, sync_granularity: sync_granularity, sync_direction: 2, webhook_gid: @gitea_webhook["id"])
  end

  def create_sync_repository_branch 
    branch1 = Reposync::CreateSyncBranchService.call(repo_name(1),gitlink_branch_name, external_branch_name)
    branch2 = Reposync::CreateSyncBranchService.call(repo_name(2),gitlink_branch_name, external_branch_name)
    raise Error, '创建同步仓库分支失败' if branch1[0].to_i > 0 || branch2[0].to_i > 0
    @sync_repository_branch1 = SyncRepositoryBranch.create!(sync_repository: @sync_repository1, gitlink_branch_name: gitlink_branch_name, external_branch_name: external_branch_name, reposync_branch_id: branch1[1]["id"])
    @sync_repository_branch2 = SyncRepositoryBranch.create!(sync_repository: @sync_repository2, gitlink_branch_name: gitlink_branch_name, external_branch_name: external_branch_name, reposync_branch_id: branch2[1]["id"])
  end

  def touch_first_sync
    first_sync_direction == 1 ? TouchSyncJob.perform_later(@sync_repository1) : TouchSyncJob.perform_later(@sync_repository2)
  end

  def touch_first_sync_branch
    first_sync_direction == 1 ? TouchSyncJob.perform_later(@sync_repository_branch1) : TouchSyncJob.perform_later(@sync_repository_branch2)
  end

  def create_webhook
    url = ""
    if type == "SyncRepositories::Gitee"
      url = "#{Rails.application.config_for(:configuration)['platform_url']}/api/v1/#{project&.owner&.login}/#{project&.identifier}/sync_repositories/sync?sync_direction=1&repo_type=SyncRepositories::Gitee"
    else 
      url = "#{Rails.application.config_for(:configuration)['platform_url']}/api/v1/#{project&.owner&.login}/#{project&.identifier}/sync_repositories/sync?sync_direction=1&repo_type=SyncRepositories::Github"
    end
    webhook_params = {
      active: true,
      branch_filter: '*',
      http_method: 'POST',
      url: url,
      content_type: 'json',
      type: 'reposync',
      events: ["push"]
    }
    @gitea_webhook = Api::V1::Projects::Webhooks::CreateService.call(project, webhook_params)
  end

  def repo_name(sync_direction)
    if type == "SyncRepositories::Gitee"
      return "gitee:#{project.id}:#{sync_granularity}:#{sync_direction}"
    else
      return "github:#{project.id}:#{sync_granularity}:#{sync_direction}"
    end
  end

  def gitlink_repo_address
    "#{EduSetting.get("gitlink_repo_domain")}/#{project.owner&.login}/#{project.identifier}.git"
  end

  def gitlink_token
    EduSetting.get("gitlink_admin_token")
  end
end