<?php

declare(strict_types=1);

namespace ImovelZapAi\ClientPortal\Infrastructure\Persistence\Eloquent;

use App\Models\User;
use Database\Factories\ClientPortalFactory;
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\ClientPortal\Domain\Enums\PortalStatus;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ContactModel;
use ImovelZapAi\Conversations\Infrastructure\Persistence\Eloquent\ConversationModel;
use ImovelZapAi\Sales\Infrastructure\Persistence\Eloquent\DealModel;
use ImovelZapAi\Shared\Infrastructure\Persistence\Concerns\BelongsToTenant;
use ImovelZapAi\Shared\Infrastructure\Persistence\Concerns\HasUuidPrimaryKey;

class ClientPortalModel extends Model
{
    use BelongsToTenant;
    use HasFactory;
    use HasUuidPrimaryKey;

    protected $table = 'client_portals';

    protected $fillable = [
        'tenant_id', 'contact_id', 'deal_id', 'conversation_id', 'owner_id',
        'created_by', 'responsible_user_id', 'title', 'greeting_name', 'status',
        'intro_message', 'expires_at', 'revoked_at', 'completed_at', 'last_activity_at',
        'documents_total', 'documents_approved', 'documents_submitted',
    ];

    protected function casts(): array
    {
        return [
            'status' => PortalStatus::class,
            'expires_at' => 'datetime',
            'revoked_at' => 'datetime',
            'completed_at' => 'datetime',
            'last_activity_at' => 'datetime',
            'documents_total' => 'integer',
            'documents_approved' => 'integer',
            'documents_submitted' => 'integer',
        ];
    }

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

    public function contact(): BelongsTo
    {
        return $this->belongsTo(ContactModel::class, 'contact_id');
    }

    public function deal(): BelongsTo
    {
        return $this->belongsTo(DealModel::class, 'deal_id');
    }

    public function conversation(): BelongsTo
    {
        return $this->belongsTo(ConversationModel::class, 'conversation_id');
    }

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

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

    public function tokens(): HasMany
    {
        return $this->hasMany(PortalAccessTokenModel::class, 'client_portal_id');
    }

    public function documentRequest(): HasOne
    {
        return $this->hasOne(DocumentRequestModel::class, 'client_portal_id');
    }

    public function requestedDocuments(): HasMany
    {
        return $this->hasMany(RequestedDocumentModel::class, 'client_portal_id')->orderBy('position');
    }

    public function activities(): HasMany
    {
        return $this->hasMany(PortalActivityModel::class, 'client_portal_id')->orderByDesc('created_at');
    }

    public function comments(): HasMany
    {
        return $this->hasMany(DocumentCommentModel::class, 'client_portal_id');
    }

    public function progressPercent(): int
    {
        if ($this->documents_total <= 0) {
            return 0;
        }

        return (int) round(($this->documents_approved / $this->documents_total) * 100);
    }

    public function isPubliclyAccessible(): bool
    {
        if ($this->status !== PortalStatus::Active) {
            return false;
        }
        if ($this->revoked_at !== null) {
            return false;
        }
        if ($this->expires_at !== null && $this->expires_at->isPast()) {
            return false;
        }

        return true;
    }
}
