<?php

namespace App\Http\Controllers;

use App\Models\Clan\CF_CLAN_INFO;
use App\Models\Clan\CF_CLAN_MEMBER_INFO;
use App\Models\Game\CF_ITEM_INFO;
use App\Models\Game\CF_MEMBER;
use App\Models\Game\CF_MIN_CU;
use App\Models\Game\CF_RANK_MEDAL;
use App\Models\Game\CF_RANK_USER_CUR_MODE_SCORE;
use App\Models\Game\CF_RANK_USER_CUR_TM;
use App\Models\Game\CF_USER;
use App\Models\Game\CF_USER_INVENTORY;
use App\Models\Log\CF_PLAY_LOG;
use App\Models\Web\CF_WEB_ADMIN_OTP;
use App\Models\Web\CF_WEB_DOWNLOADS;
use App\Models\Web\CF_WEB_EVENT_TRACK_INFO;
use App\Models\Web\CF_WEB_GO_EVENT_INFO;
use App\Models\Web\CF_WEB_NEWS;
use App\Models\Web\CF_WEB_QUESTION_INFO;
use App\Models\Bills\TAccountCashMst;
use App\Models\Web\CF_WEB_USER_BAN_INFO;
use App\Models\Web\Forum\CF_USER_PREREGISTER;
use App\Models\Web\Forum\mybb_users;
use App\Models\Web\Wof\CF_WEB_WOF_BASE_INFO;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;

