<?php

declare(strict_types=1);

namespace App\Support;

use Hypervel\Codec\Json;
use App\Models\User;
use App\Models\Market\Product;
use App\Models\Market\Store;

/**
 * HashkeyResolver provides a universal resolver for any model by hashkey.
 * This allows resolving resources (User, Product, Store, etc.) without knowing
 * the specific model class upfront.
 */
class HashkeyResolver
{
    /**
     * Resolve a resource by its hashkey.
     * This is a generic method that works with any model class.
     *
     * @param string $hashkey The hashkey to resolve
     * @param string $modelClass The model class name (e.g., 'App\Models\User')
     * @return mixed|null The resolved model instance or null if not found
     */
    public function resolveByHashkey($hashkey, $modelClass)
    {
        if (!$hashkey || empty($modelClass)) {
            return null;
        }

        // Use the model's static where method to find by hashkey
        try {
            return $modelClass::where('hashkey', $hashkey)->first();
        } catch (\Exception $e) {
            error_log("[HashkeyResolver] Error resolving {$modelClass} by hashkey: " . $e->getMessage());
            return null;
        }
    }

    /**
     * Resolve a user by their hashkey.
     *
     * @param string $hashkey The user's hashkey
     * @return mixed|null The resolved User instance or null if not found
     */
    public function resolveUserByHashkey($hashkey)
    {
        return $this->resolveByHashkey($hashkey, User::class);
    }

    /**
     * Resolve a product by its hashkey.
     *
     * @param string $hashkey The product's hashkey
     * @return mixed|null The resolved Product instance or null if not found
     */
    public function resolveProductByHashkey($hashkey)
    {
        return $this->resolveByHashkey($hashkey, Product::class);
    }

    /**
     * Resolve a store by its hashkey.
     *
     * @param string $hashkey The store's hashkey
     * @return mixed|null The resolved Store instance or null if not found
     */
    public function resolveStoreByHashkey($hashkey)
    {
        return $this->resolveByHashkey($hashkey, Store::class);
    }

    /**
     * Check if a model exists by its hashkey.
     *
     * @param string $hashkey The resource's hashkey
     * @param string $modelClass The model class name
     * @return bool True if the resource exists, false otherwise
     */
    public function existsByHashkey($hashkey, $modelClass)
    {
        if (!$hashkey || empty($modelClass)) {
            return false;
        }

        try {
            return $modelClass::where('hashkey', $hashkey)->exists();
        } catch (\Exception $e) {
            error_log("[HashkeyResolver] Error checking existence for {$modelClass}: " . $e->getMessage());
            return false;
        }
    }

    /**
     * Resolve multiple resources by their hashkeys.
     *
     * @param array $hashkeys Array of hashkeys to resolve
     * @param string $modelClass The model class name
     * @return array Collection of resolved models
     */
    public function resolveMultipleByHashkey($hashkeys, $modelClass)
    {
        if (!is_array($hashkeys) || empty($hashkeys)) {
            return [];
        }

        try {
            return $modelClass::where('hashkey', '!=', null)
                ->whereIn('hashkey', $hashkeys)
                ->get();
        } catch (\Exception $e) {
            error_log("[HashkeyResolver] Error resolving multiple by hashkey: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Get hashkey from request input (from various sources).
     * This helper method looks for 'hashkey' or 'target' in the request.
     *
     * @param \Hypervel\Http\Request $request The request object
     * @return string|null The hashkey value or null
     */
    public function getHashkeyFromRequest($request)
    {
        $hashkey = $request->input('hashkey') ?: $request->input('target');
        
        return !empty($hashkey) ? $hashkey : null;
    }
}