<?php
declare(strict_types=1);
namespace App\Controllers;

use App\Core\Controller;
use App\Core\SessionAuth;
use App\Repositories\CategoryRepository;
use App\Repositories\ItemRepository;

final class ItemController extends Controller {
    public function index(): void {
        app()->get(SessionAuth::class)->requireLogin();
        $filters = [
            'category_id' => (int)($_GET['category_id'] ?? 0),
            'status' => trim((string)($_GET['status'] ?? '')),
            'q' => trim((string)($_GET['q'] ?? '')),
        ];
        $repo = new ItemRepository();
        $items = $repo->allWithFilters($filters);
        $categories = (new CategoryRepository())->active();
        $this->view('items/index', compact('items','categories','filters'));
    }

    public function create(): void {
        app()->get(SessionAuth::class)->requireLogin();
        $categories = (new CategoryRepository())->active();
        $locations = (new ItemRepository())->activeLocations();
        $item = [
            'id' => 0,
            'category_id' => 0,
            'location_id' => null,
            'item_code' => '',
            'item_name' => '',
            'default_price' => '0.000',
            'item_type' => 'rental_or_sale',
            'item_status' => 'available',
            'barcode_value' => '',
            'is_active' => 1,
            'images_json' => json_encode([], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES),
            'primary_image' => '',
        ];
        $mode = 'create';
        $this->view('items/form', compact('item', 'categories', 'locations', 'mode'));
    }

    public function store(): void {
        app()->get(SessionAuth::class)->requireLogin();
        verify_csrf();

        $data = $this->collectFormData();
        $repo = new ItemRepository();

        if ($repo->codeExists($data['item_code'])) {
            flash('error', 'رقم / كود القطعة مستخدم مسبقًا');
            redirect(base_url('?page=item_create'));
        }

        $itemId = $repo->create($data);

        [$keepExisting, $uploadedImages, $primaryChoice] = $this->collectImagePayload();
        $repo->syncImages($itemId, $keepExisting, $uploadedImages, $primaryChoice);

        flash('success', 'تمت إضافة القطعة بنجاح');
        redirect(base_url('?page=items'));
    }

    public function edit(): void {
        app()->get(SessionAuth::class)->requireLogin();
        $id = (int)($_GET['id'] ?? 0);
        $repo = new ItemRepository();
        $item = $repo->find($id);
        if (!$item) {
            http_response_code(404);
            $this->view('errors/404');
            return;
        }
        $categories = (new CategoryRepository())->active();
        $locations = $repo->activeLocations();
        $mode = 'edit';
        $this->view('items/form', compact('item', 'categories', 'locations', 'mode'));
    }

    public function update(): void {
        app()->get(SessionAuth::class)->requireLogin();
        verify_csrf();

        $id = (int)($_POST['id'] ?? 0);
        if ($id <= 0) {
            flash('error', 'معرّف القطعة غير صالح');
            redirect(base_url('?page=items'));
        }

        $data = $this->collectFormData();
        $repo = new ItemRepository();

        if ($repo->codeExists($data['item_code'], $id)) {
            flash('error', 'رقم / كود القطعة مستخدم مسبقًا');
            redirect(base_url('?page=item_edit&id=' . $id));
        }

        $repo->updateItem($id, $data);

        [$keepExisting, $uploadedImages, $primaryChoice] = $this->collectImagePayload();
        $repo->syncImages($id, $keepExisting, $uploadedImages, $primaryChoice);

        flash('success', 'تم تحديث بيانات القطعة بنجاح');
        redirect(base_url('?page=items'));
    }

    public function delete(): void {
        app()->get(SessionAuth::class)->requireLogin();
        verify_csrf();

        $id = (int)($_POST['id'] ?? 0);
        if ($id > 0) {
            (new ItemRepository())->softDelete($id);
            flash('success', 'تم حذف القطعة بنجاح');
        }
        redirect(base_url('?page=items'));
    }

