<?php

namespace App\Models;

use App\Enums\AccountStatus;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
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;

#[Fillable([
    'full_name',
    'username',
    'email',
    'phone_number',
    'password',
    'paystack_customer_code',
    'virtual_account_number',
    'virtual_account_bank',
])]
#[Hidden(['password', 'remember_token', 'transaction_pin'])]
class User extends Authenticatable
{
    /** @use HasFactory<UserFactory> */
    use HasApiTokens, HasFactory, Notifiable;

    protected $appends = ['email_status', 'phone_number_status'];

    protected static function booted(): void
    {
        static::creating(function (User $user) {
            if (! $user->account_id) {
                $user->account_id = static::generateUniqueAccountId();
            }
        });
    }

    protected static function generateUniqueAccountId(): string
    {
        do {
            $id = (string) random_int(1000000000, 9999999999);
        } while (static::where('account_id', $id)->exists());

        return $id;
    }

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'phone_number_verified_at' => 'datetime',
            'password' => 'hashed',
            'status' => AccountStatus::class,
            'balance' => 'decimal:2',
        ];
    }

    public function getEmailStatusAttribute(): string
    {
        return $this->email_verified_at ? 'verified' : 'unverified';
    }

    public function getPhoneNumberStatusAttribute(): string
    {
        return $this->phone_number_verified_at ? 'verified' : 'unverified';
    }

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