<?php

namespace App\Models\Mangboard;

use App\Entities\Mangboard\UserEntity;
use App\Models\CommonModel;

// +-------------------+----------------------+------+-----+---------------------+----------------+
// | Field             | Type                 | Null | Key | Default             | Extra          |
// +-------------------+----------------------+------+-----+---------------------+----------------+
// | pid               | int(10) unsigned     | NO   | PRI | NULL                | auto_increment |
// | wp_user_pid       | int(10) unsigned     | NO   |     | 0                   |                |
// | user_id           | varchar(150)         | NO   | UNI |                     |                |
// | passwd            | varchar(255)         | NO   |     |                     |                |
// | user_name         | varchar(100)         | NO   |     |                     |                |
// | user_state        | varchar(255)         | NO   |     |                     |                |
// | user_level        | tinyint(3) unsigned  | NO   |     | 1                   |                |
// | user_group        | varchar(255)         | NO   | MUL | home                |                |
// | user_platform     | varchar(100)         | NO   |     | mb                  |                |
// | user_email        | varchar(255)         | NO   |     |                     |                |
// | user_point        | int(10) unsigned     | NO   |     | 0                   |                |
// | user_money        | int(10) unsigned     | NO   |     | 0                   |                |
// | user_coin         | int(10) unsigned     | NO   |     | 0                   |                |
// | payment_count     | smallint(5) unsigned | NO   |     | 0                   |                |
// | payment_total     | int(10) unsigned     | NO   |     | 0                   |                |
// | user_birthday     | varchar(50)          | NO   |     |                     |                |
// | user_phone        | varchar(50)          | NO   |     |                     |                |
// | user_picture      | varchar(255)         | NO   |     |                     |                |
// | user_icon         | varchar(255)         | NO   |     |                     |                |
// | user_messenger    | varchar(255)         | NO   |     |                     |                |
// | user_homepage     | varchar(255)         | NO   |     |                     |                |
// | user_blog         | varchar(255)         | NO   |     |                     |                |
// | user_sex          | tinyint(3)           | NO   |     | 0                   |                |
// | home_postcode     | varchar(20)          | NO   |     |                     |                |
// | home_address1     | varchar(255)         | NO   |     |                     |                |
// | home_address2     | varchar(255)         | NO   |     |                     |                |
// | home_tel          | varchar(50)          | NO   |     |                     |                |
// | office_postcode   | varchar(20)          | NO   |     |                     |                |
// | office_address1   | varchar(255)         | NO   |     |                     |                |
// | office_address2   | varchar(255)         | NO   |     |                     |                |
// | office_tel        | varchar(50)          | NO   |     |                     |                |
// | office_fax        | varchar(50)          | NO   |     |                     |                |
// | company_name      | varchar(255)         | NO   |     |                     |                |
// | job_title         | varchar(255)         | NO   |     |                     |                |
// | gps_latitude      | decimal(10,8)        | NO   |     | 0.00000000          |                |
// | gps_longitude     | decimal(11,8)        | NO   |     | 0.00000000          |                |
// | allow_mailing     | tinyint(3) unsigned  | NO   | MUL | 1                   |                |
// | allow_message     | tinyint(3) unsigned  | NO   |     | 1                   |                |
// | allow_push        | tinyint(3) unsigned  | NO   |     | 1                   |                |
// | allow_sms         | tinyint(3) unsigned  | NO   |     | 1                   |                |
// | followers         | int(10) unsigned     | NO   |     | 0                   |                |
// | following         | int(10) unsigned     | NO   |     | 0                   |                |
// | new_memo          | smallint(5) unsigned | NO   |     | 0                   |                |
// | login_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | write_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | reply_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | comment_count     | int(10) unsigned     | NO   |     | 0                   |                |
// | send_count        | int(10) unsigned     | NO   |     | 0                   |                |
// | api_count         | int(10) unsigned     | NO   |     | 0                   |                |
// | item1_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | item2_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | item3_count       | int(10) unsigned     | NO   |     | 0                   |                |
// | review_count      | int(10) unsigned     | NO   |     | 0                   |                |
// | review_star_sum   | int(10) unsigned     | NO   |     | 0                   |                |
// | reg_mail          | tinyint(3)           | NO   |     | 0                   |                |
// | reg_phone         | tinyint(3)           | NO   |     | 0                   |                |
// | push_pid          | int(10) unsigned     | NO   |     | 0                   |                |
// | reg_date          | datetime             | NO   | MUL | 0000-00-00 00:00:00 |                |
// | last_login        | datetime             | NO   | MUL | 0000-00-00 00:00:00 |                |
// | user_memo         | varchar(255)         | NO   |     |                     |                |
// | admin_memo        | varchar(255)         | NO   |     |                     |                |
// | recommender_id    | varchar(255)         | NO   |     |                     |                |
// | user_auth_key     | varchar(255)         | NO   |     |                     |                |
// | user_access_token | varchar(255)         | NO   |     |                     |                |
// | ext1              | varchar(255)         | NO   |     |                     |                |
// | ext2              | varchar(255)         | NO   |     |                     |                |
// | ext3              | varchar(255)         | NO   |     |                     |                |
// | ext4              | varchar(255)         | NO   |     |                     |                |
// | ext5              | varchar(255)         | NO   |     |                     |                |
// | ext6              | varchar(255)         | NO   |     |                     |                |
// | ext7              | varchar(255)         | NO   |     |                     |                |
// | ext8              | varchar(255)         | NO   |     |                     |                |
// | ext9              | varchar(255)         | NO   |     |                     |                |
// | ext10             | varchar(255)         | NO   |     |                     |                |
// | ext11             | varchar(255)         | NO   |     |                     |                |
// | ext12             | varchar(255)         | NO   |     |                     |                |
// | ext13             | varchar(255)         | NO   |     |                     |                |
// | ext14             | varchar(255)         | NO   |     |                     |                |
// | ext15             | varchar(255)         | NO   |     |                     |                |
// | ext16             | varchar(255)         | NO   |     |                     |                |
// | ext17             | varchar(255)         | NO   |     |                     |                |
// | ext18             | varchar(255)         | NO   |     |                     |                |
// | ext19             | varchar(255)         | NO   |     |                     |                |
// | ext20             | varchar(255)         | NO   |     |                     |                |
// +-------------------+----------------------+------+-----+---------------------+----------------+

