<?php

namespace App\Services;

use App\Models\Order;
use App\Models\PurchaseOrder;
use App\Models\PurchaseOrderItem;
use App\Models\ProductVariant;
use App\Models\Supplier;
use App\Models\User;
use App\Notifications\OrderReadyForAssemblyNotification;
use App\Notifications\PurchaseOrderCreatedNotification;

class SupplierSyncService
{
    /**
     * إنشاء أوامر شراء تلقائية لكل أصناف الطلب.
     * تجميع الأصناف حسب المورد: أمر شراء واحد لكل مورد.
     * المنتجات بدون مورد تُضاف لأمر "مخزن الشركة".
     *
     * @return int عدد أوامر الشراء المُنشأة
     */
    public function createPurchaseOrders(Order $order): int
    {
        $order->load('items.variant.product.supplier', 'items.variant.defaultSupplier');

        $companyWarehouseId = Supplier::getCompanyWarehouseId();
        if (! $companyWarehouseId) {
            return 0;
        }

        $groupedBySupplier = [];

        foreach ($order->items as $item) {
            $variant = $item->variant;
            $product = $variant?->product;

            $supplierId = $variant->default_supplier_id
                ?? $product?->supplier_id
                ?? $companyWarehouseId;

            if (! isset($groupedBySupplier[$supplierId])) {
                $groupedBySupplier[$supplierId] = [];
            }

            $groupedBySupplier[$supplierId][] = [
                'variant_id' => $variant->id,
                'quantity' => $item->quantity,
                'unit_cost' => (float) $variant->cost_price,
            ];
        }

        foreach ($groupedBySupplier as $supplierId => $items) {
            $totalCost = 0;
            foreach ($items as $item) {
                $totalCost += $item['quantity'] * $item['unit_cost'];
            }

            $po = PurchaseOrder::create([
                'supplier_id' => $supplierId,
                'source_order_id' => $order->id,
                'status' => PurchaseOrder::STATUS_DRAFT,
                'total_cost' => $totalCost,
                'notes' => "أمر شراء تلقائي من الطلب #{$order->id}",
            ]);

            foreach ($items as $item) {
                PurchaseOrderItem::create([
                    'purchase_order_id' => $po->id,
                    'variant_id' => $item['variant_id'],
                    'quantity' => $item['quantity'],
                    'unit_cost' => $item['unit_cost'],
                ]);
            }

            $supplier = $po->supplier;
            if ($supplier && ! $supplier->is_company_warehouse && $supplier->email) {
                try {
                    $supplier->notify(new PurchaseOrderCreatedNotification($po));
                } catch (\Throwable $e) {
                    report($e);
                }
            }
        }

        $order->items()->update(['fulfillment_status' => 'awaiting_supplier']);

        return count($groupedBySupplier);
    }

    /**
     * عند تأكيد أمر الشراء، يتم تحديث حالة الأصناف في الطلب الأصلي.
     */
    public function onPurchaseOrderConfirmed(PurchaseOrder $po): void
    {
        if (! $po->source_order_id) {
            return;
        }

        $po->sourceOrder->update(['status' => Order::STATUS_ORDERED_FROM_SUPPLIER]);

        $variantIds = $po->items->pluck('variant_id');

        $po->sourceOrder->items()
            ->whereIn('variant_id', $variantIds)
            ->update(['fulfillment_status' => 'ordered']);
    }

    /**
     * عند استلام أمر الشراء:
     * - مورد خارجي: زيادة المخزون، تحديث الرصيد، ثم خصم (للتسليم).
     * - مخزن الشركة: فقط تحديث حالة الأصناف (لا تغيير مخزون).
     */
    public function onPurchaseOrderReceived(PurchaseOrder $po): void
    {
        $supplier = $po->supplier;
        $isCompanyWarehouse = $supplier && $supplier->is_company_warehouse;

        if (! $isCompanyWarehouse) {
            foreach ($po->items as $poItem) {
                ProductVariant::where('id', $poItem->variant_id)
                    ->increment('stock', $poItem->quantity);
            }
            $supplier->increment('current_balance', (float) $po->total_cost);
        }

        if (! $po->source_order_id) {
            return;
        }

        $sourceOrder = $po->sourceOrder;
        $variantIds = $po->items->pluck('variant_id');

        $sourceOrder->items()
            ->whereIn('variant_id', $variantIds)
            ->update(['fulfillment_status' => 'received']);

        if (! $isCompanyWarehouse) {
            foreach ($po->items as $poItem) {
                ProductVariant::where('id', $poItem->variant_id)
                    ->decrement('stock', $poItem->quantity);
            }
        }

        $sourceOrder->items()
            ->whereIn('variant_id', $variantIds)
            ->update(['fulfillment_status' => 'ready']);

        $allReady = ! $sourceOrder->items()
            ->where('fulfillment_status', '!=', 'ready')
            ->exists();

        if ($allReady) {
            $sourceOrder->update(['status' => Order::STATUS_PROCESSING]);

            $admins = User::where('is_admin', true)->where('is_active', true)->get();
            foreach ($admins as $admin) {
                $admin->notify(new OrderReadyForAssemblyNotification($sourceOrder));
            }
        } else {
            $sourceOrder->update(['status' => Order::STATUS_RECEIVED_FROM_SUPPLIER]);
        }
    }
}
