<?php

namespace App\Services\PwApi\Role;

class RoleService extends \App\Services\PwApi\Core\PwApiService
{
    public function getRole($role)
    {
        if (config('pw-api.game_version') == '07') {
            $user['base'] = $this->getRoleBase($role);
            $user['status'] = $this->getRoleStatus($role);
            $user['pocket'] = $this->getRoleInventory($role);
            $user['equipment'] = $this->getRoleEquipment($role);
            $user['storehouse'] = $this->getRoleStorehouse($role);
            $user['task'] = $this->getRoleTask($role);
        } else {
            $pack = pack('N*', -1, $role);
            $pack = $this->gamed->createHeader($this->data['code']['getRole'], $pack);
            $send = $this->gamed->SendToGamedBD($pack);
            $data = $this->gamed->deleteHeader($send);
            $user = $this->gamed->unmarshal($data, $this->data['role']);

            if (! is_array($user)) {
                $user['base'] = $this->getRoleBase($role);
                $user['status'] = $this->getRoleStatus($role);
                $user['pocket'] = $this->getRoleInventory($role);
                $user['equipment'] = $this->getRoleEquipment($role);
                $user['storehouse'] = $this->getRoleStorehouse($role);
                $user['task'] = $this->getRoleTask($role);
            }
        }

        return $user;
    }

    public function getRoleBase($role): ?array
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleBase'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['base']);

