<?php

declare(strict_types=1);

namespace ImovelZapAi\Tenancy\Infrastructure\Persistence\Eloquent;

use Database\Factories\TenantFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use ImovelZapAi\Organizations\Infrastructure\Persistence\Eloquent\OrganizationSettingsModel;
use ImovelZapAi\Organizations\Infrastructure\Persistence\Eloquent\OrganizationSubscriptionModel;
use ImovelZapAi\Shared\Infrastructure\Persistence\Concerns\HasUuidPrimaryKey;
use ImovelZapAi\Tenancy\Domain\Entities\Tenant as TenantEntity;
use ImovelZapAi\Tenancy\Domain\Enums\OrganizationType;
use ImovelZapAi\Tenancy\Domain\Enums\TenantStatus;
use ImovelZapAi\Users\Infrastructure\Persistence\Eloquent\UserModel;

class TenantModel extends Model
{
    /** @use HasFactory<TenantFactory> */
    use HasFactory;
    use HasUuidPrimaryKey;

    protected $table = 'tenants';

    /** @var list<string> */
    protected $fillable = [
        'name',
        'slug',
        'status',
        'type',
        'owner_user_id',
    ];

    /** @return array<string, string> */
    protected function casts(): array
    {
        return [
            'status' => TenantStatus::class,
            'type' => OrganizationType::class,
        ];
    }

    public function users(): HasMany
    {
        return $this->hasMany(UserModel::class, 'tenant_id');
    }

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

    public function organizationSettings(): HasOne
    {
        return $this->hasOne(OrganizationSettingsModel::class, 'tenant_id');
    }

    public function organizationSubscription(): HasOne
    {
        return $this->hasOne(OrganizationSubscriptionModel::class, 'tenant_id');
    }

    public function isSolo(): bool
    {
        return $this->type === OrganizationType::Solo;
    }

    public function toDomainEntity(): TenantEntity
    {
        return new TenantEntity(
            id: (string) $this->getKey(),
            name: $this->name,
            slug: $this->slug,
            status: $this->status,
            type: $this->type ?? OrganizationType::Agency,
            ownerUserId: $this->owner_user_id !== null ? (string) $this->owner_user_id : null,
        );
    }

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