<?php

namespace WMS\Controllers;

use WMS\Core\Database;
use WMS\Core\Request;
use WMS\Core\Response;

class ItemController
{
    /**
     * GET /api/items
     * Lista todos los artículos, con búsqueda opcional (?search=term).
     */
    public static function index(array $params): void
    {
        try {
            $db = Database::getConnection();
            $search = Request::query('search');

            $code = Request::query('code');

            $blockedEntry = Request::query('blocked_entry');

            if ($blockedEntry) {
                $stmt = $db->query("SELECT id, item_code, item_name, force_blocked_on_entry, block_entry_reason FROM items WHERE force_blocked_on_entry = 1 ORDER BY item_code");
            } elseif ($code) {
                $stmt = $db->prepare("SELECT id, item_code, item_name FROM items WHERE item_code = ?");
                $stmt->execute([$code]);
            } elseif ($search) {
                $stmt = $db->prepare(
                    "SELECT * FROM items
                     WHERE item_code LIKE ? OR item_name LIKE ? OR barcode LIKE ?
                     ORDER BY item_code ASC
                     LIMIT 200"
                );
                $like = '%' . $search . '%';
                $stmt->execute([$like, $like, $like]);
            } else {
                $limit = (int) (Request::query('limit', 200));
                if ($limit > 5000) $limit = 5000;
                $stmt = $db->query(
                    "SELECT * FROM items ORDER BY item_code ASC LIMIT {$limit}"
                );
            }

            Response::success($stmt->fetchAll());
        } catch (\Throwable $e) {
            Response::error('Error al obtener artículos: ' . $e->getMessage(), 500);
        }
    }

    /**
     * GET /api/items/{id}
     * Detalle de un artículo por ID.
     */
    public static function show(array $params): void
    {
        try {
            $db = Database::getConnection();
            $stmt = $db->prepare("SELECT * FROM items WHERE id = ?");
            $stmt->execute([(int) $params['id']]);
            $item = $stmt->fetch();

            if (!$item) {
                Response::error('Artículo no encontrado', 404);
                return;
            }

            Response::success($item);
        } catch (\Throwable $e) {
            Response::error('Error al obtener artículo: ' . $e->getMessage(), 500);
        }
    }

    /**
     * POST /api/items/block-entry
     * Body: { item_code, reason?, enabled }
     */
    public static function blockEntry(array $params): void
    {
        $body = Request::body();
        if (empty($body['item_code'])) {
            Response::error('item_code requerido', 422);
            return;
        }
        try {
            $db = Database::getConnection();
            $stmt = $db->prepare("SELECT id, item_code FROM items WHERE item_code = ?");
            $stmt->execute([$body['item_code']]);
            $item = $stmt->fetch();
            if (!$item) {
                Response::error('Item ' . $body['item_code'] . ' no encontrado', 404);
                return;
            }
            $enabled = $body['enabled'] ?? true;
            $reason = $body['reason'] ?? null;
            $stmt = $db->prepare("UPDATE items SET force_blocked_on_entry = ?, block_entry_reason = ? WHERE id = ?");
            $stmt->execute([$enabled ? 1 : 0, $enabled ? $reason : null, $item['id']]);
            Response::success(['item_code' => $body['item_code'], 'force_blocked_on_entry' => $enabled ? 1 : 0]);
        } catch (\Throwable $e) {
            Response::error('Error: ' . $e->getMessage(), 500);
        }
    }


    /**
     * GET /api/items/{id}/batches
     * Lista los lotes de un item (con vencimiento y estado).
     */
    public static function batches(array $params): void
    {
        $id = (int) ($params['id'] ?? 0);
        if ($id <= 0) { Response::error('id invalido', 422); return; }
        try {
            $db = Database::getConnection();
            $stmt = $db->prepare(
                "SELECT id, item_id, batch_number, expiry_date, manufacturing_date,
                        supplier_batch, status, sap_batch_num, created_at
                 FROM batches
                 WHERE item_id = ?
                 ORDER BY expiry_date ASC, id DESC
                 LIMIT 200"
            );
            $stmt->execute([$id]);
            Response::success($stmt->fetchAll(\PDO::FETCH_ASSOC));
        } catch (\Throwable $e) {
            Response::error('Error obteniendo lotes: ' . $e->getMessage(), 500);
        }
    }


    /**
     * GET /api/items/{id}/preferred-zone
     * Devuelve la preferencia de zonificación cargada para el item.
     * Acepta {id} como item.id (numérico) o item_code (string).
     */
    public static function preferredZone(array $params): void
    {
        try {
            $db = Database::getConnection();
            $idOrCode = (string) ($params['id'] ?? '');
            if ($idOrCode === '') { Response::error('id requerido', 422); return; }

            // Buscar por item_code primero (códigos GOLIVE son numéricos pero NO son IDs)
            $stmt = $db->prepare("SELECT id, item_code, item_name, item_group FROM items WHERE item_code = ?");
            $stmt->execute([$idOrCode]);
            $item = $stmt->fetch();
            if (!$item && ctype_digit($idOrCode)) {
                $stmt = $db->prepare("SELECT id, item_code, item_name, item_group FROM items WHERE id = ?");
                $stmt->execute([(int) $idOrCode]);
                $item = $stmt->fetch();
            }
            if (!$item) { Response::error('Artículo no encontrado', 404); return; }

            $stmt = $db->prepare(
                "SELECT izp.zone_id, z.code AS zone_code, z.name AS zone_name,
                        izp.preferred_level, izp.max_level, izp.pallet_weight_kg,
                        izp.source, izp.notes, izp.updated_at
                 FROM item_zone_preferences izp
                 LEFT JOIN warehouse_zones z ON z.id = izp.zone_id
                 WHERE izp.item_id = ?"
            );
            $stmt->execute([(int) $item['id']]);
            $pref = $stmt->fetch();

            Response::success([
                'item'       => $item,
                'preference' => $pref ?: null,
            ]);
        } catch (\Throwable $e) {
            Response::error('Error: ' . $e->getMessage(), 500);
        }
    }

}