        return is_array($user) ? $user : null;
    }

    public function getRoleStatus($role): ?array
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleStatus'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['status']);

        return is_array($user) ? $user : null;
    }

    public function getRoleInventory($role)
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleInventory'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['pocket']);

        return $user;
    }

    public function getRoleEquipment($role)
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleEquipment'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['equipment']);

        return $user;
    }

    public function getRolePetBadge($role)
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader(3088, $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['pocket']['petbadge']);

        return $user;
    }

    public function getRoleStorehouse($role)
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleStoreHouse'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $store = $this->gamed->unmarshal($data, $this->data['role']['storehouse']);

        return $store;
    }

    public function getRoleTask($role)
    {
        $pack = pack('N*', -1, $role);
        $pack = $this->gamed->createHeader($this->data['code']['getRoleTask'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, $this->data['role']['task']);

        return $user;
    }

    public function getJdRole($role)
    {
        /*$pack = pack("N*", -1, $role);
        $pack = $this->gamed->createHeader(config('code.getRole'), $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $user = $this->gamed->unmarshal($data, config('role'));

        return $user;*/
    }

    public function getRoles($userID)
    {
        $pack = pack('N*', -1, $userID);
        $pack = $this->gamed->createHeader(3401, $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        $roles = $this->gamed->unmarshal($data, $this->data['user']['roles']);

        return $roles;
    }

    public function getUser($id)
    {
        $pack = pack('N*', -1, $id, 1, 1);
        $data = $this->gamed->cuint($this->data['code']['getUser']).$this->gamed->cuint(strlen($pack)).$pack;
        $send = $this->gamed->SendToGamedBD($data);
        $strlarge = unpack('H', substr($send, 2, 1));
        if (substr($strlarge[1], 0, 1) == 8) {
            $tmp = 12;
        } else {
            $tmp = 11;
        }
        $send = substr($send, $tmp);
        $user = $this->gamed->unmarshal($send, $this->data['user']['info']);
        $user['login_ip'] = $this->gamed->getIp($this->gamed->reverseOctet(substr($user['login_record'], 8, 8)));
        $user['login_time'] = $this->gamed->getTime(substr($user['login_record'], 0, 8));

        return $user;
    }

    public function getJdUser($id)
    {
        /*$pack = pack("N*", -1, $id);
        $data = $this->gamed->SendToGamedBD($this->gamed->createHeader(config('code.getUser'), $pack));
        $send = $this->gamed->SendToGamedBD($data);
        return $this->gamed->unmarshal($data, config('user.info'));*/
    }

    public function putRole($role, $params)
    {
        if (isset($params['equipment']['eqp']['id'])) {
            $tmp = $params['equipment']['eqp'];
            $params['equipment']['eqp'] = [];
            $params['equipment']['eqp'][] = $tmp;
        }
        if (isset($params['pocket']['inv']['id'])) {
            $tmp = $params['pocket']['inv'];
            $params['pocket']['inv'] = [];
            $params['pocket']['inv'][] = $tmp;
        }
        if (isset($params['storehouse']['store']['id'])) {
            $tmp = $params['storehouse']['store'];
            $params['storehouse']['store'] = [];
            $params['storehouse']['store'][] = $tmp;
        }
        if (isset($params['task']['task_inventory']['id'])) {
            $tmp = $params['task']['task_inventory'];
            $params['task']['task_inventory'] = [];
            $params['task']['task_inventory'][] = $tmp;
        }
        if (isset($params['storehouse']['dress']['id'])) {
            $tmp = $params['storehouse']['dress'];
            $params['storehouse']['dress'] = [];
            $params['storehouse']['dress'][] = $tmp;
        }
        if (isset($params['storehouse']['material']['id'])) {
            $tmp = $params['storehouse']['material'];
            $params['storehouse']['material'] = [];
            $params['storehouse']['material'][] = $tmp;
        }
        if (config('pw-api.game_version') != '07') {
            $pack = pack('NNC*', -1, $role, 1).$this->gamed->marshal($params, $this->data['role']);

            return $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRole'], $pack));
        } else {
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['base'], $this->data['role']['base']);
            $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleBase'], $pack));
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['status'], $this->data['role']['status']);
            $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleStatus'], $pack));
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['pocket'], $this->data['role']['pocket']);
            $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleInventory'], $pack));
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['equipment'], $this->data['role']['equipment']);
            $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleEquipment'], $pack));
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['storehouse'], $this->data['role']['storehouse']);
            $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleStoreHouse'], $pack));
            $pack = pack('NNC*', -1, $role).$this->gamed->marshal($params['task'], $this->data['role']['task']);

            return $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleTask'], $pack));
        }
    }

    public function putRoleInventory($role, $params)
    {
        $data = '';

        $data .= pack('N', isset($params['icapacity']) ? $params['icapacity'] : 0);
        $data .= pack('N', isset($params['timestamp']) ? $params['timestamp'] : 0);
        $data .= pack('N', isset($params['money']) ? $params['money'] : 0);

        $items = [];
        if (isset($params['inv'])) {
            if (isset($params['inv']['id'])) {
                $items[] = $params['inv'];
            } elseif (is_array($params['inv'])) {
                $items = $params['inv'];
            }
        }

        $data .= $this->gamed->cuint(count($items));

        foreach ($items as $item) {
            $data .= pack('N', isset($item['id']) ? $item['id'] : 0);
            $data .= pack('N', isset($item['pos']) ? $item['pos'] : 0);
            $data .= pack('N', isset($item['count']) ? $item['count'] : 0);
            $data .= pack('N', isset($item['max_count']) ? $item['max_count'] : 0);

            $itemData = isset($item['data']) ? $item['data'] : '';
            if (ctype_xdigit($itemData)) {
                $binData = hex2bin($itemData);
            } else {
                $binData = $itemData;
            }
            $data .= $this->gamed->cuint(strlen($binData)).$binData;

            $data .= pack('N', isset($item['proctype']) ? $item['proctype'] : 0);
            $data .= pack('N', isset($item['expire_date']) ? $item['expire_date'] : 0);
            $data .= pack('N', isset($item['guid1']) ? $item['guid1'] : 0);
            $data .= pack('N', isset($item['guid2']) ? $item['guid2'] : 0);
            $data .= pack('N', isset($item['mask']) ? $item['mask'] : 0);
        }

        $data .= pack('N', isset($params['reserved6']) ? $params['reserved6'] : 0);
        $data .= pack('N', isset($params['reserved7']) ? $params['reserved7'] : 0);

        $pack = pack('NNC*', -1, $role).$data;

        return $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['putRoleInventory'], $pack));
    }

    public function putJdRole($role, $params)
    {
        /*$pack = pack("NNC*", -1, $role, 1).$this->gamed->marshal($params, config('role'));
        $this->gamed->SendToGamedBD($this->gamed->createHeader(config('code.putRole'), $pack));

        return true;*/
    }

    public function getRoleid($rolename)
    {
        $pack = pack('N', -1).$this->gamed->packString($rolename).pack('C', 1);
        $data = $this->gamed->deleteHeader($this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['getRoleid'], $pack)));
        $var = unpack('l', $data);
        if ($var[1] !== -1) {
            $var = unpack('N', $data);
        }

        return $var[1];
    }

    public function renameRole($role, $oldname, $newname)
    {
        $pack = pack('N*', -1, $role).$this->gamed->packString($oldname).$this->gamed->packString($newname);

        return $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['renameRole'], $pack));
    }

    public function getRoleFriends($role)
    {
        $tmp = 0;
        $pack = pack('N*', -1, $role);
        $data = $this->gamed->SendToGamedBD($this->gamed->createHeader($this->data['code']['getRoleFriend'], $pack));
        $this->gamed->unpackCuint($data, $tmp);
        $this->gamed->unpackCuint($data, $tmp);
        $data = substr($data, $tmp + 5);

        return $this->gamed->unmarshal($data, $this->data['FriendList']);
    }

    public function generateSkill($params = [])
    {
        $skills = substr($params['skills'], 8);
        $id = isset($params['id']) ? dechex($params['id']) : 1;
        $level = isset($params['level']) ? dechex($params['level']) : 1;
        $progress = isset($params['progress']) ? dechex($params['progress']) : 0;
        $skills .= $this->gamed->reverseOctet($this->gamed->hex2octet($id));
        $skills .= $this->gamed->reverseOctet($this->gamed->hex2octet($progress));
        $skills .= $this->gamed->reverseOctet($this->gamed->hex2octet($level));
        $count = dechex(strlen($skills) / 24);
        $skills = $this->gamed->reverseOctet($this->gamed->hex2octet($count)).$skills;

        return $skills;
    }

    public function getUserIp($user_id)
    {
        $pack = pack('N*', -1, 0, $user_id);

        return $this->gamed->SendToDelivery($this->gamed->createHeader(35, $pack));
    }
}
