class Api::V1::Projects::PortraitController < Api::V1::BaseController
  before_action :require_public_and_member_above

  def index 
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")

    # 社区影响力
    praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count 
    praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count 
    watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count 
    fork_count = ForkUser.where(project_id: @project.id).count 
    community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i)
    community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i)
    community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i)
    community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork)

    # 项目成熟度
    pullrequest_count = PullRequest.where(project_id: @project.id).count
    complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
    project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24)
    max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24)
    project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i)
    project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i)
    project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day))
    project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day)

    # 项目健康度
    member_count = Member.where(project_id: @project.id).count
    max_member_count = @platform_statistic['max-member-count'].to_i

    project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first
    last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0
    
    has_license = @project.license.present? ? 1 : 0

    closed_pullrequest_count = PullRequest.where(project_id: @project.id).merged_and_closed.count
    closed_issue_count = Issue.issue_issue.where(project_id: @project.id).closed.count
    pullrequest_count = PullRequest.where(project_id: @project.id).count
    issue_count = Issue.issue_issue.where(project_id: @project.id).count
    health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count)
    health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day))
    health_code = 10 * (health_code1 + health_code2)
    health_license = 10 * has_license
    health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1)) 
    health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1))

    project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue)

    # 团队影响度
    member_count = Member.where(project_id: @project.id).count
    max_member_count = @platform_statistic['max-member-count'].to_i
    recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count
    max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i
    issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count
    team_impact_member = 40*(member_count.to_f/max_member_count)
    team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count)
    team_impact_issue_assigner = 20*(issue_assigner_count.to_f/max_member_count)
    team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner)

    # 开发活跃度
    recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
    recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
    recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count
    recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count
    max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i
    max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i
    max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i
    max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i
    develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count)
    develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count)
    develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count)
    develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count)
    develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release)

    render :json => {community_impact: community_impact, project_maturity: project_maturity, project_health: project_health, team_impact: team_impact, develop_activity: develop_activity}
  end

  # 社区影响力
  def community_impact 
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
    praise_count = PraiseTread.where(praise_tread_object_type: "Project", praise_tread_object_id: @project.id).count 
    watcher_count = Watcher.where(watchable_type:"Project", watchable_id: @project.id).count 
    fork_count = ForkUser.where(project_id: @project.id).count 
    community_impact_praise = @platform_statistic['max-praise-count'].to_i == 0 ? 0 : 30*(praise_count.to_f/@platform_statistic['max-praise-count'].to_i)
    community_impact_watcher = @platform_statistic['max-watcher-count'].to_i == 0 ? 0 : 30*(watcher_count.to_f/@platform_statistic['max-watcher-count'].to_i)
    community_impact_fork = @platform_statistic['max-fork-count'].to_i == 0 ? 0 : 40*(fork_count.to_f/@platform_statistic['max-fork-count'].to_i)
    community_impact = format("%.2f", community_impact_praise + community_impact_watcher + community_impact_fork)

    render :json => {
      community_impact_praise: community_impact_praise,
      community_impact_watcher: community_impact_watcher, 
      community_impact_fork: community_impact_fork, 
      community_impact: community_impact
    }
  end

  # 项目成熟度
  def project_maturity
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
    pullrequest_count = PullRequest.where(project_id: @project.id).count
    complete_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
    project_create_day = (Time.now.to_i - @project.created_on.to_i)/(3600*24)
    max_project_create_day = (Time.now.to_i - Project.order("created_on desc").last.created_on.to_i)/(3600*24)
    project_maturity_pullrequest = @platform_statistic['max-pullrequest-count'].to_i == 0? 0 : 40*(pullrequest_count.to_f/@platform_statistic['max-pullrequest-count'].to_i)
    project_maturity_complete_issue = @platform_statistic['max-complete-issue-count'].to_i == 0? 0 : 40*(complete_issue_count.to_f/@platform_statistic['max-complete-issue-count'].to_i)
    project_maturity_project_create_day = max_project_create_day.to_i <= 0 || project_create_day.to_i <= 0 ? 0 : 20*(Math.sqrt(project_create_day).to_f/Math.sqrt(max_project_create_day))
    project_maturity = format("%.2f", project_maturity_pullrequest + project_maturity_complete_issue + project_maturity_project_create_day)

    render :json => {
      project_maturity_pullrequest: project_maturity_pullrequest,
      project_maturity_complete_issue: project_maturity_complete_issue,
      project_maturity_project_create_day: project_maturity_project_create_day,
      project_maturity: project_maturity
    }
  end

  # 项目健康度
  def project_health
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")

    member_count = Member.where(project_id: @project.id).count
    max_member_count = @platform_statistic['max-member-count'].to_i

    project_last_commit = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).order("created_at desc").first
    last_commit_day = project_last_commit.present? ? (Time.now.to_i - project_last_commit.created_at.to_i)/(3600*24) : 0
    
    has_license = @project.license.present? ? 1 : 0

    closed_pullrequest_count = PullRequest.where(project_id: @project.id, status: 1).count
    closed_issue_count = Issue.issue_issue.where(project_id: @project.id, status_id: [3,5]).count
    pullrequest_count = PullRequest.where(project_id: @project.id).count
    issue_count = Issue.issue_issue.where(project_id: @project.id).count
    health_code1 = max_member_count.to_i == 0 ? 0 : 0.3*(member_count.to_f/max_member_count)
    health_code2 = last_commit_day.to_i == 0 ? 0 : 0.7*(1.to_f/(1+last_commit_day*0.1))
    health_code = 10 * (health_code1 + health_code2)
    health_license = 10 * has_license
    health_pullrequest = pullrequest_count <= 1 ? 0 : 40 * (closed_pullrequest_count.to_f/pullrequest_count)*(1-1/Math.sqrt(pullrequest_count+1)) 
    health_issue = issue_count <= 1 ? 0 : 40 * (closed_issue_count.to_f/issue_count)*(1-1/Math.sqrt(issue_count+1))

    project_health = format("%.2f", health_code + health_license + health_pullrequest + health_issue)

    render :json => {
      health_code: health_code,
      health_license: health_license,
      health_pullrequest: health_pullrequest,
      health_issue: health_issue,
      project_health: project_health
    }
  end

  # 团队健康度
  def team_impact
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
    member_count = Member.where(project_id: @project.id).count
    max_member_count = @platform_statistic['max-member-count'].to_i
    recent_one_month_member_count = Member.where(project_id:@project.id).where("created_on >?", Time.now - 30.days).count
    max_recent_one_month_member_count = @platform_statistic['max-recent-one-month-member-count'].to_i
    issue_assigner_count = IssueAssigner.joins(:issue).merge(Issue.issue_issue).where(issues: {project_id: @project.id}).distinct.count
    project_member_count = @project.owner.is_a?(User) ? member_count : @project.owner.organization_users.count
    team_impact_member = 40*(member_count.to_f/max_member_count)
    team_impact_recent_member = 40*(recent_one_month_member_count.to_f/max_recent_one_month_member_count)
    team_impact_issue_assigner = 20*(issue_assigner_count.to_f/project_member_count)
    team_impact = format("%.2f", team_impact_member + team_impact_recent_member + team_impact_issue_assigner)

    render :json => {
      team_impact_member: team_impact_member,
      team_impact_recent_member: team_impact_recent_member,
      team_impact_issue_assigner: team_impact_issue_assigner, 
      team_impact: team_impact
    }
  end

  # 开发活跃度
  def develop_activity
    Cache::V2::PlatformStatisticService.new().reset
    @platform_statistic = $redis_cache.hgetall("v2-platform-statistic")
    recent_one_month_commit_count = CommitLog.joins(:project).merge(Project.common).where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
    recent_one_month_pullrequest_count = PullRequest.where(project_id: @project.id).where("created_at >?", Time.now - 30.days).count
    recent_one_month_issue_count = Issue.issue_issue.where(project_id: @project.id).where("created_on >?", Time.now - 30.days).count
    recent_one_month_release_count = VersionRelease.joins(:repository).where(repositories: {project_id: @project.id}).where("created_at >?", Time.now - 30.days).count
    max_recent_one_month_commit_count = @platform_statistic['max-recent-one-month-commit-count'].to_i
    max_recent_one_month_pullrequest_count = @platform_statistic['max-recent-one-month-pullrequest-count'].to_i
    max_recent_one_month_issue_count = @platform_statistic['max-recent-one-month-issue-count'].to_i
    max_recent_one_month_release_count = @platform_statistic['max-recent-one-month-release-count'].to_i
    develop_activity_commit = max_recent_one_month_commit_count.zero? ? 0 : 40*(recent_one_month_commit_count.to_f/max_recent_one_month_commit_count)
    develop_activity_issue = max_recent_one_month_issue_count.zero? ? 0 : 20*(recent_one_month_issue_count.to_f/max_recent_one_month_issue_count)
    develop_activity_pullrequest = max_recent_one_month_pullrequest_count.zero? ? 0 : 20*(recent_one_month_pullrequest_count.to_f/max_recent_one_month_pullrequest_count)
    develop_activity_release = max_recent_one_month_release_count.zero? ? 0 : 20*(recent_one_month_release_count.to_f/max_recent_one_month_release_count)
    develop_activity = format("%.2f", develop_activity_commit + develop_activity_issue + develop_activity_pullrequest + develop_activity_release)

    render :json => {
      develop_activity_commit: develop_activity_commit,
      develop_activity_issue: develop_activity_issue,
      develop_activity_pullrequest: develop_activity_pullrequest,
      develop_activity_release: develop_activity_release,
      develop_activity: develop_activity
    }
  end
end