<?php

namespace App\Http\Controllers\Appearance;

use App\Exceptions\AlertException;
use App\Http\Controllers\Core\Auth;
use App\Models\Appearance\PartnerRankModel;
use App\Models\Appearance\SchoolRankModel;
use App\Models\Appearance\AppearanceModel;
use App\Models\Appearance\AppearanceVoteModel;
use App\Models\Fpdx\MediaModel;
use App\Models\User\UserModel;
use App\Models\PartnerModel;
use App\Models\SchoolModel;
use App\Services\Appearance\RankService;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class RankController extends Controller
{


    /**
     * 学校榜
     * @param  Request  $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function schoolRank(Request $request)
    {
        $sex = $request->get('sex', 2);
        $page = $request->get('page', 1);
        $per_page = $request->get('per_page', 20);
        if ($request->filled('monthly')) {
            $type = 'monthly';
            $date = $request->get("date", date("Y-m-01"));
            $date = date("Y-05-01");
        } elseif ($request->filled("weekly")) {
            $type = 'weekly';
            $date = $request->get("date", date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)));
            $date = date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600));
        } else {
            $type = 'daily';
            $date = $request->get("date", date("Y-m-d"));
            $date = date("Y-m-d");
        }
        $school = $request->get('school', null);
        if (is_null($school)) {
            $random = rand(0, 460);
            $school = PartnerRankModel::where('date', $date)
                ->where('type', $type)
                ->where('sex', $sex)
                ->groupBy('school')
                ->havingRaw('count(*) > 20')
                ->skip($random)
                ->value('school');
        }
        $schoolModel = SchoolModel::where('school', $school)->firstOrFail();

        $builder = \DB::table("fpdx_appearance_partner_ranks as r")
            ->selectRaw("r.partner_id, r.sex, r.school, r.count")
            ->join("fpdx_appearances as a", "r.partner_id", '=', 'a.partner_id')
            ->where('r.date', $date)
            ->where('r.type', $type)
            ->where('r.school', $school)
            ->where('r.sex', $sex)
            ->where('a.state', 2);
        $total = $builder->count();
        $votes = $builder->orderBy('count', 'desc')->offset(($page - 1) * $per_page)->limit($per_page)->get();
        $last_page = ceil($total / $per_page);

        try {
            $uid = Auth::auth();
            $appearance = AppearanceModel::where('uid', $uid)->first();
            if ($appearance && $appearance->school == $school && $appearance->sex == $sex && $appearance->state == 2) {
                $partner = PartnerModel::select(
                    'address',
                    'age',
                    'check_photo',
                    'is_sell',
                    'id',
                    'media_id',
                    'photo_src',
                    'photo_1',
                    'photo_2',
                    'photo_3',
                    'photo_4',
                    'photo_1_check',
                    'photo_2_check',
                    'photo_3_check',
                    'photo_4_check',
                    'voice',
                    'voice_check',
                    'praises',
                    'school',
                    'star'
                )->find($appearance->partner_id);
                // 我的排名
                $count = PartnerRankModel::where('date', $date)->where('type', $type)->where(
                    'partner_id',
                    $appearance->partner_id
                )->value('count');
                $rank = $count ?
                    \DB::table("fpdx_appearance_partner_ranks as r")
                        ->join("fpdx_appearances as a", "r.partner_id", "=", "a.partner_id")
                        ->where('r.date', $date)
                        ->where('r.type', $type)
                        ->where('r.school', $school)
                        ->where('r.count', '>', $count)
                        ->where('r.sex', $sex)
                        ->where("a.state", 2)
                        ->count() + 1
                    : null;
                $self = true;
                $pick = AppearanceVoteModel::where('uid', $uid)->where('type', 2)->where(
                    'partner_id',
                    $appearance->partner_id
                )->today()->first() ? true : false;
                $my_rank = [
                    'appearance' => $appearance,
                    'partner' => $partner,
                    'user' => UserModel::select(
                        'nickname',
                        'headimgurl',
                        'identity_auth',
                        'sex',
                        'age',
                        'star'
                    )->find($uid),
                    'count' => $count,
                    'self' => $self,
                    'pick' => $pick,
                    'rank' => $rank,
                ];
            } else {
                $my_rank = [
                    'appearance' => $appearance,
                ];
            }
        } catch (\Exception $e) {
            $uid = 0;
            $my_rank = null;
        }

        $picks = AppearanceVoteModel::where('uid', $uid)->where('type', 2)->whereIn(
            'partner_id',
            $votes->pluck('partner_id')->toArray()
        )->today()->get();
        $partners = PartnerModel::whereIn('id', $votes->pluck('partner_id')->toArray())->get([
            'uid',
            'address',
            'age',
            'check_photo',
            'is_sell',
            'id',
            'media_id',
            'photo_src',
            'photo_1',
            'photo_2',
            'photo_3',
            'photo_4',
            'photo_1_check',
            'photo_2_check',
            'photo_3_check',
            'photo_4_check',
            'voice',
            'voice_check',
            'praises',
            'school',
            'star'
        ])->toArray();
        $partners = array_combine(array_column($partners, 'id'), $partners);
        $users = UserModel::whereIn('uid', array_column($partners, 'uid'))->get([
            'uid',
            'nickname',
            'headimgurl',
            'identity_auth',
            'sex',
            'age',
            'star'
        ])->toArray();
        $users = array_combine(array_column($users, 'uid'), $users);
        foreach ($votes as $vote) {
            $vote->self = $uid && $appearance && $appearance->partner_id == $vote->partner_id ? true : false;
            $vote->pick = $uid && in_array($vote->partner_id, $picks->pluck('partner_id')->toArray()) ? true : false;
            $vote->partner = $partners[$vote->partner_id];
            $vote->user = $users[$vote->partner['uid']];
        }
        // 学校票数
        $school_count = SchoolRankModel::where('date', $date)->where('type', $type)->where(
            'school',
            $school
        )->value('count') ?: 0;
        // 学校全国全省排名
        $country_school_number = SchoolRankModel::where('date', $date)->where('type', $type)->count() ?: 1;
        $country_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
            'count',
            '>',
            $school_count
        )->count() + 1;
        $province_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
            'province',
            $schoolModel->province
        )->where('count', '>', $school_count)->count() + 1;
        // 排名上一个学校
        if ($province_school_rank == 1) {
            $last = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                'count',
                '>',
                $school_count
            )->orderBy('count', 'asc')->first();
        } else {
            $last = SchoolRankModel::where([
                'date' => $date,
                'type' => $type,
                'province' => $schoolModel->province,
            ])->where('count', '>', $school_count)->orderBy('count', 'asc')->first();
        }
        // 跟上一名学校差距的票
        if ($last) {
            $last_school = $last->school;
            $disparity_count = $last->count - $school_count;
        } else {
            $last_school = null;
            $disparity_count = null;
        }

        $self = $uid && $appearance && $appearance->school == $school ? true : false;
        $pick = $uid && AppearanceVoteModel::where('uid', $uid)->where('type', 1)->where(
            'school',
            $school
        )->today()->first() ? true : false;
        $ratio = round(($country_school_rank - 1) / $country_school_number * 100, 2) . '%';
        $media = (new RankService())->getSchoolFirstMedia($school);
        $meta = [
            'self' => $self,
            'pick' => $pick,
            'school' => $school,
            'count' => $school_count,
            'last_school' => $last_school,
            'disparity_count' => $disparity_count,
            'ratio' => $ratio,
            'my_rank' => $my_rank,
            'province_school_rank' => $province_school_rank,
            'country_school_rank' => $country_school_rank,
            'country_school_number' => $country_school_number,
            'sex' => $sex,
            'current_page' => $page,
            'per_page' => $per_page,
            'last_page' => $last_page,
            'total' => $total,
            'media' => $media
        ];
        return response([
            'code' => 200,
            'message' => 'OK',
            'data' => $votes,
            'meta' => $meta,
        ]);
    }


    /**
     * 全国榜
     * @param  Request  $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function countryRank(Request $request)
    {
        $page = $request->get('page', 1);
        $per_page = $request->get('per_page', 20);
        if ($request->filled('monthly')) {
            $type = 'monthly';
            $date = $request->get("date", date("Y-m-01"));
            $date = date("Y-05-01");
        } elseif ($request->filled("weekly")) {
            $type = 'weekly';
            $date = $request->get("date", date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)));
            $date = date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600));
        } else {
            $type = 'daily';
            $date = $request->get("date", date("Y-m-d"));
            $date = date("Y-m-d");
        }
        $rankService = new RankService();
        $builder = SchoolRankModel::where('date', $date)->where('type', $type);
        $total = $builder->count();
        $votes = $builder->orderBy('count', 'desc')->offset(($page - 1) * $per_page)->limit($per_page)->get();
        $last_page = ceil($total / $per_page);
        try {
            $uid = Auth::auth();
            $user = UserModel::find($uid);
            $my_school = $user->school;
            if ($my_school && $schoolModel = SchoolModel::where('school', $my_school)->first()) {
                $pick = AppearanceVoteModel::where('uid', $uid)->where('type', 1)->where(
                    'school',
                    $my_school
                )->today()->first() ? true : false;
                $count = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'school',
                    $my_school
                )->value('count');
                $rank = $count ? SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'count',
                    '>',
                    $count
                )->count() + 1 : null;
                $partners = $rankService->getPartners($type, $date, $my_school);

                // 学校票数
                $school_count = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'school',
                    $schoolModel->school
                )->value('count') ?: 0;
                // 学校全国全省排名
                $country_school_number = SchoolRankModel::where('date', $date)->where('type', $type)->count() ?: 1;
                $country_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'count',
                    '>',
                    $school_count
                )->count() + 1;
                $province_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'province',
                    $schoolModel->province
                )->where('count', '>', $school_count)->count() + 1;
                // 排名上一个学校
                if ($province_school_rank == 1) {
                    $last = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                        'count',
                        '>',
                        $school_count
                    )->orderBy('count', 'asc')->first();
                } else {
                    $last = SchoolRankModel::where([
                        'date' => $date,
                        'type' => $type,
                        'province' => $schoolModel->province,
                    ])->where('count', '>', $school_count)->orderBy('count', 'asc')->first();
                }
                // 跟上一名学校差距的票
                if ($last) {
                    $last_school = $last->school;
                    $disparity_count = $last->count - $school_count;
                } else {
                    $last_school = null;
                    $disparity_count = null;
                }
                $ratio = round(($country_school_rank - 1) / $country_school_number * 100, 2) . '%';
                $my_rank = [
                    'school' => $schoolModel->school,
                    'province' => $schoolModel->province,
                    'city' => $schoolModel->city,
                    'partners' => $partners,
                    'count' => $count,
                    'rank' => $rank,
                    'self' => true,
                    'pick' => $pick,
                    'province_school_rank' => $province_school_rank,
                    'country_school_rank' => $country_school_rank,
                    'last_school' => $last_school,
                    'disparity_count' => $disparity_count,
                    'ratio' => $ratio,
                ];
            } else {
                $my_rank = [
                    'school' => $my_school
                ];
            }
        } catch (\Exception $e) {
            $uid = 0;
            $my_rank = null;
        }
        $schools = AppearanceVoteModel::where('uid', $uid)->where('type', 1)->whereIn(
            'school',
            $votes->pluck('school')->toArray()
        )->today()->get();
        $schoolsRank = $rankService->getSchoolsFirstPartner($type, $date, $votes->pluck('school')->toArray());
        foreach ($votes as $vote) {
            $vote->pick = $uid && in_array($vote->school, $schools->pluck('school')->toArray()) ? true : false;
            $partners = array(
                'men' => empty($schoolsRank[$vote->school]['men']['partner']['photo_src']) ? "" : "https://oss.pocketuniversity.cn" . $schoolsRank[$vote->school]['men']['partner']['photo_src'],
                'women' => empty($schoolsRank[$vote->school]['women']['partner']['photo_src']) ? "" : "https://oss.pocketuniversity.cn" . $schoolsRank[$vote->school]['women']['partner']['photo_src'],
            );
            $vote->partners = $partners;
        }
        $meta = [
            'current_page' => $page,
            'per_page' => $per_page,
            'last_page' => $last_page,
            'total' => $total,
            'my_rank' => $my_rank
        ];
        return response([
            'code' => 200,
            'message' => 'OK',
            'data' => $votes,
            'meta' => $meta,
        ]);
    }


    /**
     * 省榜
     * @param  Request  $request
     * @param $province
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function provinceRank(Request $request, $province)
    {
        $page = $request->get('page', 1);
        $per_page = $request->get('per_page', 20);
        if ($request->filled('monthly')) {
            $type = 'monthly';
            $date = $request->get("date", date("Y-m-01"));
            $date = date("Y-05-01");
        } elseif ($request->filled("weekly")) {
            $type = 'weekly';
            $date = $request->get("date", date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600)));
            $date = date('Y-m-d', (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600));
        } else {
            $type = 'daily';
            $date = $request->get("date", date("Y-m-d"));
            $date = date("Y-m-d");
        }

        $builder = SchoolRankModel::where('date', $date)->where('type', $type)->where('province', $province);
        $total = $builder->count();
        $votes = $builder->orderBy('count', 'desc')->offset(($page - 1) * $per_page)->limit($per_page)->get();
        $last_page = ceil($total / $per_page);
        $rankService = new RankService();
        try {
            $uid = Auth::auth();
            $user = UserModel::find($uid);
            $my_school = $user->school;
            if (
                $my_school && $schoolModel = SchoolModel::where('school', $my_school)->where(
                    'province',
                    $province
                )->first()
            ) {
                $pick = AppearanceVoteModel::where('uid', $uid)->where('type', 1)->where(
                    'school',
                    $my_school
                )->today()->first() ? true : false;
                $count = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'province',
                    $province
                )->where('school', $schoolModel->school)->value('count');
                $rank = $count ? SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'province',
                    $province
                )->where('count', '>', $count)->count() + 1 : null;
                // 学校排名第一的校花校草
                $partners = $rankService->getPartners($type, $date, $schoolModel->school);

                // 学校票数
                $school_count = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'school',
                    $schoolModel->school
                )->value('count') ?: 0;
                // 学校全国全省排名
                $country_school_number = SchoolRankModel::where('date', $date)->where('type', $type)->count() ?: 1;
                $country_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'count',
                    '>',
                    $school_count
                )->count() + 1;
                $province_school_rank = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                    'province',
                    $schoolModel->province
                )->where('count', '>', $school_count)->count() + 1;
                // 排名上一个学校
                if ($province_school_rank == 1) {
                    $last = SchoolRankModel::where('date', $date)->where('type', $type)->where(
                        'count',
                        '>',
                        $school_count
                    )->orderBy('count', 'asc')->first();
                } else {
                    $last = SchoolRankModel::where([
                        'date' => $date,
                        'type' => $type,
                        'province' => $schoolModel->province,
                    ])->where('count', '>', $school_count)->orderBy('count', 'asc')->first();
                }
                // 跟上一名学校差距的票
                if ($last) {
                    $last_school = $last->school;
                    $disparity_count = $last->count - $school_count;
                } else {
                    $last_school = null;
                    $disparity_count = null;
                }
                $ratio = round(($country_school_rank - 1) / $country_school_number * 100, 2) . '%';

                $my_rank = [
                    'school' => $schoolModel->school,
                    'province' => $schoolModel->province,
                    'city' => $schoolModel->city,
                    'partners' => $partners,
                    'count' => $count,
                    'rank' => $rank,
                    'self' => true,
                    'pick' => $pick,
                    'province_school_rank' => $province_school_rank,
                    'country_school_rank' => $country_school_rank,
                    'last_school' => $last_school,
                    'disparity_count' => $disparity_count,
                    'ratio' => $ratio,
                ];
            } else {
                $my_rank = [
                    'school' => $my_school
                ];
            }
        } catch (\Exception $e) {
            $uid = 0;
            $my_rank = null;
        }

        $schools = AppearanceVoteModel::where('uid', $uid)->where('type', 1)->whereIn(
            'school',
            $votes->pluck('school')->toArray()
        )->today()->get();
        $schoolsRank = $rankService->getSchoolsFirstPartner($type, $date, $votes->pluck('school')->toArray());
        foreach ($votes as $vote) {
            $vote->pick = $uid && in_array($vote->school, $schools->pluck('school')->toArray()) ? true : false;
            $partners = array(
                'men' => empty($schoolsRank[$vote->school]['men']['partner']['photo_src']) ? "" : "https://oss.pocketuniversity.cn" . $schoolsRank[$vote->school]['men']['partner']['photo_src'],
                'women' => empty($schoolsRank[$vote->school]['women']['partner']['photo_src']) ? "" : "https://oss.pocketuniversity.cn" . $schoolsRank[$vote->school]['women']['partner']['photo_src'],
            );
            $vote->partners = $partners;
        }
        $meta = [
            'current_page' => $page,
            'per_page' => $per_page,
            'last_page' => $last_page,
            'total' => $total,
            'my_rank' => $my_rank
        ];
        return response([
            'code' => 200,
            'message' => 'OK',
            'data' => $votes,
            'meta' => $meta,
        ]);
    }


    /**
     * 卡片信息
     * @param  Request  $request
     * @param $partner_id
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     * @throws AlertException
     */
    public function partner(Request $request, $partner_id)
    {
        $partner = PartnerModel::findOrFail($partner_id);
        $appearance = AppearanceModel::where('partner_id', $partner_id)->first();
        if (!$appearance) {
            throw new AlertException("卡片未参与投票");
        }
        $user = UserModel::find($partner->uid);
        $type = 'monthly';
        $date = date('Y-m-01');
        $count = PartnerRankModel::where('date', $date)->where('type', $type)->where(
            'partner_id',
            $partner_id
        )->value('count');
        try {
            $uid = Auth::auth();
            $self = $user->partner_id == $partner_id ? true : false;
            $pick = AppearanceVoteModel::where('uid', $uid)->where('type', 2)->where(
                'partner_id',
                $partner_id
            )->today()->first() ? true : false;
        } catch (\Exception $e) {
            $self = false;
            $pick = false;
        }

        return response([
            'code' => 200,
            'message' => 'OK',
            'data' => [
                'partner' => $partner,
                'user' => $user,
                'count' => $count,
                'self' => $self,
                'pick' => $pick,
            ]
        ]);
    }


    /**
     * logo墙
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function medias()
    {
        $medias = MediaModel::select('media_id', 'public_name', 'head_img')
            ->whereIn('media_id', \DB::table("pocket.kdgx_activity_enrolls")
                ->where("state", 1)
                ->pluck('media_id'))->get();
        return response([
            'code' => 200,
            'message' => 'OK',
            'data' => $medias
        ]);
    }
}
