<?php
declare(strict_types=1);

namespace App\Modules\Procurement\Services;

use App\Core\App;
use App\Core\EventBus;

final class QuoteService
{
    public static function createQuoteRequest(int $requisitionId, array $supplierIds): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $requisition = $db->selectOne("SELECT * FROM purchase_requisitions WHERE id = ?", [$requisitionId]);
        if (!$requisition) {
            return ['success' => false, 'error' => 'طلب الشراء غير موجود'];
        }

        $items = $db->select(
            "SELECT * FROM purchase_requisition_items WHERE requisition_id = ?",
            [$requisitionId]
        );

        $db->beginTransaction();
        try {
            $quoteIds = [];
            foreach ($supplierIds as $supplierId) {
                $quoteNumber = 'QR-' . date('Ymd') . '-' . str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT);

                $quoteId = $db->insert('supplier_price_quotes', [
                    'quote_number' => $quoteNumber,
                    'requisition_id' => $requisitionId,
                    'supplier_id' => (int) $supplierId,
                    'request_date' => date('Y-m-d'),
                    'status' => 'requested',
                    'created_by' => $employee ? (int) $employee->id : null,
                ]);

                foreach ($items as $item) {
                    $db->insert('supplier_quote_items', [
                        'quote_id' => $quoteId,
                        'item_id' => (int) $item['item_id'],
                        'item_description' => $item['description'] ?? null,
                        'quantity' => $item['quantity'],
                        'unit_price' => '0.00',
                        'total_price' => '0.00',
                    ]);
                }

                $quoteIds[] = $quoteId;
            }

            $db->commit();

            EventBus::dispatch('quote.requested', [
                'requisition_id' => $requisitionId,
                'quote_ids' => $quoteIds,
            ]);

