<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class SearchState extends Model
{
    protected $fillable = [
        'user_id',
        'conversation_id',
        'session_id',
        'search_type',
        'search_params',
        'all_product_ids',
        'total_count',
        'current_page',
        'per_page',
        'confirmed',
        'expires_at',
    ];

    protected $casts = [
        'search_params' => 'array',
        'all_product_ids' => 'array',
        'total_count' => 'integer',
        'current_page' => 'integer',
        'per_page' => 'integer',
        'confirmed' => 'boolean',
        'expires_at' => 'datetime',
    ];

    /**
     * Get the user that owns the search state.
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    /**
     * Get the conversation associated with the search state.
     */
    public function conversation(): BelongsTo
    {
        return $this->belongsTo(AiConversation::class, 'conversation_id');
    }

    /**
     * Get the current page's product IDs.
     */
    public function getCurrentPageIds(): array
    {
        $offset = ($this->current_page - 1) * $this->per_page;

        return array_slice($this->all_product_ids, $offset, $this->per_page);
    }

    /**
     * Check if there are more results available.
     */
    public function hasMorePages(): bool
    {
        return $this->current_page * $this->per_page < $this->total_count;
    }

    /**
     * Get the remaining count of products.
     */
    public function getRemainingCount(): int
    {
        return max(0, $this->total_count - ($this->current_page * $this->per_page));
    }

    /**
     * Move to the next page.
     */
    public function nextPage(): self
    {
        $this->increment('current_page');

        return $this->fresh();
    }

    /**
     * Mark as confirmed by user.
     */
    public function markAsConfirmed(): self
    {
        $this->update(['confirmed' => true]);

        return $this->fresh();
    }

    /**
     * Check if the search state is expired.
     */
    public function isExpired(): bool
    {
        return $this->expires_at && $this->expires_at->isPast();
    }

    /**
     * Clean up expired search states.
     */
    public static function cleanExpired(): int
    {
        return static::where('expires_at', '<', now())->delete();
    }

    /**
     * Create a new search state.
     */
    public static function createFromSearch(
        ?int $userId,
        ?int $conversationId,
        string $searchType,
        array $searchParams,
        array $productIds,
        int $perPage = 4
    ): self {
        // Clean up old states for this conversation first
        static::where('conversation_id', $conversationId)
            ->where('search_type', $searchType)
            ->delete();

        return static::create([
            'user_id' => $userId,
            'conversation_id' => $conversationId,
            'search_type' => $searchType,
            'search_params' => $searchParams,
            'all_product_ids' => $productIds,
            'total_count' => count($productIds),
            'current_page' => 1,
            'per_page' => $perPage,
            'confirmed' => false,
            'expires_at' => now()->addHours(24), // Expire after 24 hours
        ]);
    }

    /**
     * Get the active search state for a conversation.
     */
    public static function getActive(?int $conversationId, string $searchType = 'products'): ?self
    {
        return static::where('conversation_id', $conversationId)
            ->where('search_type', $searchType)
            ->where('expires_at', '>', now())
            ->latest()
            ->first();
    }
}
