<?php

namespace App\Controllers;

use App\Database;
use App\Models\Item;
use App\Models\Category;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

class ItemController
{
    // Renders the full layout for overview page load
    public static function overview()
    {
        global $twig;
        try {
            echo $twig->render('layout.twig', ['active_page' => 'overview']);
        } catch (Exception $e) {
            echo "Twig Error: " . $e->getMessage();
        }
    }

    // Edit item form (AJAX)
    public function editItem($itemId)
    {
        global $twig;
        try {
            $db = Database::getInstance();
            $item = Item::getById($db, $itemId);
            if (!$item) {
                echo '<div class="alert alert-danger">Item not found</div>';
                return;
            }
            
            // Get all categories for the dropdown
            $categories = Category::getAll($db);
            
            echo $twig->render('partials/item_edit.twig', [
                'item' => $item,
                'categories' => $categories
            ]);
        } catch (Exception $e) {
            echo '<div class="alert alert-danger">Error loading item: ' . htmlspecialchars($e->getMessage()) . '</div>';
        }
    }

    // Renders the full layout for add parts page
    public static function addForm()
    {
        global $twig;
        echo $twig->render('layout.twig', ['active_page' => 'parts']);
    }

    // Get single item (JSON)
    public static function getItem($id) {
        header('Content-Type: application/json');
        try {
            $db = Database::getInstance();
            $item = Item::getById($db, $id);
            if ($item) {
                echo json_encode($item);
            } else {
                http_response_code(404);
                global $translator;
                echo json_encode(['error' => $translator->trans('Part not found')]);
            }
        } catch (Exception $e) {
            error_log('Error in getItem: ' . $e->getMessage());
            http_response_code(500);
            global $translator;
            echo json_encode(['error' => $translator->trans('Server error')]);
        }
    }

    // Returns the HTML content for the add parts page (used by AJAX)
    public static function renderAddForm()
    {
        global $twig;
        try {
            $db = Database::getInstance();
            $categories = Category::getAll($db);

            // Render only the content block
            echo $twig->render('parts.twig', [
                'categories' => $categories,
            ]);
        } catch (\Exception $e) {
            http_response_code(500);
            error_log("Error rendering add form: " . $e->getMessage());
            echo "Error: Could not load add form.";
        }
    }

    // Returns the HTML content for the items page (used by AJAX)
    public static function listItems()
    {
        global $twig;
        try {
            $db = Database::getInstance();
            $search = trim($_GET['search'] ?? '');
            $categoryId = !empty($_GET['category_id']) ? (int)$_GET['category_id'] : null;

            $items = Item::getAllFiltered($db, $search, $categoryId);
            foreach ($items as &$item) {
                if ($item['category_id']) {
                    $item['category_path'] = Category::getFullPath($db, $item['category_id']);
                } else {
                    $item['category_path'] = null;
                }
            }
            $categories = Category::getAll($db);

            // Render only the content block
            echo $twig->render('items.twig', [
                'items' => $items,
                'categories' => $categories,
                'search' => $search,
                'selected_category' => $categoryId,
            ]);
        } catch (\Exception $e) {
            error_log("Error in listItems: " . $e->getMessage());
            http_response_code(500);
            echo "Error: Could not load items.";
        }
    }

