<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, Billable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'role',
        'status',
        'phone',
        'avatar',
        'referral_code',
        'referred_by',
        'paypal_email',
        'paypal_me_link',
        'paypal_enabled',
        'bio',
        'specializations',
        'social_links',
        'years_experience',
        'google_id',
        'google_token',
        'google_refresh_token',
        'google_avatar',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'specializations' => 'array',
            'social_links' => 'array',
        ];
    }

    /**
     * The accessors to append to the model's array form.
     */
    protected $appends = ['avatar_url'];

    /**
     * Get the avatar URL.
     */
    public function getAvatarUrlAttribute(): ?string
    {
        if ($this->avatar) {
            // If avatar is already a full URL
            if (str_starts_with($this->avatar, 'http')) {
                return $this->avatar;
            }
            // If avatar is a storage path
            return asset('storage/' . $this->avatar);
        }
        return null;
    }

    // ===== Relationships =====

    /**
     * Get subscriptions for this coach.
     */
    public function subscriptions(): HasMany
    {
        return $this->hasMany(Subscription::class);
    }

    /**
     * Get the active subscription.
     */
    public function activeSubscription(): HasOne
    {
        return $this->hasOne(Subscription::class)
            ->where('status', 'active')
            ->whereDate('end_date', '>=', now())
            ->latest();
    }

    /**
     * Get clients for this coach.
     */
    public function clients(): HasMany
    {
        return $this->hasMany(Client::class);
    }

    /**
     * Get coach plans created by this coach.
     */
    public function coachPlans(): HasMany
    {
        return $this->hasMany(CoachPlan::class, 'coach_id');
    }

    /**
     * Get payment methods for this coach.
     */
    public function paymentMethods(): HasMany
    {
        return $this->hasMany(CoachPaymentMethod::class, 'coach_id');
    }

    /**
     * Get active payment methods for this coach.
     */
    public function activePaymentMethods(): HasMany
    {
        return $this->paymentMethods()->where('is_active', true)->orderBy('priority');
    }

    /**
     * Get custom foods created by this coach.
     */
    public function customFoods(): HasMany
    {
        return $this->hasMany(Food::class)->where('is_custom', true);
    }

    /**
     * Get invoices for this coach.
     */
    public function invoices(): HasMany
    {
        return $this->hasMany(Invoice::class);
    }

    /**
     * Get orders for this user.
     */
    public function orders(): HasMany
    {
        return $this->hasMany(Order::class);
    }

    /**
     * Get addresses for this user.
     */
    public function addresses(): HasMany
    {
        return $this->hasMany(Address::class);
    }

    // ===== Role Helpers =====

    public function isAdmin(): bool
    {
        return $this->role === 'admin';
    }

    public function isCoach(): bool
    {
        return $this->role === 'coach';
    }

    public function isActive(): bool
    {
        return $this->status === 'active';
    }

    public function isPending(): bool
    {
        return $this->status === 'pending';
    }

    // ===== Subscription Helpers =====

    /**
     * Get current plan or null.
     */
    public function currentPlan(): ?Plan
    {
        return $this->activeSubscription?->plan;
    }

    /**
     * Check if user has an active subscription.
     */
    public function hasActiveSubscription(): bool
    {
        return $this->activeSubscription !== null;
    }

    /**
     * Check if user can create more of a resource.
     */
    public function canCreate(string $resource): bool
    {
        $plan = $this->currentPlan();

        if (!$plan) {
            return false;
        }

        $limit = $plan->getLimit('max_' . $resource);

        // Unlimited
        if ($limit === -1) {
            return true;
        }

        // Count current resources
        $count = match ($resource) {
            'clients' => $this->clients()->count(),
            'diets' => $this->clients()->withCount('mealPlans')->get()->sum('meal_plans_count'),
            'routines' => $this->clients()->withCount('workouts')->get()->sum('workouts_count'),
            default => 0,
        };

        return $count < $limit;
    }

    /**
     * Get remaining count for a resource.
     */
    public function remaining(string $resource): int|string
    {
        $plan = $this->currentPlan();

        if (!$plan) {
            return 0;
        }

        $limit = $plan->getLimit('max_' . $resource);

        if ($limit === -1) {
            return '∞';
        }

        $count = match ($resource) {
            'clients' => $this->clients()->count(),
            'diets' => $this->clients()->withCount('mealPlans')->get()->sum('meal_plans_count'),
            'routines' => $this->clients()->withCount('workouts')->get()->sum('workouts_count'),
            default => 0,
        };

        return max(0, $limit - $count);
    }

    // ===== Scopes =====

    public function scopePending($query)
    {
        return $query->where('status', 'pending');
    }

    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    public function scopeCoaches($query)
    {
        return $query->where('role', 'coach');
    }

    // ===== Advanced Features Relationships =====

    public function wallet(): HasOne
    {
        return $this->hasOne(Wallet::class);
    }

    public function sentMessages(): HasMany
    {
        return $this->hasMany(Message::class, 'sender_id');
    }

    public function receivedMessages(): HasMany
    {
        return $this->hasMany(Message::class, 'receiver_id');
    }

    public function referrer(): BelongsTo
    {
        return $this->belongsTo(User::class, 'referred_by', 'referral_code');
    }

    public function referrals(): HasMany
    {
        return $this->hasMany(User::class, 'referred_by', 'referral_code');
    }

    /**
     * Check if user is a client.
     */
    public function isClient(): bool
    {
        return $this->role === 'client';
    }

    /**
     * Get the client profile associated with this user (if role is client).
     */
    public function clientProfile(): HasOne
    {
        return $this->hasOne(Client::class, 'client_user_id');
    }

    /**
     * Alias for clientProfile - for backward compatibility.
     */
    public function client(): HasOne
    {
        return $this->clientProfile();
    }
    /**
     * Get coach results created by this coach.
     */
    public function coachResults(): HasMany
    {
        return $this->hasMany(CoachResult::class);
    }
}

