<?php

declare(strict_types=1);

namespace App\Domain\Account\Models;

use App\Domain\Account\Enums\AccountStatus;
use App\Domain\Package\Models\Package;
use App\Models\User;
use Database\Factories\AccountFactory;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;

/**
 * @property int $id
 * @property int $owner_user_id
 * @property int $package_id
 * @property string $username Linux username (onx_<4-12 char>)
 * @property int|null $linux_uid 10000-65000, null = henüz provision değil
 * @property int|null $linux_gid Primary group GID (provision sonrası set)
 * @property string|null $skeleton_version cPanel-grade skeleton template versiyonu
 * @property string $email
 * @property string|null $primary_domain
 * @property AccountStatus $status
 * @property Carbon|null $provisioned_at
 * @property Carbon|null $suspended_at
 * @property string|null $suspended_reason
 * @property Carbon|null $terminated_at
 * @property int|null $quota_bytes
 * @property int $disk_usage_bytes
 * @property Carbon|null $usage_updated_at
 * @property float|null $last_quota_pct
 * @property string|null $admin_notes
 * @property Carbon $created_at
 * @property Carbon $updated_at
 * @property Carbon|null $deleted_at
 * @property-read User $owner
 * @property-read Package $package
 */
class Account extends Model
{
    /** @use HasFactory<AccountFactory> */
    use HasFactory, SoftDeletes;

    protected $table = 'accounts';

    protected $fillable = [
        'owner_user_id',
        'package_id',
        'username',
        'linux_uid',
        'linux_gid',
        'skeleton_version',
        'email',
        'primary_domain',
        'status',
        'provisioned_at',
        'suspended_at',
        'suspended_reason',
        'terminated_at',
        'quota_bytes',
        'disk_usage_bytes',
        'usage_updated_at',
        'last_quota_pct',
        'admin_notes',
        'tags',
    ];

    protected function casts(): array
    {
        return [
            'status' => AccountStatus::class,
            'provisioned_at' => 'datetime',
            'suspended_at' => 'datetime',
            'terminated_at' => 'datetime',
            'usage_updated_at' => 'datetime',
            'linux_uid' => 'integer',
            'linux_gid' => 'integer',
            'quota_bytes' => 'integer',
            'disk_usage_bytes' => 'integer',
            'last_quota_pct' => 'float',
            'tags' => 'array',
        ];
    }

    // ─── Relationships ────────────────────────────────────────────────────

    public function owner(): BelongsTo
    {
        return $this->belongsTo(User::class, 'owner_user_id');
    }

    public function package(): BelongsTo
    {
        return $this->belongsTo(Package::class);
    }

    public function domains(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(\App\Domain\Domain\Models\Domain::class);
    }

    public function mysqlDatabases(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(\App\Domain\Database\Models\MysqlDatabase::class);
    }

    public function emailAccounts(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(\App\Domain\Email\Models\EmailAccount::class);
    }

    public function ftpUsers(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(\App\Domain\Ftp\Models\FtpUser::class);
    }

    // ─── Scopes ───────────────────────────────────────────────────────────

    public function scopeActive(Builder $q): Builder
    {
        return $q->where('status', AccountStatus::Active);
    }

    public function scopeSuspended(Builder $q): Builder
    {
        return $q->where('status', AccountStatus::Suspended);
    }

    public function scopePending(Builder $q): Builder
    {
        return $q->where('status', AccountStatus::Pending);
    }

    public function scopeProvisioned(Builder $q): Builder
    {
        return $q->whereNotNull('linux_uid');
    }

    // ─── Helpers ──────────────────────────────────────────────────────────

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

    public function isProvisioned(): bool
    {
        return $this->linux_uid !== null;
    }

    public function homeDirectory(): string
    {
        return '/home/'.$this->username;
    }

    /**
     * Disk kullanım yüzdesi (0-100, null quota → null).
     */
    public function diskUsagePercent(): ?float
    {
        if ($this->quota_bytes === null || $this->quota_bytes === 0) {
            return null;
        }

        return round(($this->disk_usage_bytes / $this->quota_bytes) * 100, 2);
    }

    protected static function newFactory(): AccountFactory
    {
        return AccountFactory::new();
    }
}
