<?php

namespace App\Services\Product;

use App\Models\Product\Product;
use Illuminate\Support\Facades\Cache;

class ProductCatalogService
{
    /**
     * Get the Redis cache key for a company's product catalog.
     *
     * @param int|null $companyId
     * @return string
     */
    public function getCacheKey(?int $companyId): string
    {
        return "products_catalog:" . ($companyId ?? 'global');
    }

    /**
     * Get the product catalog payload, using cache if available.
     *
     * @param int|null $companyId
     * @return array
     */
    public function getPayload(?int $companyId): array
    {
        $cacheKey = $this->getCacheKey($companyId);
        $cached   = Cache::get($cacheKey);

        if ($cached) {
            return $cached;
        }

        return $this->rebuildCache($companyId);
    }

    /**
     * Rebuild the product catalog cache for a company.
     *
     * @param int|null $companyId
     * @return array
     */
    public function rebuildCache(?int $companyId): array
    {
        $products = Product::where('company_id', $companyId)
            ->with(['translations'])
            ->active()
            ->get()
            ->map(fn($p) => $this->mapProduct($p));

        $payload = [
            'success' => true,
            'code'    => 200,
            'data'    => $products->toArray(),
        ];

        Cache::forever($this->getCacheKey($companyId), $payload);

        return $payload;
    }

    /**
     * Invalidate the product catalog cache for a company.
     *
     * @param int|null $companyId
     * @return void
     */
    public function invalidate(?int $companyId): void
    {
        Cache::forget($this->getCacheKey($companyId));
    }

    /**
     * Map a Product model to the catalog format expected by machines.
     *
     * @param Product $product
     * @return array
     */
    private function mapProduct($product): array
    {
        $nameEn = $product->translations->firstWhere('locale', 'en')?->value ?? '';
        $nameJp = $product->translations->firstWhere('locale', 'ja')?->value ?? '';

        return [
            't060v00'      => (string) $product->id,
            't060v01'      => $product->name,
            't060v01_en'   => $nameEn,
            't060v01_jp'   => $nameJp,
            't060v03'      => $product->spec ?? '',
            't060v06'      => $product->image_url
                                ? (str_starts_with($product->image_url, 'http') ? $product->image_url : asset($product->image_url))
                                : '',
            't060v09'      => (float) $product->price,
            't060v11'      => (int) ($product->track_limit ?? 10),
            't060v30'      => (float) ($product->member_price ?? $product->price),
            't060v40'      => $product->metadata['marketing_plan'] ?? '',
            't060v41'      => $product->metadata['material_code'] ?? $product->barcode ?? '',
            'spring_limit' => (int) ($product->spring_limit ?? 10),
            'track_limit'  => (int) ($product->track_limit ?? 10),
            't063v03'      => (float) $product->price,
        ];
    }
}
