<?php

namespace App\Services\PwApi\Faction;

class FactionService extends \App\Services\PwApi\Core\PwApiService
{
    public function addFaction($roleid, $name, $fid)
    {
        $pack = pack('N*', -1).$this->gamed->packString($name).pack('NN', $roleid, $fid);
        $pack = $this->gamed->createHeader($this->data['code']['AddFaction'], $pack);

        return $this->gamed->SendToGamedBD($pack);
    }

    public function delFaction($fid)
    {
        $pack = pack('N*', -1, $fid);
        $pack = $this->gamed->createHeader($this->data['code']['DelFaction'], $pack);

        return $this->gamed->SendToGamedBD($pack);
    }

    public function upgradeFaction($roleid, $fid, $level)
    {
        $pack = pack('N*', -1, $fid, $roleid, 0).pack('C', $level);
        $pack = $this->gamed->createHeader($this->data['code']['FactionUpgrade'], $pack);

        return $this->gamed->SendToGamedBD($pack);
    }

    public function getFactionInfo($id)
    {
        $pack = pack('N*', -1, $id);
        $pack = $this->gamed->createHeader($this->data['code']['getFactionInfo'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);

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

    public function getFactionDetail($id)
    {
        $pack = pack('N*', -1, $id);
        $pack = $this->gamed->createHeader($this->data['code']['getFactionDetail'], $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);

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

    public function getFactionDetails($id)
    {
        $detail = $this->getFactionDetail($id);
        if (! $detail || ! isset($detail['fid']) || $detail['fid'] == 0 || empty($detail['name'])) {
            return null;
        }

        $members = [];
        $master = null;
        $rawMembers = $detail['member'] ?? [];

        foreach ($rawMembers as $m) {
            $member = [
                'role_id' => $m['roleid'] ?? 0,
                'name' => $m['name'] ?? '',
                'level' => $m['level'] ?? 0,
                'cls' => $m['occupation'] ?? 0,
                'faction_role' => $m['froleid'] ?? 6,
                'is_online' => ($m['online_status'] ?? 0) == 1,
            ];
            $members[] = $member;

            if ($member['faction_role'] == 2) {
                $master = $member;
            }
        }

        return [
            'id' => $detail['fid'],
            'name' => $detail['name'],
            'level' => $detail['level'] ?? 0,
            'announce' => $detail['announce'] ?? '',
            'member_count' => count($members),
            'master' => $master,
            'members' => $members,
        ];
    }

    public function getFactionFortressDetail($id)
    {
        /*$pack = pack("N*", -1, $id);
        $pack = $this->gamed->createHeader(config('code.GFactionFortressDetail'), $pack);
        $send = $this->gamed->SendToGamedBD($pack);
        $data = $this->gamed->deleteHeader($send);
        return $this->gamed->unmarshal($data, config('FactionFortressDetail'));*/
    }

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

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

    public function searchFactions($search, $limit = 20)
    {
        if (empty(trim($search)) || strlen(trim($search)) < 2) {
            return [];
        }

        $search = trim($search);
        $results = [];
        $maxFactionId = 500;
        $notFoundCount = 0;
        $maxNotFound = 50;

        for ($fid = 1; $fid <= $maxFactionId && count($results) < $limit; $fid++) {
            $factionInfo = $this->getFactionInfo($fid);

            if ($factionInfo && isset($factionInfo['fid']) && $factionInfo['fid'] > 0 && ! empty($factionInfo['name'])) {
                $notFoundCount = 0;
                $factionName = $factionInfo['name'];

                if (stripos($factionName, $search) !== false) {
                    $results[] = [
                        'id' => $factionInfo['fid'],
                        'name' => $factionName,
                    ];
                }
            } else {
                $notFoundCount++;
                if ($notFoundCount >= $maxNotFound) {
                    break;
                }
            }
        }

        return $results;
    }
}