class UserModel extends CommonModel
{
    protected $table            = 'mb_users';
    protected $primaryKey       = 'pid';
    protected $returnType       = UserEntity::class;
    protected $allowedFields = [
        "user_id",
        "passwd",
        "user_name",
        "user_email",
        "user_state",
        "user_level",
        "user_point"
    ];
    public function __construct()
    {
        parent::__construct();
    }
    public function getTitleField(): string
    {
        return 'user_name';
    }
    public function getFieldRule(string $field, array $rules): array
    {
        switch ($field) {
            case "user_id":
            case "passwd":
                $rules[$field] =  "required|trim|string";
                break;
            case "user_state":
                $rules[$field] =  "if_exist|trim|string";
                break;
            case "user_email":
                $rules[$field] =  "if_exist|trim|valid_email";
                break;
            case "user_level":
            case "user_point":
                $rules[$field] =  "if_exist|numeric";
                break;
            default:
                $rules = parent::getFieldRule($field, $rules);
                break;
        }
        return $rules;
    }

    public function getEntityByPK(int $uid): null|UserEntity
    {
        $this->where($this->getPKField(), $uid);
        return $this->getEntity();
    }
    public function getEntityByID(string $id): null|UserEntity
    {
        $this->where('user_id', $id);
        return $this->getEntity();
    }
    public function getEntityByLoginCheck(string $id, string $password): null|UserEntity
    {
        $this->where('user_id', $id);
        $this->where('passwd', password_hash($password, PASSWORD_DEFAULT));
        return $this->getEntity();
    }

    private function getLevelByPoint(UserEntity $entity): int
    {
        //Admin용 Level로는 변경불가
        if ($entity->getLevel() == getenv('mangboard.admin.level')) {
            log_message("notice", "Admin용 Level을 변경하실수 없습니다.");
            return $entity->getLevel();
        }

        //사용자 Point별 Level 계산
        $levelup_point = getenv('mangboard.level.up.point.unit');
        $level = intval($entity->getPoint() / $levelup_point * $levelup_point / $levelup_point);

        //운영자면 7~9
        if (getenv('mangboard.level.manager.min') <= $level && $level <= getenv('mangboard.level.manager.max')) {
            $level = $level < getenv('mangboard.level.manager.min') ? getenv('mangboard.level.manager.min') : $level;
            $level = getenv('mangboard.level.manager.max') < $level ? getenv('mangboard.level.manager.max') : $level;
        }
        // echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";

        //사용자 Level 1~5;
        if (getenv('mangboard.level.user.min') <= $level && $level <= getenv('mangboard.level.user.max')) {
            $level = $level < getenv('mangboard.level.user.min') ? getenv('mangboard.level.user.min') : $level;
            $level = getenv('mangboard.level.user.max') < $level ? getenv('mangboard.level.user.max') : $level;
        }
        // echo "point:" . $entity->getPoint() . ",level:" . $level . "\n";
        return $level;
    }

    public function setPoint(UserEntity $entity, int $point, $sign = '+'): UserEntity
    {
        switch ($sign) {
            case '-':
                if ($point < $point) {
                    throw new \Exception("기존포인트:{$point}가 감소 포인트:-{$point} 작습니다.\n");
                }
                $point = $point - $point;
                break;
            case '+':
                $point = $point + $point;
                break;
            default:
                throw new \Exception(__FUNCTION__ . "에서는 {$sign}은 사용할수 없습니다.\n");
                // break;
        }

        //기존정보와 Point값이 다르면 저장
        if ($entity->getPoint() != $point) {
            $formDatas = ["point" => $point];
            $entity = $this->modify($entity, $formDatas);
            log_message("notice", __FUNCTION__ . "=>{$entity->getTitle()}님의 Point가 {$entity->getPoint()}에서 {$point}로 변경되었습니다.");
        }
        return $this->setLevel($entity, $this->getLevelByPoint($entity));
    }
    public function setLevel(UserEntity $entity, int $level): UserEntity
    {
        //기존정보와 Level값이 다르면 저장
        if ($entity->getLevel() != $level) {
            $formDatas = ["level" => $level];
            $entity = $this->modify($entity, $formDatas);
            log_message("notice", __FUNCTION__ . "=>{$entity->getTitle()}님의 Level이 {$entity->getLevel()}에서 {$level}로 변경되었습니다.");
        }
        return $entity;
    }

    //create용
    public function create(array $formDatas = []): UserEntity
    {
        return $this->create_process(new UserEntity(), $formDatas);
    }
    //modify용
    public function modify(UserEntity $entity, array $formDatas): UserEntity
    {
        return $this->modify_process($entity, $formDatas);
    }
}
