<?php
declare(strict_types=1);

namespace App\Modules\Sales\Services;

use App\Core\App;
use App\Core\Logger;

final class PackageService
{
    /**
     * Create a package with its component items.
     *
     * @param array $header Keys: code, name_ar, name_en, description_ar, package_price_member,
     *                             package_price_nonmember, active_from, active_to, notes
     * @param array $items  Each: ['item_id' => int, 'quantity' => string]
     * @return int package ID
     */
    public static function createPackage(array $header, array $items): int
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        if (empty($items)) {
            throw new \RuntimeException('يجب إضافة صنف واحد على الأقل للباقة');
        }

        // Calculate items total price
        $itemsTotalPrice = '0.00';
        foreach ($items as $item) {
            $itemRow = $db->selectOne(
                "SELECT `sale_price_member` FROM `inventory_items` WHERE `id` = ?",
                [(int) $item['item_id']]
            );
            if ($itemRow) {
                $linePrice = bcmul((string) ($itemRow['sale_price_member'] ?? '0'), (string) $item['quantity'], 2);
                $itemsTotalPrice = bcadd($itemsTotalPrice, $linePrice, 2);
            }
        }

        $db->beginTransaction();
        try {
            $packageId = $db->insert('packages', [
                'code'                    => $header['code'],
                'name_ar'                 => $header['name_ar'],
                'name_en'                 => $header['name_en'] ?? null,
                'description_ar'          => $header['description_ar'] ?? null,
                'package_price_member'    => $header['package_price_member'],
                'package_price_nonmember' => $header['package_price_nonmember'],
                'items_total_price'       => $itemsTotalPrice,
                'active_from'             => $header['active_from'] ?? null,
                'active_to'               => $header['active_to'] ?? null,
                'is_active'               => 1,
                'notes'                   => $header['notes'] ?? null,
                'created_by'              => $employee ? (int) $employee->id : null,
                'created_at'              => date('Y-m-d H:i:s'),
                'updated_at'              => date('Y-m-d H:i:s'),
            ]);

            foreach ($items as $i => $item) {
                $db->insert('package_items', [
                    'package_id' => $packageId,
                    'item_id'    => (int) $item['item_id'],
                    'quantity'   => $item['quantity'],
                    'sort_order' => $i,
                ]);
            }

            $db->commit();
        } catch (\Throwable $e) {
            $db->rollBack();
            throw $e;
        }

        Logger::info("Package #{$packageId} ({$header['code']}) created with " . count($items) . " items");

        return $packageId;
    }

    /**
     * Update a package and its items.
     */
    public static function updatePackage(int $packageId, array $header, array $items): void
    {
        $db = App::getInstance()->db();

        // Recalculate items total price
        $itemsTotalPrice = '0.00';
        foreach ($items as $item) {
            $itemRow = $db->selectOne(
                "SELECT `sale_price_member` FROM `inventory_items` WHERE `id` = ?",
                [(int) $item['item_id']]
            );
            if ($itemRow) {
                $linePrice = bcmul((string) ($itemRow['sale_price_member'] ?? '0'), (string) $item['quantity'], 2);
                $itemsTotalPrice = bcadd($itemsTotalPrice, $linePrice, 2);
            }
        }

        $db->beginTransaction();
        try {
            $db->update('packages', [
                'code'                    => $header['code'],
                'name_ar'                 => $header['name_ar'],
                'name_en'                 => $header['name_en'] ?? null,
                'description_ar'          => $header['description_ar'] ?? null,
                'package_price_member'    => $header['package_price_member'],
                'package_price_nonmember' => $header['package_price_nonmember'],
                'items_total_price'       => $itemsTotalPrice,
                'active_from'             => $header['active_from'] ?? null,
                'active_to'               => $header['active_to'] ?? null,
                'notes'                   => $header['notes'] ?? null,
                'updated_at'              => date('Y-m-d H:i:s'),
            ], '`id` = ?', [$packageId]);

            // Replace items
            $db->statement("DELETE FROM `package_items` WHERE `package_id` = ?", [$packageId]);

            foreach ($items as $i => $item) {
                $db->insert('package_items', [
                    'package_id' => $packageId,
                    'item_id'    => (int) $item['item_id'],
                    'quantity'   => $item['quantity'],
                    'sort_order' => $i,
                ]);
            }

            $db->commit();
        } catch (\Throwable $e) {
            $db->rollBack();
            throw $e;
        }
    }
}