    // CRUD operations (returns JSON)
    public static function create() {
        header('Content-Type: application/json');
        try {
            $db = Database::getInstance();
            $data = $_POST;

            $name = trim($data['item_name'] ?? '');
            $description = trim($data['item_description'] ?? '');
            $categoryId = !empty($data['category_id']) ? (int)$data['category_id'] : null;
            $location = trim($data['location'] ?? '');
            $idCode = strtoupper(substr(md5(uniqid()), 0, 8));
            $imagePath = null;

            // Generate unique id_code
            $idCode = self::generateUniqueIdCode($db);

            // Handle image upload
            if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
                $imagePath = self::handleImageUpload($_FILES['image']);
                error_log("Image uploaded: " . $imagePath);
            } else {
                error_log("No image uploaded or error: " . ($_FILES['image']['error'] ?? 'no file'));
            }

            $item = new Item($db, null, $name, $description, $categoryId, null, $idCode, $imagePath, $location);
            if ($item->save()) {
                // Generate QR code
                self::generateQRCode($idCode);
                echo json_encode(['success' => true, 'message' => 'Part added successfully']);
            } else {
                throw new Exception('Failed to save part');
            }
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => $e->getMessage()]);
        }
    }

    private static function generateUniqueIdCode(\PDO $db): string {
        do {
            $code = strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 8));
            $stmt = $db->prepare('SELECT id FROM items WHERE id_code = :code');
            $stmt->execute([':code' => $code]);
        } while ($stmt->fetch());
        return $code;
    }

    private static function handleImageUpload(array $file): ?string {
        $uploadDir = __DIR__ . '/../../public/uploads/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        $safeName = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', basename($file['name']));
        $fileName = uniqid() . '_' . $safeName;
        $targetPath = $uploadDir . $fileName;
        error_log("Attempting to move from " . $file['tmp_name'] . " to " . $targetPath);
        if (move_uploaded_file($file['tmp_name'], $targetPath)) {
            error_log("Image uploaded successfully: " . $targetPath);
            return 'uploads/' . $fileName;
        }
        error_log("Failed to upload image");
        return null;
    }

    private static function generateQRCode(string $idCode): void {
        $qrDir = __DIR__ . '/../../public/uploads/qr/';
        if (!is_dir($qrDir)) {
            mkdir($qrDir, 0755, true);
        }
        $options = new QROptions([
            'outputType' => QRCode::OUTPUT_MARKUP_SVG,
            'eccLevel' => QRCode::ECC_L,
        ]);
        $qrCode = new QRCode($options);
        $qrCode->render($idCode, $qrDir . $idCode . '.svg');
    }

    public static function printQR($id) {
        global $twig;
        $db = Database::getInstance();
        $item = Item::getById($db, $id);
        if (!$item) {
            http_response_code(404);
            echo "Item not found";
            return;
        }
        // Ensure QR code exists
        $qrFile = __DIR__ . '/../../public/uploads/qr/' . $item['id_code'] . '.svg';
        if (!file_exists($qrFile) || strpos(file_get_contents($qrFile), 'data:image/svg+xml;base64,') === 0) {
            self::generateQRCode($item['id_code']);
        }
        echo $twig->render('print_qr.twig', ['item' => $item]);
    }

    public static function update($id) {
        header('Content-Type: application/json');
        try {
            $db = Database::getInstance();
            $data = json_decode(file_get_contents('php://input'), true) ?? $_POST;

            $existing = Item::getById($db, $id);
            if (!$existing) {
                http_response_code(404);
                global $translator;
                echo json_encode(['error' => $translator->trans('Part not found')]);
                return;
            }

            $name = trim($data['item_name'] ?? $existing['name']);
            $description = trim($data['item_description'] ?? $existing['description']);
            $categoryId = isset($data['category_id']) && $data['category_id'] !== '' ? (int)$data['category_id'] : $existing['category_id'];
            $location = trim($data['location'] ?? $existing['location']);
            $idCode = $existing['id_code']; // Keep existing id_code
            $imagePath = $existing['image'];

            // Handle image upload if new file
            if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
                $newImagePath = self::handleImageUpload($_FILES['image']);
                if ($newImagePath) {
                    $imagePath = $newImagePath;
                    error_log("Image updated: " . $imagePath);
                } else {
                    error_log("Image upload failed, keeping existing image");
                }
            } else {
                error_log("No image update or error: " . ($_FILES['image']['error'] ?? 'no file'));
            }

            if (empty($name)) {
                http_response_code(400);
                global $translator;
                echo json_encode(['error' => $translator->trans('Part name is required')]);
                return;
            }

            $item = new Item($db, $id, $name, $description, $categoryId, null, $idCode, $imagePath, $location);
            error_log("Updating item $id with image: $imagePath");
            if ($item->save()) {
                error_log("Item $id updated successfully");
                echo json_encode(['success' => true, 'message' => 'Part updated successfully']);
            } else {
                error_log("Failed to update item $id");
                throw new Exception('Failed to update part');
            }
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => $e->getMessage()]);
        }
    }

    public static function delete($id) {
        header('Content-Type: application/json');
        try {
            $db = Database::getInstance();
            if (Item::delete($db, $id)) {
                echo json_encode(['success' => true, 'message' => 'Part deleted successfully']);
            } else {
                http_response_code(404);
                global $translator;
                echo json_encode(['error' => $translator->trans('Part not found')]);
            }
        } catch (Exception $e) {
            http_response_code(500);
            echo json_encode(['error' => $e->getMessage()]);
        }
    }
}
