<?php

declare(strict_types=1);

namespace App\Domain\Database\Models;

use App\Domain\Account\Models\Account;
use App\Domain\Database\Enums\DatabaseEngine;
use App\Domain\Database\Enums\DatabaseStatus;
use Database\Factories\MysqlDatabaseFactory;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;

/**
 * @property int $id
 * @property int $account_id
 * @property string $name
 * @property string $real_db_name
 * @property string $charset
 * @property string $collation
 * @property DatabaseEngine $engine
 * @property string|null $engine_version
 * @property DatabaseStatus $status
 * @property string|null $last_error
 * @property Carbon|null $last_provisioned_at
 * @property int $size_bytes
 * @property-read Account $account
 * @property-read Collection<int, MysqlUser> $users
 */
class MysqlDatabase extends Model
{
    /** @use HasFactory<MysqlDatabaseFactory> */
    use HasFactory, SoftDeletes;

    protected $table = 'mysql_databases';

    protected $fillable = [
        'account_id', 'name', 'real_db_name', 'charset', 'collation',
        'engine', 'engine_version',
        'status', 'last_error', 'last_provisioned_at', 'size_bytes', 'size_updated_at',
    ];

    protected function casts(): array
    {
        return [
            'engine' => DatabaseEngine::class,
            'status' => DatabaseStatus::class,
            'last_provisioned_at' => 'datetime',
            'size_updated_at' => 'datetime',
            'size_bytes' => 'integer',
        ];
    }

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

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(MysqlUser::class, 'mysql_grants', 'database_id', 'user_id')
            ->withPivot('privileges')
            ->withTimestamps();
    }

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

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