<?php

namespace App\Http\Controllers\CFP\GM;

use App\Models\Game\CF_MEMBER;
use App\Models\Game\CF_USER;
use App\Models\Web\CF_WEB_CHANGE_LOG;
use App\Tools\Helper;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class SharedController extends Controller
{
    public function doChanges (Request $request, $change)
    {
        if (!$request->hasValidSignature()) {
            return response()->json(["result" => false, "reason" => "Oops, o token expirou, atualize a página e tente novamente."]);
        }

        if (!$request->ajax()) {
            return response()->json(["result" => false, "reason" => "Oops, requisição inválida."]);
        }

        $value = $request->input("value");
        $no_check = $request->input("no-check", false);
        if (empty($value) && !$no_check) {
            return response()->json(["result" => false, "reason" => "Oops, o novo valor não pode ficar em branco! {$value}"]);
        }

        $usn = $request->input("usn");
        switch ($change)
        {
            case "password": {
                return $this->ChangeAccountPassword($usn, $value);
            }
            case "email": {
                return $this->ChangeAccountEmail($usn, $value);
            }
            case "title": {
                return $this->ChangeAccountTitle($usn, $value);
            }
            case "nick": {
                return $this->ChangeCharNick($usn, $value);
            }
            case "authority": {
                return $this->ChangeCharAuthority($usn, $value);
            }
            case "level": {
                return $this->ChangeCharLevel($usn, $value, $request->input("checkbox", false));
            }
            default: {
                return response()->json(["result" => false, "reason" => "Requisição inválida!"]);
            }
        }
    }

    public function doAdd (Request $request, $add)
    {
        if (!$request->hasValidSignature()) {
            return response()->json(["result" => false, "reason" => "Oops, o token expirou, atualize a página e tente novamente."]);
        }

        if (!$request->ajax()) {
            return response()->json(["result" => false, "reason" => "Oops, requisição inválida."]);
        }

        $value = $request->input("value");
        $no_check = $request->input("no-check", false);
        if (empty($value) && !$no_check) {
            return response()->json(["result" => false, "reason" => "Oops, o novo valor não pode ficar em branco! {$value}"]);
        }

        $usn = $request->input("usn");
        switch ($add)
        {
            default: {
                return response()->json(["result" => false, "reason" => "Requisição inválida!"]);
            }
        }
    }

    /** private helpers */

    private function ChangeAccountPassword($usn, $value)
    {
        $user = CF_MEMBER::where("USN", $usn)->first(["USN", "USER_ID", "AUTHORITY_LEV"]);
        if ($user != null)
        {
            if (($this->user_data->AUTHORITY_LEV <= $user->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, seu nível de permissão é menor ou igual a do usuário."]);
            }

            $new_password = md5($value . env("APP_SALT"));

            $result = \Helper::db_execStoredProcedure("cf_game", "PROC_WEB_USER_INFO_UPD", "?, ?, ?", "@p_Result",
                [$user->USER_ID, $new_password, 'P']
            );
            switch($result)
            {
                case 0: {
                    return response()->json(["result" => true, "reason" => "Tudo certo, a senha foi atualizada com sucesso!"]);
                }
                case -1: {
                    return response()->json(["result" => false, "reason" => "Oops, não encontramos o ID, tente novamente ou entre em contato com um dev."]);
                }
                case -2:
                default: {
                    return response()->json(["result" => false, "reason" => "Oops, erro desconhecido, entre em contato com um dev."]);
                }
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
        }
    }

    private function ChangeAccountEmail($usn, $value)
    {
        $user = CF_MEMBER::where("USN", $usn)->first(["USN", "USER_ID", "AUTHORITY_LEV"]);
        if ($user != null)
        {
            if (($this->user_data->AUTHORITY_LEV <= $user->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, seu nível de permissão é menor ou igual a do usuário."]);
            }

            $result = \Helper::db_execStoredProcedure("cf_game", "PROC_WEB_USER_INFO_UPD", "?, ?, ?", "@p_Result",
                [$user->USER_ID, $value, 'E']
            );
            switch($result)
            {
                case 0: {
                    return response()->json(["result" => true, "reason" => "Tudo certo, o e-mail foi atualizado com sucesso!", "reload" => true]);
                }
                case -1: {
                    return response()->json(["result" => false, "reason" => "Oops, não encontramos o ID, tente novamente ou entre em contato com um dev."]);
                }
                case -2:
                default: {
                    return response()->json(["result" => false, "reason" => "Oops, erro desconhecido, entre em contato com um dev."]);
                }
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
        }
    }

    private function ChangeAccountTitle($usn, $value)
    {
        $user = CF_MEMBER::where("USN", $usn)->first(["USN", "USER_ID", "AUTHORITY_LEV"]);
        if ($user != null)
        {
            if (($this->user_data->AUTHORITY_LEV <= $user->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, seu nível de permissão é menor ou igual a do usuário."]);
            }

            $result = \Helper::db_execStoredProcedure("cf_web", "WSP_USER_BADGE_UPD", "?, ?", "@p_Result",
                [$user->USN, $value]
            );
            switch($result)
            {
                case 1: {
                    return response()->json(["result" => true, "reason" => "Tudo certo, o título foi alterado com sucesso!"]);
                }
                case -1: {
                    return response()->json(["result" => false, "reason" => "Oops, falha ao inserir o título, entre em contato com um dev."]);
                }
                case -2: {
                    return response()->json(["result" => false, "reason" => "Oops, falha ao atualizar o título, entre em contato com um dev."]);
                }
                case -99:
                default: {
                    return response()->json(["result" => false, "reason" => "Oops, erro desconhecido, entre em contato com um dev."]);
                }
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
        }
    }

    private function ChangeCharNick($usn, $value)
    {
        $user = CF_USER::where("USN", $usn)->with("member:USN,AUTHORITY_LEV")->first(["USN", "NICK"]);
        if ($user != null)
        {
            /*if (($this->user_data->AUTHORITY_LEV <= $user->member->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, seu nível de permissão é menor ou igual a do usuário."]);
            }*/

            $result = \Helper::db_execStoredProcedure("cf_game", "SP_USE_CHANGE_NICK", "?, ?, ?, ?, ?", "@p_Result",
                [$user->USN, $user->NICK, $value, -907, -907]
            );
            switch($result)
            {
                case 1: {
                    return response()->json(["result" => true, "reason" => "Alright, nickname changed successfully!", "reload" => true]);
                }
                case -1: {
                    return response()->json(["result" => false, "reason" => "Oops, this nickname is already in use."]);
                }
                case -2: {
                    return response()->json(["result" => false, "reason" => "Oops, a fail occured while nickname change, contact dev team."]);
                }
                case -3: {
                    return response()->json(["result" => false, "reason" => "Oops, we've failed to generate the log, contact dev team."]);
                }
                case -99:
                default: {
                    return response()->json(["result" => false, "reason" => "Oops, unknown error, contact dev team."]);
                }
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, we cannot find this user."]);
        }
    }

    private function ChangeCharAuthority($usn, $value)
    {
        if ($this->user_data->AUTHORITY_LEV < 3) {
            return abort(403);
        }

        $authorityArr = ["N", "G"];
        if (!in_array($value, $authorityArr)) {
            return response()->json(["result" => false, "reason" => "Oops, a autoridade é inválida, escolha uma da lista."]);
        }

        $user = CF_USER::where("USN", $usn)->with("member:USN,AUTHORITY_LEV")->first(["USN", "NICK", "AUTHORITY"]);
        if ($user != null)
        {
            if (($this->user_data->AUTHORITY_LEV <= $user->member->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, you authority is lesser or equal as the user."]);
            }

            if (strcmp($user->AUTHORITY, $value) == 0) {
                return response()->json(["result" => true, "reason" => "All good, but nothing has changed because authority is the same."]);
            }

            $newAuthority = $value == 'G' ? "GM" : "Normal";

            $user->AUTHORITY = strtoupper($value);
            if ($user->save())
            {
                return response()->json(["result" => true, "reason" => "Alright, authority changed to '{$newAuthority}' successfully!", "reload" => true]);
            } else {
                return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
        }
    }

    private function ChangeCharLevel($usn, $level, $giveExp)
    {
        if (!in_array($level, range(0, 100)) || empty($level)) {
            return response()->json(["result" => false, "reason" => "Oops, o level é inválido, escolha um da lista."]);
        }

        $user = CF_USER::where("USN", $usn)->with("member:USN,AUTHORITY_LEV")->first(["USN", "NICK", "LEV"]);
        if ($user != null)
        {
            if (($this->user_data->AUTHORITY_LEV <= $user->member->AUTHORITY_LEV) && $this->user_data->USN != $user->USN) {
                return response()->json(["result" => false, "reason" => "Oops, seu nível de permissão é menor ou igual a do usuário."]);
            }

            if (strcmp($user->LEV, $level) == 0) {
                return response()->json(["result" => true, "reason" => "Tudo certo, porém nada foi alterado pois o level é o mesmo."]);
            }

            $flag = $giveExp ? 'E' : 'L';
            $result = \Helper::db_execStoredProcedure("cf_web", "WSP_GIVE_CURRENCY", "?, ?, ?, ?", "@p_Result",
                [$usn, $this->user_data->USN, $flag, $level]
            );

            switch($result)
            {
                case 0: {
                    return response()->json(["result" => true, "reason" => "Tudo certo, a patente de '{$user->NICK}' foi alterada para '". \Helper::web_getCharLevelName($level) ."' com sucesso!</br>O EXP " . ($giveExp ? "<strong class=text-success>foi alterado</strong>" : "<strong class=text-warning>não foi alterado</strong>") . ".", "reload" => true]);
                }
                case -99:
                default: {
                    return response()->json(["result" => false, "reason" => "Oops, ocorreu um erro, entre em contato com um dev."]);
                }
            }
        } else {
            return response()->json(["result" => false, "reason" => "Oops, não encontramos o usuário, tente novamente."]);
        }
    }
}
