<?php

namespace App\Http\Controllers\Api\Pos;

use App\Http\Controllers\Controller;
use App\Models\Product;
use App\Models\User;
use App\Services\PriceService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    protected PriceService $priceService;

    public function __construct(PriceService $priceService)
    {
        $this->priceService = $priceService;
    }

    /**
     * POS image fields: thumb URL only — never expose original.
     *
     * @return array{image_path: string|null, image_thumb: string|null, image: array<string, string|null>|null}
     */
    private function posImageFields(Product $product): array
    {
        $thumb = $product->getImageUrlForContext('thumb');

        return [
            'image_path' => $thumb,
            'image_thumb' => $thumb,
            'image' => $product->pos_image,
        ];
    }

    /**
     * Search products by name or barcode (only products with available stock)
     */
    public function index(Request $request): JsonResponse
    {
        $query = $request->get('q', '');
        $limit = $request->get('limit', 50);
        $customerId = $request->get('customer_id');

        // Load customer if provided
        $customer = null;
        if ($customerId) {
            $customer = User::select('id', 'name', 'mobile', 'email', 'customer_type')->find($customerId);
            // Ensure customer_type is set (default to 'retail' if null)
            if ($customer) {
                // Get raw customer_type from database attributes to avoid any casting issues
                $rawCustomerType = $customer->getAttributes()['customer_type'] ?? null;
                $customer->customer_type = $rawCustomerType ?? 'retail';
            }
        }

        // Unified model: All sellable products (single and variants) are in products table
        // Variants have parent_id set, single products have parent_id = NULL
        $products = Product::active()
            ->forPos()
            ->where('current_stock', '>', 0) // Only products with stock
            ->with(['category', 'unit', 'tax', 'parent', 'attributeValues.attribute'])
            ->when($query, function ($q) use ($query) {
                $q->where(function ($queryBuilder) use ($query) {
                    $queryBuilder->where('name', 'like', "%{$query}%")
                        ->orWhere('barcode', 'like', "%{$query}%")
                        ->orWhere('tags', 'like', "%{$query}%")
                        ->orWhere('sku', 'like', "%{$query}%");
                });
            })
            ->limit($limit)
            ->get()
            ->map(function ($product) use ($customer) {
                $effectivePrice = $this->priceService->getPriceForCustomer($product, $customer);
                
                // Determine price type based on customer
                $priceType = 'retail';
                if ($customer) {
                    $rawCustomerType = $customer->getAttributes()['customer_type'] ?? $customer->customer_type ?? 'retail';
                    $priceType = $rawCustomerType === 'wholesale' ? 'wholesale' : 'retail';
                }
                
                // Get variation name if this is a variant
                $variationName = null;
                if ($product->parent_id && $product->attributeValues->isNotEmpty()) {
                    $variationName = $product->attributeValues->map(function ($av) {
                        return $av->attribute->name . ': ' . $av->value;
                    })->implode(' - ');
                }

                return array_merge([
                    'id' => $product->id,
                    'name' => $product->name,
                    'barcode' => $product->barcode,
                    'product_type' => $product->parent_id ? 'variant' : $product->product_type,
                    'price' => (float) $product->price,
                    'sale_price' => (float) $product->price,
                    'wholesale_price' => $product->wholesale_price ? (float) $product->wholesale_price : null,
                    'effective_price' => $effectivePrice,
                    'price_type' => $priceType,
                    'mrp' => $product->mrp ? (float) $product->mrp : null,
                    'current_stock' => $product->current_stock,
                    'category' => $product->category ? $product->category->name : null,
                    'unit' => $product->unit ? $product->unit->name : null,
                    'tax_id' => $product->tax_id,
                    'tax_rate' => $product->tax ? (float) $product->tax_rate_snapshot : 0,
                    'tax_name' => $product->tax ? $product->tax->name : null,
                    'variation_name' => $variationName,
                    'tags' => $product->tags,
                ], $this->posImageFields($product));
            });

        return response()->json([
            'success' => true,
            'data' => $products,
        ]);
    }

    /**
     * Get single product details (only if stock available)
     */
    public function show(Request $request, $id): JsonResponse
    {
        $customerId = $request->get('customer_id');

        // Load customer if provided
        $customer = null;
        if ($customerId) {
            $customer = User::select('id', 'name', 'mobile', 'email', 'customer_type')->find($customerId);
            // Ensure customer_type is set (default to 'retail' if null)
            if ($customer) {
                // Get raw customer_type from database attributes to avoid any casting issues
                $rawCustomerType = $customer->getAttributes()['customer_type'] ?? null;
                $customer->customer_type = $rawCustomerType ?? 'retail';
            }
        }

        $product = Product::active()
            ->forPos()
            ->with(['category', 'unit', 'tax', 'parent', 'attributeValues.attribute'])
            ->findOrFail($id);

        // Check if product has available stock
        if ($product->current_stock <= 0) {
            return response()->json([
                'success' => false,
                'message' => 'Product is out of stock',
            ], 404);
        }

        $effectivePrice = $this->priceService->getPriceForCustomer($product, $customer);
        // Determine price type based on customer
        $priceType = 'retail';
        if ($customer) {
            $rawCustomerType = $customer->getAttributes()['customer_type'] ?? $customer->customer_type ?? 'retail';
            $priceType = $rawCustomerType === 'wholesale' ? 'wholesale' : 'retail';
        }

        // Load latest approved reviews
        $latestReviews = $product->approvedReviews()
            ->with('user:id,name')
            ->latest()
            ->limit(5)
            ->get()
            ->map(function ($review) {
                return [
                    'id' => $review->id,
                    'rating' => $review->rating,
                    'title' => $review->title,
                    'body' => $review->body,
                    'author' => $review->author_name,
                    'created_at' => $review->created_at->format('Y-m-d H:i:s'),
                    'helpful_count' => $review->helpful_count,
                ];
            });

        return response()->json([
            'success' => true,
            'data' => array_merge([
                'id' => $product->id,
                'name' => $product->name,
                'barcode' => $product->barcode,
                'product_type' => $product->parent_id ? 'variant' : $product->product_type,
                'price' => (float) $product->price,
                'sale_price' => (float) $product->price,
                'wholesale_price' => $product->wholesale_price ? (float) $product->wholesale_price : null,
                'effective_price' => $effectivePrice,
                'price_type' => $priceType,
                'mrp' => $product->mrp ? (float) $product->mrp : null,
                'current_stock' => $product->current_stock,
                'category' => $product->category ? $product->category->name : null,
                'unit' => $product->unit ? $product->unit->name : null,
                'tax_id' => $product->tax_id,
                'tax_rate' => $product->tax ? (float) $product->tax_rate_snapshot : 0,
                'tax_name' => $product->tax ? $product->tax->name : null,
                'avg_rating' => $product->avg_rating ? (float) $product->avg_rating : 0.00,
                'rating_count' => $product->rating_count ?? 0,
                'reviews' => $latestReviews,
            ], $this->posImageFields($product)),
        ]);
    }
}
