class Api::V1::Projects::SyncRepositoriesController < Api::V1::BaseController
  before_action :require_public_and_member_above, except: [:sync]
  before_action :load_project, only: [:sync]

  def index 
    @sync_repositories = @project.sync_repositories
    @group_sync_repository = @project.sync_repositories.group(:type, :external_repo_address, :sync_granularity, :external_token).count
  end

  def create 
    @sync_repository1, @sync_repository2, @sync_repository_branch1, @sync_repository_branch2 = Api::V1::Projects::SyncRepositories::CreateService.call(@project, sync_repository_params)
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def update_info
    return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present? 
    Api::V1::Projects::SyncRepositories::UpdateService.call(@project, params[:sync_repository_ids], sync_repository_update_params)
    render_ok
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def sync
    return render_error("请输入正确的同步方向！") if params[:sync_direction].blank?
    if params[:repo_type].present? 
      @sync_repositories = SyncRepository.where(project: @project, type: params[:repo_type], sync_direction: params[:sync_direction])
    else
      @sync_repositories = SyncRepository.where(project: @project, sync_direction: params[:sync_direction])
    end
    branch = params[:payload].present? ? JSON.parse(params[:payload])["ref"].split("/")[-1]  : params[:ref].split("/")[-1] rescue nil
    if params[:sync_direction].to_i == 1
      @sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: @sync_repositories, gitlink_branch_name: branch, enable: true)
    else 
      @sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: @sync_repositories, external_branch_name: branch, enable: true)
    end
    # 全部分支同步暂时不做
    # @sync_repositories.each do |item|
    #   TouchSyncJob.perform_later(item)
    # end
    @sync_repository_branches.each do |item|
      TouchSyncJob.set(wait: 5.seconds).perform_later(item)
    end
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def unbind 
    return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present? 
    @sync_repositories = SyncRepository.where(id: params[:sync_repository_ids].split(","))
    @sync_repositories.each do |repo|
      # Reposync::DeleteRepoService.call(repo.repo_name) # 解绑操作放在回调里
      Api::V1::Projects::Webhooks::DeleteService.call(@project, repo.webhook_gid)
      repo.destroy
    end
    render_ok
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def change_enable
    return render_error("请输入正确的仓库类型") if params[:repo_type].blank?
    return render_error("请输入正确的分支名称") if params[:gitlink_branch_name].blank? || params[:external_branch_name].blank? 
    # return render_error("请输入正确的状态") if params[:enable].blank?
    @sync_repository_branches = SyncRepositoryBranch.joins(:sync_repository).where(sync_repositories: {project_id: @project.id, type: params[:repo_type]}, gitlink_branch_name: params[:gitlink_branch_name], external_branch_name: params[:external_branch_name])
    if @sync_repository_branches.update_all({enable: params[:enable]})
      @sync_repository_branches.each do |branch|
        branch_sync_direction = branch&.sync_repository&.sync_direction.to_i
        if branch_sync_direction == 1
          Reposync::UpdateBranchStatusService.call(branch&.sync_repository&.repo_name, branch.gitlink_branch_name, params[:enable])
        else
          Reposync::UpdateBranchStatusService.call(branch&.sync_repository&.repo_name, branch.external_branch_name, params[:enable])
        end
        TouchSyncJob.perform_later(branch) if params[:enable] && branch_sync_direction == params[:first_sync_direction].to_i
      end
      render_ok
    else
      render_error("更新失败！")
    end
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def create_branch 
    return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present? 
    return render_error("请输入正确的Gitlink分支名称") unless params[:gitlink_branch_name].present?
    return render_error("请输入正确的外部仓库分支名称") unless params[:external_branch_name].present? 
    return render_error("请输入正确的首次同步方向") unless params[:first_sync_direction].present?
    
    params[:sync_repository_ids].split(",").each do |id|
      repo = SyncRepository.find_by_id id
      branch = Reposync::CreateSyncBranchService.call(repo.repo_name, params[:gitlink_branch_name], params[:external_branch_name])
      return render_error(branch[2]) if branch[0].to_i !=0
      sync_branch = SyncRepositoryBranch.create!(sync_repository_id: id, gitlink_branch_name: params[:gitlink_branch_name], external_branch_name: params[:external_branch_name], reposync_branch_id: branch[1]['id'])
      TouchSyncJob.perform_later(sync_branch) if params[:first_sync_direction].to_i == repo.sync_direction
    end
    render_ok
  rescue Exception => e
    uid_logger_error(e.message)
    tip_exception(e.message)
  end

  def branches 
    return render_error("请输入正确的同步仓库ID") unless params[:sync_repository_ids].present? 
    @sync_repository_branches = SyncRepositoryBranch.where(sync_repository_id: params[:sync_repository_ids].split(","))
    @sync_repository_branches = @sync_repository_branches.ransack(gitlink_branch_name_or_external_branch_name_cont: params[:branch_name]).result if params[:branch_name].present?
    @group_sync_repository_branch = @sync_repository_branches.joins(:sync_repository).group("sync_repositories.type, sync_repository_branches.gitlink_branch_name, sync_repository_branches.external_branch_name").select("sync_repositories.type as type,max(sync_repository_branches.updated_at) as updated_at, sync_repository_branches.gitlink_branch_name, sync_repository_branches.external_branch_name").sort_by{|i|i.updated_at}
    @each_json = []
    @group_sync_repository_branch.each do |item|
      branches = @sync_repository_branches.joins(:sync_repository).where(sync_repositories: {type: item.type}, gitlink_branch_name: item.gitlink_branch_name, external_branch_name: item.external_branch_name).order(sync_time: :desc)
      branch = branches.first
      @each_json << {
        gitlink_branch_name: item.gitlink_branch_name,
        external_branch_name: item.external_branch_name,
        type: branch&.sync_repository&.type,
        sync_time: branch.sync_time.present? ? branch.sync_time.strftime("%Y-%m-%d %H:%M:%S") : nil,
        sync_status: branch.sync_status,
        enable: branch.enable,
        enable_num: branch.enable ? 1 : 0,
        created_at: branch.created_at.to_i,
        reposync_branch_ids: branches.pluck(:reposync_branch_id)
      }
    end
    @each_json = @each_json.sort_by{|h| [-h[:enable_num], h[:created_at]]}
    render :json => {total_count: @group_sync_repository_branch.count, sync_repository_branches: @each_json}
  end

  def history
    return render_error("请输入正确的同步分支ID") unless params[:reposync_branch_ids]
    @branch = SyncRepositoryBranch.find_by(reposync_branch_id: params[:reposync_branch_ids].split(",")[0])
    _, @reposync_branch_logs, @total_count, _ = Reposync::GetLogsService.call(nil, params[:reposync_branch_ids], page, limit)
  end

  private
  def sync_repository_params
    params.permit(:type, :external_token, :external_repo_address, :sync_granularity, :external_branch_name, :gitlink_branch_name, :first_sync_direction)
  end

  def sync_repository_update_params
    params.permit(:external_token, :external_repo_address)
  end

end