            return ['success' => true, 'quote_ids' => $quoteIds];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public static function recordQuoteResponse(int $quoteId, array $items, array $terms = []): array
    {
        $db = App::getInstance()->db();

        $quote = $db->selectOne("SELECT * FROM supplier_price_quotes WHERE id = ?", [$quoteId]);
        if (!$quote) {
            return ['success' => false, 'error' => 'عرض السعر غير موجود'];
        }

        $db->beginTransaction();
        try {
            $totalAmount = '0.00';

            foreach ($items as $item) {
                $total = bcmul((string) $item['unit_price'], (string) $item['quantity'], 2);
                $totalAmount = bcadd($totalAmount, $total, 2);

                $db->update('supplier_quote_items', [
                    'unit_price' => $item['unit_price'],
                    'total_price' => $total,
                    'delivery_days' => $item['delivery_days'] ?? null,
                    'notes' => $item['notes'] ?? null,
                ], 'id = ?', [(int) $item['quote_item_id']]);
            }

            $db->update('supplier_price_quotes', [
                'status' => 'received',
                'response_date' => date('Y-m-d'),
                'total_amount' => $totalAmount,
                'delivery_terms' => $terms['delivery_terms'] ?? null,
                'payment_terms' => $terms['payment_terms'] ?? null,
                'expiry_date' => $terms['expiry_date'] ?? null,
            ], 'id = ?', [$quoteId]);

            $db->commit();
            return ['success' => true, 'total_amount' => $totalAmount];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public static function evaluateQuotes(int $requisitionId, int $winningQuoteId, string $justification): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $evalNumber = 'EVAL-' . date('Ymd') . '-' . str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT);

        $db->beginTransaction();
        try {
            $evalId = $db->insert('quote_evaluations', [
                'evaluation_number' => $evalNumber,
                'requisition_id' => $requisitionId,
                'evaluation_date' => date('Y-m-d'),
                'status' => 'completed',
                'winning_quote_id' => $winningQuoteId,
                'justification' => $justification,
                'evaluated_by' => $employee ? (int) $employee->id : null,
            ]);

            $db->update('supplier_price_quotes', ['status' => 'accepted', 'evaluation_id' => $evalId], 'id = ?', [$winningQuoteId]);

            $db->query(
                "UPDATE supplier_price_quotes SET status = 'rejected' WHERE requisition_id = ? AND id != ? AND status = 'received'",
                [$requisitionId, $winningQuoteId]
            );

            $db->commit();

            EventBus::dispatch('quote.evaluated', [
                'evaluation_id' => $evalId,
                'winning_quote_id' => $winningQuoteId,
                'requisition_id' => $requisitionId,
            ]);

            return ['success' => true, 'evaluation_id' => $evalId];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public static function convertToPurchaseOrder(int $evaluationId): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $eval = $db->selectOne("SELECT * FROM quote_evaluations WHERE id = ?", [$evaluationId]);
        if (!$eval || !$eval['winning_quote_id']) {
            return ['success' => false, 'error' => 'التقييم غير موجود أو لم يتم اختيار فائز'];
        }

        $quote = $db->selectOne("SELECT * FROM supplier_price_quotes WHERE id = ?", [(int) $eval['winning_quote_id']]);
        $quoteItems = $db->select("SELECT * FROM supplier_quote_items WHERE quote_id = ?", [(int) $eval['winning_quote_id']]);

        $db->beginTransaction();
        try {
            $poNumber = 'PO-' . date('Ymd') . '-' . str_pad((string) random_int(1, 9999), 4, '0', STR_PAD_LEFT);

            $poId = $db->insert('purchase_orders', [
                'po_number' => $poNumber,
                'supplier_id' => (int) $quote['supplier_id'],
                'requisition_id' => $quote['requisition_id'],
                'status' => 'draft',
                'total_amount' => $quote['total_amount'],
                'payment_terms' => $quote['payment_terms'],
                'delivery_terms' => $quote['delivery_terms'],
                'notes' => 'تم إنشاؤه من تقييم عروض الأسعار: ' . $eval['evaluation_number'],
                'created_by' => $employee ? (int) $employee->id : null,
                'created_at' => date('Y-m-d H:i:s'),
            ]);

            foreach ($quoteItems as $qi) {
                $db->insert('purchase_order_items', [
                    'purchase_order_id' => $poId,
                    'item_id' => (int) $qi['item_id'],
                    'quantity' => $qi['quantity'],
                    'unit_price' => $qi['unit_price'],
                    'total_price' => $qi['total_price'],
                    'expected_delivery_date' => $qi['delivery_days']
                        ? date('Y-m-d', strtotime("+{$qi['delivery_days']} days"))
                        : null,
                ]);
            }

            $db->update('quote_evaluations', ['purchase_order_id' => $poId, 'status' => 'approved'], 'id = ?', [$evaluationId]);

            $db->commit();

            EventBus::dispatch('purchase_order.created', ['po_id' => $poId, 'from_evaluation' => $evaluationId]);

            return ['success' => true, 'po_id' => $poId, 'po_number' => $poNumber];
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    public static function getComparisonData(int $requisitionId): array
    {
        $db = App::getInstance()->db();

        $quotes = $db->select(
            "SELECT q.*, s.name_ar as supplier_name, s.code as supplier_code
             FROM supplier_price_quotes q
             JOIN suppliers s ON s.id = q.supplier_id
             WHERE q.requisition_id = ? AND q.status IN ('received','accepted','rejected')
             ORDER BY q.total_amount ASC",
            [$requisitionId]
        );

        $items = $db->select(
            "SELECT pri.item_id, i.name_ar as item_name, i.sku, pri.quantity
             FROM purchase_requisition_items pri
             JOIN inventory_items i ON i.id = pri.item_id
             WHERE pri.requisition_id = ?",
            [$requisitionId]
        );

        $comparison = [];
        foreach ($items as $item) {
            $itemQuotes = [];
            foreach ($quotes as $quote) {
                $qi = $db->selectOne(
                    "SELECT * FROM supplier_quote_items WHERE quote_id = ? AND item_id = ?",
                    [(int) $quote['id'], (int) $item['item_id']]
                );
                $itemQuotes[] = [
                    'quote_id' => (int) $quote['id'],
                    'supplier_name' => $quote['supplier_name'],
                    'unit_price' => $qi['unit_price'] ?? '0.00',
                    'total_price' => $qi['total_price'] ?? '0.00',
                    'delivery_days' => $qi['delivery_days'] ?? null,
                ];
            }
            $comparison[] = [
                'item_id' => (int) $item['item_id'],
                'item_name' => $item['item_name'],
                'sku' => $item['sku'],
                'quantity' => $item['quantity'],
                'quotes' => $itemQuotes,
            ];
        }

        return ['quotes' => $quotes, 'items' => $items, 'comparison' => $comparison];
    }
}