    public function available(): void {
        app()->get(SessionAuth::class)->requireLogin();
        header('Content-Type: application/json; charset=utf-8');
        $categoryId = (int)($_GET['category_id'] ?? 0);
        $deliveryDate = trim((string)($_GET['delivery_date'] ?? date('Y-m-d')));
        $returnDate = trim((string)($_GET['return_date'] ?? date('Y-m-d')));
        echo json_encode((new ItemRepository())->availableForPeriod($categoryId ?: null, $deliveryDate, $returnDate), JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    }

    public function publicSchedule(): void {
        $id = (int)($_GET['id'] ?? 0);
        $item = (new ItemRepository())->findWithSchedule($id);
        if (!$item) {
            http_response_code(404);
            $this->view('errors/404');
            return;
        }
        $this->view('items/public_schedule', compact('item'));
    }

    public function printBulkBarcodes(): void {
        app()->get(SessionAuth::class)->requireLogin();
        $repo = new ItemRepository();
        $idsRaw = trim((string)($_GET['ids'] ?? ''));
        $items = [];
        if ($idsRaw !== '') {
            $ids = array_values(array_filter(array_map('intval', explode(',', $idsRaw))));
            foreach ($ids as $id) { $it = $repo->findWithSchedule($id); if ($it) { $it['publicUrl'] = base_url('?page=item_public&id=' . (int)$it['id']); $items[] = $it; } }
        } else {
            $filters = ['category_id' => (int)($_GET['category_id'] ?? 0), 'status' => trim((string)($_GET['status'] ?? '')), 'q' => trim((string)($_GET['q'] ?? ''))];
            foreach ($repo->filteredItems($filters) as $it) { $full = $repo->findWithSchedule((int)$it['id']); if ($full) { $full['publicUrl']=base_url('?page=item_public&id='.(int)$full['id']); $items[]=$full; } }
        }
        $this->view('items/barcodes_bulk', compact('items'));
    }

    public function printBarcode(): void {
        app()->get(SessionAuth::class)->requireLogin();
        $id = (int)($_GET['id'] ?? 0);
        $item = (new ItemRepository())->findWithSchedule($id);
        if (!$item) {
            http_response_code(404);
            $this->view('errors/404');
            return;
        }
        $publicUrl = base_url('?page=item_public&id=' . (int)$item['id']);
        $this->view('items/barcode', compact('item', 'publicUrl'));
    }

    private function collectFormData(): array {
        $categoryId = (int)($_POST['category_id'] ?? 0);
        $itemCode = trim((string)($_POST['item_code'] ?? ''));
        $itemName = trim((string)($_POST['item_name'] ?? ''));
        $defaultPrice = (float)($_POST['default_price'] ?? 0);
        $itemType = (string)($_POST['item_type'] ?? 'rental_or_sale');
        $itemStatus = (string)($_POST['item_status'] ?? 'available');
        $locationId = (int)($_POST['location_id'] ?? 0);
        $barcodeValue = trim((string)($_POST['barcode_value'] ?? ''));
        $isActive = (int)($_POST['is_active'] ?? 0);

        if ($categoryId <= 0 || $itemCode === '') {
            flash('error', 'يرجى تعبئة الفئة ورقم القطعة على الأقل');
            redirect(base_url('?page=items'));
        }

        $allowedTypes = ['rental', 'sale', 'rental_or_sale'];
        if (!in_array($itemType, $allowedTypes, true)) {
            $itemType = 'rental_or_sale';
        }

        $allowedStatuses = ['available','reserved','rented','maintenance','missing','sold'];
        if (!in_array($itemStatus, $allowedStatuses, true)) {
            $itemStatus = 'available';
        }

        return [
            'category_id' => $categoryId,
            'location_id' => $locationId > 0 ? $locationId : null,
            'item_code' => $itemCode,
            'item_name' => $itemName,
            'default_price' => $defaultPrice,
            'item_type' => $itemType,
            'item_status' => $itemStatus,
            'barcode_value' => $barcodeValue,
            'is_active' => $isActive ? 1 : 0,
        ];
    }

    private function collectImagePayload(): array {
        $keepExisting = array_values(array_filter(array_map('trim', (array)($_POST['existing_images'] ?? []))));
        $removeExisting = array_values(array_filter(array_map('trim', (array)($_POST['remove_existing_images'] ?? []))));
        if ($removeExisting) {
            $keepExisting = array_values(array_filter($keepExisting, fn($p) => !in_array($p, $removeExisting, true)));
        }

        $uploadedImages = [];
        if (!empty($_FILES['item_images']['name']) && is_array($_FILES['item_images']['name'])) {
            $dir = dirname(__DIR__, 2) . '/storage/uploads/items';
            if (!is_dir($dir)) {
                @mkdir($dir, 0777, true);
            }
            $allowed = ['jpg','jpeg','png','webp','gif'];

            foreach ($_FILES['item_images']['name'] as $idx => $name) {
                $tmp = $_FILES['item_images']['tmp_name'][$idx] ?? '';
                $err = (int)($_FILES['item_images']['error'][$idx] ?? UPLOAD_ERR_NO_FILE);
                if ($err !== UPLOAD_ERR_OK || !is_uploaded_file($tmp)) {
                    continue;
                }
                $ext = strtolower(pathinfo((string)$name, PATHINFO_EXTENSION));
                if (!in_array($ext, $allowed, true)) {
                    continue;
                }
                $newName = 'item_' . date('Ymd_His') . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
                $target = $dir . '/' . $newName;
                if (@move_uploaded_file($tmp, $target)) {
                    $uploadedImages[] = 'storage/uploads/items/' . $newName;
                }
            }
        }

        $primaryChoice = trim((string)($_POST['primary_image_choice'] ?? ''));
        $total = count($keepExisting) + count($uploadedImages);
        if ($total > 5) {
            flash('error', 'الحد الأقصى للصور هو 5 صور فقط');
            redirect(base_url(isset($_POST['id']) && (int)$_POST['id'] > 0 ? '?page=item_edit&id=' . (int)$_POST['id'] : '?page=item_create'));
        }

        return [$keepExisting, $uploadedImages, $primaryChoice];
    }
}
