<?php

namespace App\Auth;

use App\Services\XenforoService;
use App\XenForoDataTypes\XenForoData;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasName;
use Filament\Panel;
use Illuminate\Contracts\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable;

/**
 * Xenforo user custom model used for authentification.
 *
 * @property-read int $user_id
 * @property-read string $username
 * @property-read int $username_date
 * @property-read int $username_date_visible
 * @property-read string $email
 * @property-read string $custom_title
 * @property-read int $language_id
 * @property-read int $style_id
 * @property-read string $style_variation
 * @property-read string $timezone
 * @property-read int $visible
 * @property-read int $activity_visible
 * @property-read int $user_group_id
 * @property-read array $secondary_group_ids
 * @property-read int $display_style_group_id
 * @property-read int $permission_combination_id
 * @property-read int $message_count
 * @property-read int $question_solution_count
 * @property-read int $conversations_unread
 * @property-read int $register_date
 * @property-read int $last_activity
 * @property-read int $last_summary_email_date
 * @property-read int $trophy_points
 * @property-read int $alerts_unviewed
 * @property-read int $alerts_unread
 * @property-read int $avatar_date
 * @property-read int $avatar_width
 * @property-read int $avatar_height
 * @property-read int $avatar_highdpi
 * @property-read int $avatar_optimized
 * @property-read string $gravatar
 * @property-read string $user_state
 * @property-read string $security_lock
 * @property-read int $is_moderator
 * @property-read int $is_admin
 * @property-read int $is_banned
 * @property-read int $reaction_score
 * @property-read int $vote_score
 * @property-read int $warning_points
 * @property-read int $is_staff
 * @property-read string $secret_key
 * @property-read int $privacy_policy_accepted
 * @property-read int $terms_accepted
 *
 * Custom properties.
 *
 * @property-read int $rhpz_entry_count
 * @property-read int $nsfw_content
 */
class XenForoUser extends XenForoData implements Authenticatable, Authorizable, FilamentUser, HasName {

    use \Illuminate\Foundation\Auth\Access\Authorizable;

    /**
     * Permissions identifier array.
     * @var array|null
     */
    public ?array $permissions = null;

    public function getAuthIdentifierName(): string
    {
        return 'user_id';
    }

    public function getAuthIdentifier(): mixed
    {
        return $this->data->user_id;
    }

    public function getAuthPasswordName(): string
    {
        return 'password';
    }

    public function getAuthPassword(): string
    {
        return '';
    }

    public function getRememberToken(): string
    {
        return '';
    }

    public function setRememberToken($value): void
    {
       return;
    }

    public function getRememberTokenName(): string
    {
        return '';
    }

    /**
     * Get XenForo avatar if it exists.
     *
     * @param string $xfSize s/m/...
     *
     * @return string|null
     */
    public function getAvatarUrl( string $xfSize = 'm' ): ?string
    {
        $userId = $this->data->user_id;
        $avatarDate = $this->data->avatar_date;

        if( $avatarDate ){
            $group = floor($userId / 1000);
            return config('app.forum_url') . "/data/avatars/{$xfSize}/{$group}/{$userId}.jpg?{$avatarDate}";
        }

        return null;
    }

    /**
     * Custom can function. Check XF user permissions.
     *
     * @param string $permissionGroup
     * @param string $permissionName
     *
     * @return bool
     */
    public function _can(string $permissionGroup, string $permissionName): bool
    {
        if( !$this->permissions ){
            $this->permissions = $this->services->getPermissions($this->data->user_id, $this->data->permission_combination_id);
        }

        return ($this->permissions[$permissionGroup][$permissionName] ?? 0) === true;
    }

    /* FILAMENT COMPATIBILITY */

    public function canAccessPanel(Panel $panel): bool
    {
        return $this->is_admin === 1;
    }

    public function getFilamentName(): string
    {
        return $this->username ?? "XF";
    }

    public function getAttributeValue($key)
    {
        return $this->{$key} ?? null;
    }

    public function getKey()
    {
        return $this->data->user_id;
    }

    public function getKeyName()
    {
        return 'user_id';
    }

    public function validState(): bool
    {
        return $this->user_state === 'valid';
    }
}
