<?php
declare(strict_types=1);

namespace App\Modules\Sales\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Sales\Models\Package;
use App\Modules\Sales\Models\PackageItem;
use App\Modules\Sales\Services\PackageService;
use App\Modules\Inventory\Models\InventoryItem;

class PackageController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'q'         => trim((string) $request->get('q', '')),
            'is_active' => $request->get('is_active', ''),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = Package::search($filters, 25, $page);

        return $this->view('Sales.Views.packages.index', [
            'packages'   => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
        ]);
    }

    public function create(Request $request): Response
    {
        return $this->view('Sales.Views.packages.form', [
            'package' => null,
            'items'   => InventoryItem::allSellable(),
            'packageItems' => [],
        ]);
    }

    public function store(Request $request): Response
    {
        $header = $this->extractHeader($request);
        $items = $this->extractItems($request);

        $errors = $this->validateInput($header);

        // Unique code
        if ($header['code'] !== '') {
            $existing = Package::query()->where('code', '=', $header['code'])->first();
            if ($existing) {
                $errors[] = 'كود الباقة مستخدم بالفعل';
            }
        }

        if (empty($items)) {
            $errors[] = 'يجب إضافة صنف واحد على الأقل';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/sales/packages/create');
        }

        try {
            $packageId = PackageService::createPackage($header, $items);
            return $this->redirect('/sales/packages/' . $packageId)->withSuccess('تم إنشاء الباقة بنجاح');
        } catch (\RuntimeException $e) {
            return $this->redirect('/sales/packages/create')->withError($e->getMessage());
        }
    }

    public function show(Request $request, string $id): Response
    {
        $package = Package::find((int) $id);
        if (!$package) {
            return $this->redirect('/sales/packages')->withError('الباقة غير موجودة');
        }

        $packageItems = PackageItem::getForPackage((int) $id);

        return $this->view('Sales.Views.packages.show', [
            'package'      => $package,
            'packageItems' => $packageItems,
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $package = Package::find((int) $id);
        if (!$package) {
            return $this->redirect('/sales/packages')->withError('الباقة غير موجودة');
        }

        return $this->view('Sales.Views.packages.form', [
            'package'      => $package,
            'items'        => InventoryItem::allSellable(),
            'packageItems' => PackageItem::getForPackage((int) $id),
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $package = Package::find((int) $id);
        if (!$package) {
            return $this->redirect('/sales/packages')->withError('الباقة غير موجودة');
        }

        $header = $this->extractHeader($request);
        $items = $this->extractItems($request);

        $errors = $this->validateInput($header);

        // Unique code (exclude current)
        if ($header['code'] !== '') {
            $existing = Package::query()
                ->where('code', '=', $header['code'])
                ->whereRaw('`id` != ?', [(int) $id])
                ->first();
            if ($existing) {
                $errors[] = 'كود الباقة مستخدم بالفعل';
            }
        }

        if (empty($items)) {
            $errors[] = 'يجب إضافة صنف واحد على الأقل';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/sales/packages/' . $id . '/edit');
        }

        try {
            PackageService::updatePackage((int) $id, $header, $items);
            return $this->redirect('/sales/packages/' . $id)->withSuccess('تم تحديث الباقة بنجاح');
        } catch (\RuntimeException $e) {
            return $this->redirect('/sales/packages/' . $id . '/edit')->withError($e->getMessage());
        }
    }

    private function extractHeader(Request $request): array
    {
        return [
            'code'                    => strtoupper(trim((string) $request->post('code', ''))),
            'name_ar'                 => trim((string) $request->post('name_ar', '')),
            'name_en'                 => trim((string) $request->post('name_en', '')) ?: null,
            'description_ar'          => trim((string) $request->post('description_ar', '')) ?: null,
            'package_price_member'    => trim((string) $request->post('package_price_member', '0')),
            'package_price_nonmember' => trim((string) $request->post('package_price_nonmember', '0')),
            'active_from'             => $request->post('active_from') ?: null,
            'active_to'               => $request->post('active_to') ?: null,
            'notes'                   => trim((string) $request->post('notes', '')) ?: null,
        ];
    }

    private function extractItems(Request $request): array
    {
        $itemIds    = $request->post('item_ids', []);
        $quantities = $request->post('quantities', []);

        $items = [];
        foreach ($itemIds as $i => $itemId) {
            $qty = (string) ($quantities[$i] ?? '0');
            if ((int) $itemId > 0 && bccomp($qty, '0', 3) > 0) {
                $items[] = ['item_id' => (int) $itemId, 'quantity' => $qty];
            }
        }
        return $items;
    }

    private function validateInput(array $header): array
    {
        $errors = [];
        if ($header['code'] === '') $errors[] = 'كود الباقة مطلوب';
        if ($header['name_ar'] === '' || mb_strlen($header['name_ar']) < 2) $errors[] = 'اسم الباقة بالعربي مطلوب';
        if (bccomp($header['package_price_member'], '0', 2) <= 0) $errors[] = 'سعر الباقة للأعضاء يجب أن يكون أكبر من صفر';
        if (bccomp($header['package_price_nonmember'], '0', 2) <= 0) $errors[] = 'سعر الباقة لغير الأعضاء يجب أن يكون أكبر من صفر';
        return $errors;
    }
}
