<?php

declare(strict_types=1);

namespace PHPMax\Exception;

use PHPMax\Protocol\Opcode;

class ApiException extends PHPMaxException
{
     
    private $opcode;
     
    private $error;
     
    private $title;
     
    private $apiMessage;
     
    private $localizedMessage;
     
    private $payload;

    


    public function __construct(
        int $opcode,
        ?string $error = null,
        ?string $title = null,
        ?string $apiMessage = null,
        ?string $localizedMessage = null,
        array $payload = []
    ) {
        $this->opcode = $opcode;
        $this->error = $error;
        $this->title = $title;
        $this->apiMessage = $apiMessage;
        $this->localizedMessage = $localizedMessage;
        $this->payload = $payload;

        parent::__construct($this->buildMessage());
    }

    public function opcode(): int
    {
        return $this->opcode;
    }

    public function error(): ?string
    {
        return $this->error;
    }

    public function title(): ?string
    {
        return $this->title;
    }

    public function apiMessage(): ?string
    {
        return $this->apiMessage;
    }

    public function localizedMessage(): ?string
    {
        return $this->localizedMessage;
    }

    


    public function payload(): array
    {
        return $this->payload;
    }

    




    public function isLoginSessionRejected(): bool
    {
        if ($this->opcode !== Opcode::LOGIN) {
            return false;
        }

        $details = strtoupper(implode(' ', array_filter([
            $this->error,
            $this->apiMessage,
            $this->localizedMessage,
        ], static function ($value): bool {
            return is_string($value) && $value !== '';
        })));

        foreach (['FAIL_LOGIN_TOKEN', 'FAIL_LOGOUT_ALL', 'FAIL_WRONG_PASSWORD', 'LOGIN.CRED'] as $marker) {
            if (strpos($details, $marker) !== false) {
                return true;
            }
        }

        return false;
    }

    private function buildMessage(): string
    {
        $parts = [];
        foreach ([$this->localizedMessage, $this->apiMessage] as $part) {
            if ($part !== null && $part !== '' && !in_array($part, $parts, true)) {
                $parts[] = $part;
            }
        }
        if ($this->title !== null && $this->title !== '') {
            $parts[] = '(' . $this->title . ')';
        }
        if ($this->error !== null && $this->error !== '') {
            $parts[] = '[' . $this->error . ']';
        }

        return $parts !== [] ? implode(' ', $parts) : 'API request failed';
    }
}
