<?php

namespace App\Models;

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

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

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * 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',
        ];
    }

    /**
     * Get user settings.
     */
    public function settings(): HasOne
    {
        return $this->hasOne(UserSetting::class);
    }

    /**
     * Get or create user settings.
     */
    public function getSettings(): UserSetting
    {
        return UserSetting::getOrCreate($this->id);
    }

    /**
     * Get user's accounts.
     */
    public function accounts(): HasMany
    {
        return $this->hasMany(Account::class)->orderBy('sort_order');
    }

    /**
     * Get user's active accounts.
     */
    public function activeAccounts(): HasMany
    {
        return $this->accounts()->where('is_active', true);
    }

    /**
     * Get user's transactions.
     */
    public function transactions(): HasMany
    {
        return $this->hasMany(Transaction::class)->orderBy('date', 'desc');
    }

    /**
     * Get user's transfers.
     */
    public function transfers(): HasMany
    {
        return $this->hasMany(Transfer::class)->orderBy('date', 'desc');
    }

    /**
     * Get user's categories (custom + system).
     */
    public function categories(): HasMany
    {
        return $this->hasMany(Category::class);
    }

    /**
     * Get all available categories for user (custom + system).
     */
    public function availableCategories()
    {
        return Category::forUser($this->id)->active()->orderBy('sort_order');
    }

    /**
     * Get user's tags.
     */
    public function tags(): HasMany
    {
        return $this->hasMany(Tag::class);
    }

    /**
     * Get user's budgets.
     */
    public function budgets(): HasMany
    {
        return $this->hasMany(Budget::class);
    }

    /**
     * Get user's active budgets.
     */
    public function activeBudgets(): HasMany
    {
        return $this->budgets()->where('is_active', true);
    }

    /**
     * Get user's goals.
     */
    public function goals(): HasMany
    {
        return $this->hasMany(Goal::class);
    }

    /**
     * Get user's active goals.
     */
    public function activeGoals(): HasMany
    {
        return $this->goals()->where('status', 'active');
    }

    /**
     * Get user's recurring transactions.
     */
    public function recurringTransactions(): HasMany
    {
        return $this->hasMany(RecurringTransaction::class);
    }

    /**
     * Get user's active recurring transactions.
     */
    public function activeRecurringTransactions(): HasMany
    {
        return $this->recurringTransactions()->where('is_active', true);
    }

    /**
     * Get user's notifications.
     */
    public function userNotifications(): HasMany
    {
        return $this->hasMany(UserNotification::class)->orderBy('created_at', 'desc');
    }

    /**
     * Get user's unread notifications.
     */
    public function unreadNotifications(): HasMany
    {
        return $this->userNotifications()->whereNull('read_at');
    }

    /**
     * Get user's imports.
     */
    public function imports(): HasMany
    {
        return $this->hasMany(Import::class)->orderBy('created_at', 'desc');
    }

    /**
     * Get total balance across all accounts.
     */
    public function getTotalBalanceAttribute(): float
    {
        return $this->activeAccounts()
            ->where('include_in_total', true)
            ->sum('current_balance');
    }

    /**
     * Get total income for current month.
     */
    public function getCurrentMonthIncomeAttribute(): float
    {
        return $this->transactions()
            ->where('type', 'income')
            ->whereMonth('date', now()->month)
            ->whereYear('date', now()->year)
            ->sum('amount');
    }

    /**
     * Get total expenses for current month.
     */
    public function getCurrentMonthExpenseAttribute(): float
    {
        return $this->transactions()
            ->where('type', 'expense')
            ->whereMonth('date', now()->month)
            ->whereYear('date', now()->year)
            ->sum('amount');
    }

    /**
     * Get the default currency for this user.
     */
    public function getDefaultCurrencyAttribute(): Currency
    {
        return $this->settings?->defaultCurrency
            ?? Currency::where('code', 'IDR')->first()
            ?? Currency::first();
    }
}
