class ApplicationService
  include Callable

  Error = Class.new(StandardError)

  def regix_emoji content
    " " if content.blank?
    regex = /[^a-zA-Z0-9\u4E00-\u9FFF]/
    content.gsub(regex, '')
  end

  protected 
  def try_lock(key)
    raise Error, "请稍后再试！" unless $redis_cache.set(key, 1, nx: true, ex: 60.seconds)
  end

  def unlock(key)
    $redis_cache.del(key)
  end

  private

  def strip(str)
    str.to_s.strip.presence
  end

  def str_to_boolean str
    ActiveModel::Type::Boolean.new.cast str
  end

  # params: params from index.js page
  def create_repo_on_blockchain(params, project)
    username = params['user_id'].to_s
    token_name = project.id.to_s
    total_supply = params['blockchain_token_all'].to_i
    token_balance = [[username, params['blockchain_init_token'].to_i]]

    params = {
      "request-type": "create repo",
      "username": username,
      "token_name": token_name,
      "total_supply": total_supply,
      "token_balance": token_balance
    }.to_json
    resp_body = Blockchain::InvokeBlockchainApi.call(params)
    if resp_body['status'] != 0
      raise "区块链接口请求失败."
    end
  end


  def transfer_balance_on_blockchain(payer, payee, token_name, amount)

    params = {
      "request-type": "transfer amount",
      "payer": payer,
      "payee": payee,
      "token_name": token_name,
      "amount": amount
    }.to_json
    resp_body = Blockchain::InvokeBlockchainApi.call(params)
    if resp_body['status'] == 5 or resp_body['status'] == 106 or resp_body['status'] == 105
      raise resp_body['message']
    elsif resp_body['status'] != 0
      raise "区块链接口请求失败."
    else
    end
  end


  def lock_balance_on_blockchain(username, tokenname, amount)

    params = {
      "request-type": "lock user balance",
      "username": username,
      "token_name": tokenname,
      "amount": amount
    }.to_json
    resp_body = Blockchain::InvokeBlockchainApi.call(params)
    if resp_body['status'] == 5 or resp_body['status'] == 106 or resp_body['status'] == 103
      raise resp_body['message']
    elsif resp_body['status'] != 0
      raise "区块链接口请求失败."
    else
    end
  end


  def unlock_balance_on_blockchain(username, tokenname, amount)

    params = {
      "request-type": "unlock user balance",
      "username": username,
      "token_name": tokenname,
      "amount": amount
    }.to_json
    resp_body = Blockchain::InvokeBlockchainApi.call(params)
    if resp_body['status'] == 5 or resp_body['status'] == 106 or resp_body['status'] == 104
      raise resp_body['message']
    elsif resp_body['status'] != 0
      raise "区块链接口请求失败."
    else
    end
  end

  def push_activity_2_blockchain(activity_type, model)
		if activity_type == "issue_create"

			project_id = model['project_id']
			project = Project.find(project_id)
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
				# 无需执行上链操作
				return true
			end

			id = model['id']

			owner_id = project['user_id']
			owner = User.find(owner_id)
			ownername = owner['login']
			identifier = project['identifier']

			author_id = project['user_id']
			author = User.find(author_id)
			username = author['login']

			action = 'opened'

			title = model['subject']
			content = model['description']
			created_at = model['created_on']
			updated_at = model['updated_on']

			# 调用区块链接口
			params = {
				"request-type": "upload issue info",
				"issue_id": "gitlink-" + id.to_s,
				"repo_id": "gitlink-" + project_id.to_s,
				"issue_number": 0, # 暂时不需要改字段
				"reponame": identifier,
				"ownername": ownername,
				"username": username,
				"action": action,
				"title": title,
				"content": content,
				"created_at": created_at,
				"updated_at": updated_at
			}.to_json
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
			if resp_body['status'] == 10
				raise Error, resp_body['message']
			elsif resp_body['status'] != 0
				raise Error, "区块链接口请求失败."
			end

		elsif activity_type == "issue_comment_create"
			issue_comment_id = model['id']
			issue_id = model['journalized_id']
			parent_id = model['parent_id'].nil? ? "" : model['parent_id']

			issue = Issue.find(issue_id)
			issue_classify = issue['issue_classify'] # issue或pull_request
			project_id = issue['project_id']
			project = Project.find(project_id)

			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
				# 无需执行上链操作
				return
			end

			identifier = project['identifier']
			owner_id = project['user_id']
			owner = User.find(owner_id)
			ownername = owner['login']

			author_id = model['user_id']
			author = User.find(author_id)
			username = author['login']

			action = 'created'

			content = model['notes']
			created_at = model['created_on']

			if issue_classify == "issue"
				params = {
					"request-type": "upload issue comment info",
					"issue_comment_id": "gitlink-" + issue_comment_id.to_s,
					"issue_comment_number": 0, # 暂时不需要
					"issue_number": 0, # 暂时不需要
					"issue_id": "gitlink-" + issue_id.to_s,
					"repo_id": "gitlink-" + project.id.to_s,
					"parent_id": parent_id.to_s,
					"reponame": identifier,
					"ownername": ownername,
					"username": username,
					"action": action,
					"content": content,
					"created_at": created_at,
				}.to_json
			elsif issue_classify == "pull_request"
				params = {
					"request-type": "upload pull request comment info",
					"pull_request_comment_id": "gitlink-" + issue_comment_id.to_s,
					"pull_request_comment_number": 0, # 不考虑该字段
					"pull_request_number": 0, # 不考虑该字段
					"pull_request_id": "gitlink-" + issue_id.to_s,
					"parent_id": parent_id.to_s,
					"repo_id": "gitlink-" + project.id.to_s,
					"reponame": identifier,
					"ownername": ownername,
					"username": username,
					"action": action,
					"content": content,
					"created_at": created_at,
				}.to_json
			end

			# 调用区块链接口
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
			if resp_body['status'] == 10
				raise Error, resp_body['message']
			elsif resp_body['status'] != 0
				raise Error, "区块链接口请求失败."
			end
		elsif activity_type == "pull_request_create"
			# 调用区块链接口
			project_id = model['project_id']
			project = Project.find(project_id)
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
				# 无需执行上链操作
				return
			end

			pull_request_id = model['id']
			identifier = project['identifier']
			owner_id = project['user_id']
			owner = User.find(owner_id)
			ownername = owner['login']

			action = 'opened'

			title = model['title']
			content = model['body']

			source_branch = model['head']
			source_repo_id = model['fork_project_id'].nil? ? project_id : model['fork_project_id']

			target_branch = model['base']
			target_repo_id = project_id

			author_id = model['user_id']
			author = User.find(author_id)
			username = author['login']

			created_at = model['created_at']
			updated_at = model['updated_at']

			# 查询pull request对应的commit信息
			commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'])
			if commits.nil?
				raise Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
			end
			commit_shas = []
			commits.each do |c|
				commit_shas << c["Sha"]
			end
			params = {
				"request-type": "upload pull request info",
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
				"pull_request_number": 0, # trustie没有该字段
				"repo_id": "gitlink-" + project_id.to_s,
				"ownername": ownername,
				"reponame": identifier,
				"username": username,
				"action": action,
				"title": title,
				"content": content,
				"source_branch": source_branch,
				"target_branch": target_branch,
				"reviewers": [], # trustie没有该字段
				"commit_shas": commit_shas,
				"merge_user": "", # trustie没有该字段
				"created_at": created_at,
				"updated_at": updated_at
			}.to_json
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
			if resp_body['status'] == 9
				raise Error, resp_body['message']
			elsif resp_body['status'] != 0
				raise Error, "区块链接口请求失败."
			end
		elsif activity_type == "pull_request_merge"
			# 调用区块链接口
			project_id = model['project_id']
			project = Project.find(project_id)
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
				# 无需执行上链操作
				return
			end

			pull_request_id = model['id']
			identifier = project['identifier']
			owner_id = project['user_id']
			owner = User.find(owner_id)
			ownername = owner['login']

			action = 'merged'

			created_at = model['created_at']
			updated_at = model['updated_at']

			# 查询pull request对应的commit信息
			commits = Gitea::PullRequest::CommitsService.call(ownername, identifier, model['gitea_number'])
			if commits.nil?
				raise Error, "区块链接口请求失败" # 获取pr中变更的commit信息失败
			end
			commit_shas = []
			commits.each do |c|
				commit_shas << c["Sha"]
			end

			# 将pull request相关信息写入链上
			params = {
				"request-type": "upload pull request info",
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
				"pull_request_number": 0, # trustie没有该字段
				"repo_id": "gitlink-" + project_id.to_s,
				"ownername": ownername,
				"reponame": identifier,
				"username": username,
				"action": action,
				"title": title,
				"content": content,
				"source_branch": source_branch,
				"target_branch": target_branch,
				"reviewers": [], # trustie没有该字段
				"commit_shas": commit_shas,
				"merge_user": "", # trustie没有该字段
				"created_at": created_at,
				"updated_at": updated_at
			}.to_json
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
			if resp_body['status'] == 9
				raise Error, resp_body['message']
			elsif resp_body['status'] != 0
				raise Error, "区块链接口请求失败."
			end


			# 将commit相关信息写入链上
			commit_shas.each do |commit_sha|
				commit_diff = Gitea::Commit::DiffService.call(ownername, identifier, commit_sha, owner['gitea_token'])
				commit = Gitea::Commit::InfoService.call(ownername, identifier, commit_sha, owner['gitea_token'])
				params = {
					"request-type": "upload commit info",
					"commit_hash": commit_sha,
					"repo_id": "gitlink-" + project_id.to_s,
					"author": commit['commit']['author']['name'],
					"author_email": commit['commit']['author']['email'],
					"committer": commit['commit']['committer']['name'],
					"committer_email": commit['commit']['committer']['email'],
					"author_time": commit['commit']['author']['date'],
					"committer_time": commit['commit']['committer']['date'],
					"content": commit['commit']['message'],
					"commit_diff": commit_diff['Files'].to_s
				}.to_json
				resp_body = Blockchain::InvokeBlockchainApi.call(params)
				if resp_body['status'] == 7
					raise Error, resp_body['message']
				elsif resp_body['status'] != 0
					raise Error, "区块链接口请求失败."
				end
			end

		elsif activity_type == "pull_request_refuse"

			# 调用区块链接口
			project_id = model['project_id']
			project = Project.find(project_id)
			if project['use_blockchain'] == 0 || project['use_blockchain'] == false
				# 无需执行上链操作
				return true
			end

			pull_request_id = model['id']
			identifier = project['identifier']
			owner_id = project['user_id']
			owner = User.find(owner_id)
			ownername = owner['login']

			action = 'refused'

			# 将pull request相关信息写入链上
			params = {
				"request-type": "upload pull request info",
				"pull_request_id": "gitlink-" + pull_request_id.to_s,
				"pull_request_number": 0, # trustie没有该字段
				"repo_id": "gitlink-" + project_id.to_s,
				"ownername": ownername,
				"reponame": identifier,
				"username": username,
				"action": action,
				"title": title,
				"content": content,
				"source_branch": source_branch,
				"target_branch": target_branch,
				"reviewers": [], # trustie没有该字段
				"commit_shas": commit_shas,
				"merge_user": "", # trustie没有该字段
				"created_at": created_at,
				"updated_at": updated_at
			}.to_json
			resp_body = Blockchain::InvokeBlockchainApi.call(params)
			if resp_body['status'] == 9
				raise Error, resp_body['message']
			elsif resp_body['status'] != 0
				raise Error, "区块链接口请求失败."
			end
		end
	end
  
  def phone_mail_type value
    value =~ /^1\d{10}$/ ? 1 : 0
  end

end
