<?php

namespace App\Http\Controllers\Api\v3\Torob;

use App\Http\Controllers\Controller;
use App\Models\Product;
use Illuminate\Http\Request;

class TorobProductsController extends Controller
{
    public function index(Request $request)
    {
        $body = $request->json()->all();

        if (empty($body)) {
            return response()->json(['error' => 'empty body'], 400);
        }

        $hasPageUrls    = array_key_exists('page_urls', $body);
        $hasPageUniques = array_key_exists('page_uniques', $body);
        $hasPage        = array_key_exists('page', $body);
        $hasSort        = array_key_exists('sort', $body);

        if ($hasPageUrls && !$hasPageUniques && !$hasPage && !$hasSort) {
            if (!is_array($body['page_urls']) || count($body['page_urls']) === 0) {
                return response()->json(['error' => 'page_urls must be a non-empty array'], 400);
            }
            return $this->handlePageUrls($body['page_urls']);
        }

        if ($hasPageUniques && !$hasPageUrls && !$hasPage && !$hasSort) {
            if (!is_array($body['page_uniques']) || count($body['page_uniques']) === 0) {
                return response()->json(['error' => 'page_uniques must be a non-empty array'], 400);
            }
            return $this->handlePageUniques($body['page_uniques']);
        }

        if ($hasPage || $hasSort) {
            if ($hasPage && !$hasSort) {
                return response()->json(['error' => 'sort parameter is not provided'], 400);
            }
            if (!$hasPage && $hasSort) {
                return response()->json(['error' => 'page parameter is not provided'], 400);
            }
            if ($hasPage && $hasSort && !$hasPageUrls && !$hasPageUniques) {
                if (!is_int($body['page']) || $body['page'] < 1) {
                    return response()->json(['error' => 'page parameter must be an integer >= 1'], 400);
                }
                if ($body['sort'] !== 'date_added_desc') {
                    return response()->json(['error' => 'sort parameter is not supported'], 400);
                }
                return $this->handlePaginate($body['page'], $body['sort']);
            }
        }

        return response()->json(['error' => 'invalid combination of parameters'], 400);
    }

    private function handlePageUrls(array $urls)
    {
        $slugs = [];
        foreach ($urls as $url) {
            $path = parse_url($url, PHP_URL_PATH);
            if ($path) {
                $decodedPath = urldecode($path);
                $slug = basename($decodedPath);
                if (!empty($slug)) {
                    $slugs[] = $slug;
                }
            }
        }

        $products = Product::where('status', 'publish')
            ->whereIn('slug', $slugs)
            ->get()
            ->keyBy('slug');

        $ordered = [];
        foreach ($slugs as $slug) {
            if (isset($products[$slug])) {
                $ordered[] = $this->mapProductToTorob($products[$slug]);
            }
        }

        return response()->json([
            'api_version'  => 'torob_api_v3',
            'current_page' => 1,
            'total'        => count($ordered),
            'count'        => count($ordered),
            'max_pages'    => 1,
            'products'     => $ordered,
        ]);
    }

    private function handlePageUniques(array $uniques)
    {
        $products = Product::where('status', 'publish')
            ->whereIn('uuid', $uniques)
            ->get()
            ->keyBy('uuid');

        $ordered = [];
        foreach ($uniques as $uuid) {
            if (isset($products[$uuid])) {
                $ordered[] = $this->mapProductToTorob($products[$uuid]);
            }
        }

        return response()->json([
            'api_version'  => 'torob_api_v3',
            'current_page' => 1,
            'total'        => count($ordered),
            'count'        => count($ordered),
            'max_pages'    => 1,
            'products'     => $ordered,
        ]);
    }

    private function handlePaginate(int $page, string $sort)
    {
        $perPage = 100;
        $total   = Product::where('status', 'publish')->count();
        $maxPages = (int) ceil($total / $perPage);

        $orderColumn = 'created_at';
        $offset = ($page - 1) * $perPage;

        $products = Product::where('status', 'publish')
            ->orderBy($orderColumn, 'desc')
            ->skip($offset)
            ->take($perPage)
            ->get();

        $mapped = $products->map(fn($p) => $this->mapProductToTorob($p))->values()->all();

        return response()->json([
            'api_version'  => 'torob_api_v3',
            'current_page' => $page,
            'total'        => $total,
            'count'        => $total,
            'max_pages'    => $maxPages,
            'products'     => $mapped,
        ]);
    }

    private function mapProductToTorob(Product $product): array
    {
        $guarantee = null;
        $spec      = [];

        if ($product->best_inventory && isset($product->best_inventory['props'])) {
            $propsCollection = collect($product->best_inventory['props']);

            // گارانتی
            $guaranteeProp = $propsCollection->firstWhere('name', 'گارانتی');
            if ($guaranteeProp && isset($guaranteeProp['value'])) {
                $guarantee = $guaranteeProp['value'];
            }

            // رنگ
            $colorProp = $propsCollection->firstWhere('name', 'رنگ');
            if ($colorProp && isset($colorProp['value']) && is_array($colorProp['value'])) {
                $spec['رنگ'] = $colorProp['value']['label'];
            }

            // اصالت کالا
            if (array_key_exists('original', $product->best_inventory) && $product->best_inventory['original'] !== null) {
                $spec['اصالت کالا'] = $product->best_inventory['original'] ? 'اصل' : 'غیر اصل';
            }

            // وضعیت کالا
            if (array_key_exists('used', $product->best_inventory) && $product->best_inventory['used'] !== null) {
                $spec['وضعیت کالا'] = $product->best_inventory['used'] ? 'کارکرده' : 'نو';
            }
        }

        if (empty($spec)) {
            $spec = new \stdClass();
        }

        $availability = $product->inventory && $product->in_stock_status;
        $currentPrice = $product->inventory && $product->in_stock_status ? $product->best_price : 0;
        $oldPrice = $product->inventory && $product->in_stock_status && $product->has_discount ? $product->best_inventory['price'] : null;

        return [
            'page_unique'      => $product->uuid,
            'page_url'         => urldecode(route('main.products.show', $product->slug, true)),
            'title'            => $product->title,
            'subtitle'         => $product->title_en,
            'current_price'    => (int) $currentPrice,
            'old_price'        => !is_null($oldPrice) ? ($oldPrice > $currentPrice ? (int)$oldPrice : null) : null,
            'availability'     => $availability,
            'category_name'    => $product->productCategory->title ?? null,
            'image_links'      => $product->get_images_link,
            'short_desc'       => $product->seo_description
                ? (mb_strlen($product->seo_description) > 500
                    ? mb_substr($product->seo_description, 0, 500)
                    : $product->seo_description)
                : null,
            'spec'             => $spec,
            'guarantee'        => $guarantee,
            'date_added'       => $product->created_at->toIso8601String(),
        ];
    }
}