class IndexController extends Controller
{
    public function index ()
    {
        $news = \Cache::tags(["web", "news"])->remember("index-news", env("CACHE_MIN_TTL"), function() {
            return CF_WEB_NEWS::where("NOTICE_STATUS_AI", 'A')->latest("REG_DATE")->with(["author:USN,NICK"])->limit(3)->get(["SRL", "USN", "BIG_IMAGE_URL", "NOTICE_TAG", "NOTICE_TITLE", "REG_DATE"]);
        });

        $topfive_players = \Cache::tags(["web", "ranks"])->remember("index-rank-players", env("CACHE_MIN_TTL"), function() {
            return CF_USER::join("CF_MEMBER", "CF_USER.USN", '=', "CF_MEMBER.USN")
                ->where("CF_MEMBER.AUTHORITY_LEV", 0)
                ->where("AUTHORITY", 'N')
                ->where("HOLD_TYPE", "A")
                ->orderBy("EXP", "DESC")
                ->orderBy("NICK")->limit(5)
                ->get(["CF_MEMBER.USN", "NICK", "EXP", "LEV"]);
        });

        $topfive_ranked = \Cache::tags(["web", "ranks"])->remember("index-rank-ranked", env("CACHE_MIN_TTL"), function() {
            return CF_RANK_USER_CUR_MODE_SCORE::with(["user" => function($query) {
                $query->where("AUTHORITY", 'N');
            }])
            ->join("CF_RANK_MEDAL", function(JoinClause $join) {
                $join->on("CF_RANK_USER_CUR_MODE_SCORE.RANK_SCORE", ">", "CF_RANK_MEDAL.MIN_SCORE")
                    ->on("CF_RANK_USER_CUR_MODE_SCORE.RANK_SCORE", "<", "CF_RANK_MEDAL.MAX_SCORE");
            })
            ->join("CF_MEMBER", "CF_RANK_USER_CUR_MODE_SCORE.USN", '=', "CF_MEMBER.USN")
            ->where("CF_MEMBER.AUTHORITY_LEV", 0)
            ->where("RANK_MODE_INDEX", 2)
            ->where("MATCH_COUNT", ">", 5)
            ->latest("RANK_SCORE")
            ->limit(5)
            ->get();
        });

        $serverInfos = \Cache::tags(["web"])->remember("index-server-infos", env("CACHE_MIN_TTL"), function() {
            $infos = \DB::connection("cf_web")->select("
            DECLARE @p_Status VARCHAR(3); DECLARE @p_CCU VARCHAR(100); DECLARE @p_MCU BIGINT; DECLARE @p_CXP BIGINT; DECLARE @p_CGP BIGINT; DECLARE @p_EPEVT_YN VARCHAR(1); DECLARE @p_GPEVT_YN VARCHAR(1);
            EXEC [dbo].[WSP_SERVER_INFO_SEL] @p_Status OUTPUT, @p_CCU OUTPUT, @p_MCU OUTPUT, @p_CXP OUTPUT, @p_CGP OUTPUT, @p_EPEVT_YN OUTPUT, @p_GPEVT_YN OUTPUT;
            SELECT @p_Status as status, @p_CCU as ccu, @p_MCU as mcu, @p_CXP as cxp, @p_CGP as cgp, @p_EPEVT_YN as epevt, @p_GPEVT_YN as gpevt")[0];
            return [
                "infos" => $infos,
                "totalAccounts" => CF_MEMBER::where("EMAIL_VERIFY_YN", 'Y')->count("USN")
            ];
        });

        return view("index")->with(["news" => $news, "topfive" => $topfive_players, "topfive_ranked" => $topfive_ranked, "serverInfos" => $serverInfos]);
    }

    public function lang (Request $request, $lang)
    {
        if (array_key_exists($lang, config("app.languages")))
        {
            \App::setLocale($lang);
            return response()->redirectToRoute("home")->withCookie(cookie()->forever("lang", $lang));
        }

        return redirect()->home();
    }

    public function error (Request $request)
    {
        return view("errors.others");
    }

    public function downloads ()
    {
        // return redirect()->home();

        $downloadDefault = CF_WEB_DOWNLOADS::where("DEFAULT_YN", 'Y')->first(["SRL", "TITLE", "URL", "SIZE", "FORMAT"]);
        $downloadsAlt = CF_WEB_DOWNLOADS::where("DEFAULT_YN", 'N')->where("REQ_YN", 'N')->get(["SRL", "TITLE", "URL", "TYPE", "SIZE", "FORMAT"]);
        $downloadsReq = CF_WEB_DOWNLOADS::where("REQ_YN", 'Y')->get(["SRL", "TITLE", "URL", "TYPE", "SIZE", "FORMAT"]);
        return view('download', compact("downloadDefault", "downloadsAlt", "downloadsReq"));
    }

    public function wallOfShame(Request $request)
    {
        if ($request->query("page")) {
            $bans = CF_WEB_USER_BAN_INFO::with(["user:USN,NICK"])->latest("SRL")->paginate(25);
        } else {
            $bans = \Cache::tags(["web", "wos"])->remember("wos", config("cache.half_ttl"), function () {
                return CF_WEB_USER_BAN_INFO::with(["user:USN,NICK"])->latest("SRL")->paginate(25);
            });
        }
        return view("wallofshame", compact("bans"));
    }

    public function rankingPlayers (Request $request, $alpha = null)
    {
        switch ($alpha)
        {
            case "weapons": {
                return $this->doShowRankPlayersWeapons($request);
            }
            case "kd": {
                return $this->doShowRankPlayersKD($request);
            }
            default: {
                return $this->doShowRankPlayers($request);
            }
        }
    }

    public function rankingClans (Request $request)
    {
        if (\Cache::has('ranking-clans') && !$request->query('page', false))
            return view('ranking.ranking-clans')->withData(\Cache::get('ranking-clans'));

        $ranking = CF_CLAN_INFO::with(["detail:Clankey,Clanname", "master:USN,NICK"])->orderBy("ClanPoint", "DESC")->paginate(10, [
                "ClanKey", "MasterUsn", "ClanPoint", "Level", "WinCount", "LoseCount", "MarkLayer01", "MarkLayer02", "MarkLayer03"
        ]);
        if ($ranking != null)
        {
            if (!$request->query('page', false)) {
                \Cache::tags(["web"])->remember('ranking-clans', env("CACHE_TTL"), function () use ($ranking) {
                    return $ranking;
                });
            }
        }

        return view('ranking.ranking-clans')->with([
            "data" => $ranking,
            "noPage" => false
        ]);
    }

    public function rankingRanked (Request $request)
    {
        if (\Cache::has('ranking-ranked') && !$request->query('page', false))
            return view('ranking.ranking-ranked')->withData(\Cache::get('ranking-ranked'));

        $ranking = CF_RANK_USER_CUR_MODE_SCORE::selectRaw("SUM(RANK_SCORE) AS SCORE, SUM(\"KILL\") AS PK, SUM(DEATH) AS PD, SUM(WIN) as PW, SUM(LOSE) AS PL, CF_RANK_USER_CUR_MODE_SCORE.USN")
        ->with(["user" => function($query) { $query->where("AUTHORITY", "N"); }])
        ->join("CF_MEMBER", "CF_RANK_USER_CUR_MODE_SCORE.USN", '=', "CF_MEMBER.USN")
        ->where("CF_MEMBER.AUTHORITY_LEV", 0)
        ->where("RANK_MODE_INDEX", 2)
        ->groupBy(["CF_RANK_USER_CUR_MODE_SCORE.USN"])
        ->orderByRaw("SUM(RANK_SCORE) DESC")
        ->paginate(10);			   
        if ($ranking != null)
        {
            if (!$request->query('page', false)) {
                \Cache::tags(["web"])->remember('ranking-ranked', env("CACHE_TTL"), function () use ($ranking) {
                    return $ranking;
                });
            }
        }

        return view('ranking.ranking-ranked')->with([
            "data" => $ranking,
            "noPage" => false
        ]);
    }

    ///
    /// private
    ///

    private function doShowRankPlayers(Request $request)
    {
        if (\Cache::has("ranking-players") && !$request->query("page", false))
            return view("ranking.ranking-players")->withData(\Cache::get("ranking-players"));

        $ranking = CF_USER::where("AUTHORITY", "N")
            ->orderBy("EXP", "DESC")
            ->orderBy("NICK", "ASC")
            ->with(["clan.detail", "ranked_sd"])->paginate(10);

        if (!$request->query("page", false)) {
            \Cache::tags(["web"])->remember("ranking-players", env("CACHE_TTL"), function () use ($ranking) {
                return $ranking;
            });
        }

        return view("ranking.ranking-players")->with([
            "data" => $ranking,
            "noPage" => false
        ]);
    }

    private function doShowRankPlayersWeapons(Request $request)
    {
        if (\Cache::has("ranking-playersW") && !$request->query("page", false))
            return view("ranking.ranking-playersW")->withData(\Cache::get("ranking-playersW"));

        $ranking = CF_USER::selectRaw("CF_USER.USN, CF_USER.NICK, CF_USER.LEV, COUNT(DISTINCT CF_USER_INVENTORY.ITEM_CODE) AS ITEM_COUNT")
            ->join("CF_USER_INVENTORY", "CF_USER.USN", "=", "CF_USER_INVENTORY.USN")
            ->join("CF_ITEM_INFO", "CF_ITEM_INFO.ITEM_CODE", "=", "CF_USER_INVENTORY.ITEM_CODE")
            ->where("CF_USER_INVENTORY.ITEM_TYPE", "W")
            ->where("CF_ITEM_INFO.USE_TYPE1", "E")
            ->groupBy("CF_USER.USN")
            ->groupBy("CF_USER.NICK")
            ->groupBy("CF_USER.LEV")
            ->orderBy("ITEM_COUNT", "DESC")
            ->paginate(10)->onEachSide(5);

        if (!$request->query('page', false)) {
            \Cache::tags(["web"])->remember('ranking-playersW', env("CACHE_TTL"), function () use ($ranking) {
                return $ranking;
            });
        }

        return view('ranking.ranking-playersW')->with([
            "data" => $ranking,
            "noPage" => true
        ]);
    }

    private function doShowRankPlayersKD(Request $request)
    {
        if (\Cache::has('ranking-playersK') && !$request->query('page', false))
            return view('ranking.ranking-playersK')->withData(\Cache::get('ranking-playersK'));

        $ranking = CF_USER::selectRaw("
                CF_USER.USN, 
                CF_USER.NICK, 
                CF_USER.LEV, 
                CF_USER.ENEMY_KILL_CNT, 
                CF_USER.DEATH_CNT, 
                COALESCE(CF_USER.ENEMY_KILL_CNT / NULLIF(CF_USER.DEATH_CNT,0), 0) AS KD,
                (CF_USER.ENEMY_KILL_CNT-CF_USER.DEATH_CNT) as SPLIT"
            )->where("CF_USER.LEV", ">=", 99)
            ->where("CF_USER.AUTHORITY", ">=", 'N')
            ->where("ENEMY_KILL_CNT", ">", 200000)
            ->orderBy("KD", "DESC")
            ->orderBy("CF_USER.ENEMY_KILL_CNT", "DESC")
            ->orderBy("SPLIT", "DESC")
            ->paginate(10);

        if (!$request->query('page', false)) {
            \Cache::tags(["web"])->remember('ranking-playersK', env("CACHE_TTL"), function () use ($ranking) {
                return $ranking;
            });
        }

        return view('ranking.ranking-playersK')->with([
            "data" => $ranking,
            "noPage" => true
        ]);
    }
}
