<?php

namespace App\Models;

use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    /** @use HasFactory<UserFactory> */
    use HasFactory, Notifiable, HasApiTokens;

    protected $fillable = [
        'name', 'email', 'password',
        'firebase_uid', 'business_name', 'phone', 'avatar',
        'is_admin', 'is_banned', 'plan', 'plan_expires_at', 'plan_source',
        'storage_used_bytes', 'country_code', 'currency_code', 'last_seen_at',
    ];

    protected $hidden = ['password', 'remember_token'];

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'plan_expires_at' => 'datetime',
            'last_seen_at' => 'datetime',
            'password' => 'hashed',
            'is_admin' => 'boolean',
            'is_banned' => 'boolean',
            'storage_used_bytes' => 'integer',
        ];
    }

    public function stores(): HasMany
    {
        return $this->hasMany(Store::class);
    }

    public function subscriptions(): HasMany
    {
        return $this->hasMany(UserSubscription::class);
    }

    public function devices(): HasMany
    {
        return $this->hasMany(Device::class);
    }

    public function staffUsers(): HasMany
    {
        return $this->hasMany(StaffUser::class);
    }

    public function apiClientKeys(): HasMany
    {
        return $this->hasMany(ApiClientKey::class);
    }

    public function activeSubscription(): ?UserSubscription
    {
        return $this->subscriptions()
            ->where('is_active', true)
            ->where(fn($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now()))
            ->latest()
            ->first();
    }

    public function currentPlan(): string
    {
        // Active subscription record takes highest priority (paid plan)
        $activeSub = $this->activeSubscription();
        if ($activeSub) {
            return $activeSub->plan;
        }
        // Manually-set plan that has explicitly expired reverts to free
        if ($this->plan_expires_at && $this->plan_expires_at->isPast()) {
            return 'free';
        }
        $plan = $this->plan ?? 'free';
        // Map free/trial to starter — no trial period in this app
        if (in_array($plan, ['free', 'trial'], true)) {
            return 'starter';
        }
        return $plan;
    }

    public function currentPlanDetails(): array
    {
        $plan = $this->currentPlan();
        // 'free' and 'trial' have no dedicated config entry — treat as starter.
        if (in_array($plan, ['free', 'trial'], true)) {
            $plan = 'starter';
        }
        return config('quickropos.plans.' . $plan, config('quickropos.plans.starter', []));
    }

    public function planLimit(string $key, mixed $default = null): mixed
    {
        return $this->currentPlanDetails()[$key] ?? $default;
    }

    public function planModules(): array
    {
        return $this->currentPlanDetails()['modules'] ?? [];
    }

    public function hasModule(string $module): bool
    {
        return in_array($module, $this->planModules(), true);
    }
}
