<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Builder;

class UserNotification extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array<string>
     */
    protected $fillable = [
        'user_id',
        'type',
        'title',
        'message',
        'data',
        'action_url',
        'icon',
        'read_at',
    ];

    /**
     * The attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'data' => 'array',
            'read_at' => 'datetime',
        ];
    }

    /**
     * Notification types.
     */
    public const TYPE_BUDGET_ALERT = 'budget_alert';
    public const TYPE_BUDGET_EXCEEDED = 'budget_exceeded';
    public const TYPE_BILL_REMINDER = 'bill_reminder';
    public const TYPE_GOAL_ACHIEVED = 'goal_achieved';
    public const TYPE_GOAL_PROGRESS = 'goal_progress';
    public const TYPE_LOW_BALANCE = 'low_balance';
    public const TYPE_WEEKLY_SUMMARY = 'weekly_summary';
    public const TYPE_MONTHLY_SUMMARY = 'monthly_summary';

    /**
     * Type icons.
     */
    public const TYPE_ICONS = [
        self::TYPE_BUDGET_ALERT => '⚠️',
        self::TYPE_BUDGET_EXCEEDED => '🚨',
        self::TYPE_BILL_REMINDER => '📅',
        self::TYPE_GOAL_ACHIEVED => '🎉',
        self::TYPE_GOAL_PROGRESS => '📈',
        self::TYPE_LOW_BALANCE => '💸',
        self::TYPE_WEEKLY_SUMMARY => '📊',
        self::TYPE_MONTHLY_SUMMARY => '📆',
    ];

    /**
     * Get the user for this notification.
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Scope to get unread notifications.
     */
    public function scopeUnread(Builder $query): Builder
    {
        return $query->whereNull('read_at');
    }

    /**
     * Scope to get read notifications.
     */
    public function scopeRead(Builder $query): Builder
    {
        return $query->whereNotNull('read_at');
    }

    /**
     * Scope to get notifications by type.
     */
    public function scopeOfType(Builder $query, string $type): Builder
    {
        return $query->where('type', $type);
    }

    /**
     * Check if notification is read.
     */
    public function isRead(): bool
    {
        return $this->read_at !== null;
    }

    /**
     * Mark as read.
     */
    public function markAsRead(): void
    {
        if (!$this->isRead()) {
            $this->update(['read_at' => now()]);
        }
    }

    /**
     * Mark as unread.
     */
    public function markAsUnread(): void
    {
        $this->update(['read_at' => null]);
    }

    /**
     * Get the icon for this notification.
     */
    public function getDisplayIconAttribute(): string
    {
        return $this->icon ?? self::TYPE_ICONS[$this->type] ?? '🔔';
    }

    /**
     * Create a budget alert notification.
     */
    public static function createBudgetAlert(Budget $budget): self
    {
        return self::create([
            'user_id' => $budget->user_id,
            'type' => self::TYPE_BUDGET_ALERT,
            'title' => 'Budget Alert',
            'message' => "You've used {$budget->spent_percentage}% of your {$budget->category->name} budget.",
            'data' => [
                'budget_id' => $budget->id,
                'category_id' => $budget->category_id,
                'spent_percentage' => $budget->spent_percentage,
            ],
            'action_url' => route('budgets.index'),
            'icon' => '⚠️',
        ]);
    }

    /**
     * Create a budget exceeded notification.
     */
    public static function createBudgetExceeded(Budget $budget): self
    {
        return self::create([
            'user_id' => $budget->user_id,
            'type' => self::TYPE_BUDGET_EXCEEDED,
            'title' => 'Budget Exceeded!',
            'message' => "You've exceeded your {$budget->category->name} budget by {$budget->currency->format($budget->overspent_amount)}.",
            'data' => [
                'budget_id' => $budget->id,
                'category_id' => $budget->category_id,
                'overspent_amount' => $budget->overspent_amount,
            ],
            'action_url' => route('budgets.index'),
            'icon' => '🚨',
        ]);
    }

    /**
     * Create a bill reminder notification.
     */
    public static function createBillReminder(RecurringTransaction $recurring): self
    {
        return self::create([
            'user_id' => $recurring->user_id,
            'type' => self::TYPE_BILL_REMINDER,
            'title' => 'Upcoming Bill',
            'message' => "{$recurring->description} is due on {$recurring->next_due_date->format('M d, Y')}.",
            'data' => [
                'recurring_transaction_id' => $recurring->id,
                'amount' => $recurring->amount,
                'due_date' => $recurring->next_due_date->toDateString(),
            ],
            'action_url' => route('recurring.index'),
            'icon' => '📅',
        ]);
    }

    /**
     * Create a goal achieved notification.
     */
    public static function createGoalAchieved(Goal $goal): self
    {
        return self::create([
            'user_id' => $goal->user_id,
            'type' => self::TYPE_GOAL_ACHIEVED,
            'title' => 'Goal Achieved! 🎉',
            'message' => "Congratulations! You've reached your goal: {$goal->name}",
            'data' => [
                'goal_id' => $goal->id,
                'target_amount' => $goal->target_amount,
            ],
            'action_url' => route('goals.show', $goal),
            'icon' => '🎉',
        ]);
    }
}
