<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ShopProduct;
use App\Models\ShopProductPrice;
use App\Models\ShopProductStock;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class ShopProductController extends Controller
{
    /**
     * Sync products for a shop
     * 
     * @param Request $request
     * @return JsonResponse
     */
    public function sync(Request $request): JsonResponse
    {
        $request->validate([
            'last_sync_at' => 'nullable|date',
            'shop_id' => 'required|integer|exists:accounts,id',
        ]);

        $lastSyncAt = $request->input('last_sync_at') 
            ? Carbon::parse($request->input('last_sync_at')) 
            : null;
        $shopId = $request->input('shop_id');

        // Get new products (created after last sync, company products only)
        $newProducts = $this->getNewProducts($shopId, $lastSyncAt);
        
        // Get updated products (updated after last sync)
        $updatedProducts = $this->getUpdatedProducts($shopId, $lastSyncAt);
        
        // Get deleted products (soft deleted after last sync)
        $deletedProducts = $this->getDeletedProducts($shopId, $lastSyncAt);

        return response()->json([
            'success' => true,
            'data' => [
                'new_products' => $newProducts,
                'updated_products' => $updatedProducts,
                'deleted_products' => $deletedProducts,
            ],
            'message' => 'Products synced successfully'
        ]);
    }

    /**
     * Get new products created after last sync
     */
    private function getNewProducts(int $shopId, ?Carbon $lastSyncAt): array
    {
        $query = ShopProduct::query()
            ->whereNull('shop_id') // Company products only
            ->with([
                'prices' => function($q) use ($shopId) {
                    $q->where(function($subQ) use ($shopId) {
                        $subQ->whereNull('shop_id')
                             ->orWhere('shop_id', $shopId);
                    })
                    ->orderBy(DB::raw("CASE WHEN shop_id = {$shopId} THEN 0 ELSE 1 END"))
                    ->limit(1);
                },
                'stocks' => function($q) use ($shopId) {
                    $q->where('shop_id', $shopId);
                }
            ]);

        if ($lastSyncAt) {
            $query->where('created_at', '>', $lastSyncAt);
        }

        $products = $query->get();

        return $products->map(function($product) use ($shopId) {
            $price = $product->prices->first();
            $stock = $product->stocks->first();

            return [
                'id' => $product->id,
                'server_id' => $product->id,
                'local_id' => $product->local_id,
                'name' => $product->name,
                'sku' => $product->shop_product_sku,
                'barcode' => $product->shop_product_barcode,
                'is_active' => $product->is_active ?? true,
                'created_at' => $product->created_at ? $product->created_at->format('Y-m-d H:i:s') : null,
                'updated_at' => $product->updated_at ? $product->updated_at->format('Y-m-d H:i:s') : null,
                'price' => [
                    'cost_price' => $price ? (float) $price->cost_price : 0.00,
                    'selling_price' => $price ? (float) $price->selling_price : 0.00,
                    'updated_at' => $price && $price->updated_at 
                        ? $price->updated_at->format('Y-m-d H:i:s') 
                        : null,
                ],
                'stock' => [
                    'quantity' => $stock ? (float) $stock->quantity : 0.00,
                    'low_stock_threshold' => $stock ? (float) $stock->low_stock_threshold : 0.00,
                    'updated_at' => $stock && $stock->updated_at 
                        ? $stock->updated_at->format('Y-m-d H:i:s') 
                        : null,
                ],
            ];
        })->toArray();
    }

    /**
     * Get updated products (updated after last sync)
     */
    private function getUpdatedProducts(int $shopId, ?Carbon $lastSyncAt): array
    {
        if (!$lastSyncAt) {
            return [];
        }

        $query = ShopProduct::query()
            ->whereNull('shop_id') // Company products only
            ->where(function($q) use ($lastSyncAt) {
                $q->where('updated_at', '>', $lastSyncAt)
                  ->orWhereHas('prices', function($priceQ) use ($lastSyncAt, $shopId) {
                      $priceQ->where(function($subQ) use ($shopId) {
                          $subQ->whereNull('shop_id')
                               ->orWhere('shop_id', $shopId);
                      })
                      ->where('updated_at', '>', $lastSyncAt);
                  })
                  ->orWhereHas('stocks', function($stockQ) use ($lastSyncAt, $shopId) {
                      $stockQ->where('shop_id', $shopId)
                             ->where('updated_at', '>', $lastSyncAt);
                  });
            })
            ->with([
                'prices' => function($q) use ($shopId) {
                    $q->where(function($subQ) use ($shopId) {
                        $subQ->whereNull('shop_id')
                             ->orWhere('shop_id', $shopId);
                    })
                    ->orderBy(DB::raw("CASE WHEN shop_id = {$shopId} THEN 0 ELSE 1 END"))
                    ->limit(1);
                },
                'stocks' => function($q) use ($shopId) {
                    $q->where('shop_id', $shopId);
                }
            ]);

        $products = $query->get();

        return $products->map(function($product) use ($shopId) {
            $price = $product->prices->first();
            $stock = $product->stocks->first();

            return [
                'id' => $product->id,
                'server_id' => $product->id,
                'local_id' => $product->local_id,
                'name' => $product->name,
                'sku' => $product->shop_product_sku,
                'barcode' => $product->shop_product_barcode,
                'is_active' => $product->is_active ?? true,
                'created_at' => $product->created_at ? $product->created_at->format('Y-m-d H:i:s') : null,
                'updated_at' => $product->updated_at ? $product->updated_at->format('Y-m-d H:i:s') : null,
                'price' => [
                    'cost_price' => $price ? (float) $price->cost_price : 0.00,
                    'selling_price' => $price ? (float) $price->selling_price : 0.00,
                    'updated_at' => $price && $price->updated_at 
                        ? $price->updated_at->format('Y-m-d H:i:s') 
                        : null,
                ],
                'stock' => [
                    'quantity' => $stock ? (float) $stock->quantity : 0.00,
                    'low_stock_threshold' => $stock ? (float) $stock->low_stock_threshold : 0.00,
                    'updated_at' => $stock && $stock->updated_at 
                        ? $stock->updated_at->format('Y-m-d H:i:s') 
                        : null,
                ],
            ];
        })->toArray();
    }

    /**
     * Get deleted products (soft deleted after last sync)
     */
    private function getDeletedProducts(int $shopId, ?Carbon $lastSyncAt): array
    {
        if (!$lastSyncAt) {
            return [];
        }

        $query = ShopProduct::onlyTrashed()
            ->whereNull('shop_id') // Company products only
            ->where('deleted_at', '>', $lastSyncAt);

        $products = $query->get();

        return $products->map(function($product) {
            return [
                'id' => $product->id,
                'server_id' => $product->id,
                'local_id' => $product->local_id,
                'deleted_at' => $product->deleted_at 
                    ? $product->deleted_at->format('Y-m-d H:i:s') 
                    : null,
            ];
        })->toArray();
    }
}

