<?php

require_once APP_ROOT . '/models/Item.php';
require_once APP_ROOT . '/models/Subcollection.php';
require_once APP_ROOT . '/models/ItemVariant.php';
require_once APP_ROOT . '/models/ConditionOption.php';
require_once APP_ROOT . '/models/VariantTypeOption.php';
require_once APP_ROOT . '/models/ItemImage.php';
require_once APP_ROOT . '/models/Collection.php';

class ItemController
{
    private Item $itemModel;
    private PDO $db;

    public function __construct()
    {
        if (!Session::isLoggedIn()) {
            header('Location: ' . APP_URL . '/login');
            exit;
        }
        $this->itemModel = new Item();
    }

    private function getBanknoteConditionOptions(): array
    {
        return (new ConditionOption())->getByType('banknote');
    }

    public function create(string $subcollection_id): void
    {
        $subModel = new Subcollection();
        $subcollection = $subModel->getWithCollection((int)$subcollection_id);
        if (!$subcollection) {
            header('Location: ' . APP_URL . '/home');
            exit;
        }
        $conditionOptions = $this->getBanknoteConditionOptions();
        $variantTypeOptions = (new VariantTypeOption())->getAll();
        require APP_ROOT . '/views/items/create.php';
    }

    public function store(): void
    {
        if (!Session::verifyCsrfToken($_POST['csrf_token'] ?? '')) {
            Session::flash('error', 'Invalid request.');
            header('Location: ' . APP_URL . '/home');
            exit;
        }

        
        $subcollectionId = (int)($_POST['subcollection_id'] ?? 0);

        $data = [
            'subcollection_id'   => $subcollectionId,
            'nominal_value'      => trim($_POST['nominal_value'] ?? ''),
            'dimensions'         => trim($_POST['dimensions'] ?? ''),
            'color'              => trim($_POST['color'] ?? ''),
            'description_obverse'=> trim($_POST['description_obverse'] ?? ''),
            'description_reverse'=> trim($_POST['description_reverse'] ?? ''),
            'issue_date'         => trim($_POST['issue_date'] ?? ''),
            'additional_info'    => trim($_POST['additional_info'] ?? ''),
            'catalog_number'     => trim($_POST['catalog_number'] ?? ''),
            'country'            => trim($_POST['country'] ?? ''),
            'purchase_price'     => trim($_POST['purchase_price'] ?? ''),
            'note'               => trim($_POST['note'] ?? ''),
        ];

        // Handle obverse image upload
        if (!empty($_FILES['image_obverse']['name'])) {
            $result = FileUpload::upload($_FILES['image_obverse'], UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
            if ($result['success']) {
                $data['image_obverse'] = $result['filename'];
                // Create thumbnail for banknote (170x80)
                $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
            } else {
                Session::flash('error', $result['error']);
                header('Location: ' . APP_URL . '/subcollections/' . $subcollectionId . '/items/create');
                exit;
            }
        } elseif (!empty($_POST['numista_image_obverse'])) {
            // Handle Numista downloaded image
            $data['image_obverse'] = $_POST['numista_image_obverse'];
            // Create thumbnail for banknote (170x80)
            $thumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_obverse'], UPLOAD_ITEMS_THUMBS_PATH);
            FileUpload::createThumbnail(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_obverse'], $thumbPath, 170, 80, 70);
        }

        // Handle reverse image upload
        if (!empty($_FILES['image_reverse']['name'])) {
            $result = FileUpload::upload($_FILES['image_reverse'], UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
            if ($result['success']) {
                $data['image_reverse'] = $result['filename'];
                // Create thumbnail for banknote (170x80)
                $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
            } else {
                Session::flash('error', $result['error']);
                header('Location: ' . APP_URL . '/subcollections/' . $subcollectionId . '/items/create');
                exit;
            }
        } elseif (!empty($_POST['numista_image_reverse'])) {
            // Handle Numista downloaded image
            $data['image_reverse'] = $_POST['numista_image_reverse'];
            // Create thumbnail for banknote (170x80)
            $thumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_reverse'], UPLOAD_ITEMS_THUMBS_PATH);
            FileUpload::createThumbnail(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_reverse'], $thumbPath, 170, 80, 70);
        }

        $itemId = $this->itemModel->create($data);

        // Handle additional images upload
        if (!empty($_FILES['additional_images']['name'][0])) {
            $imageModel = new ItemImage();
            foreach ($_FILES['additional_images']['name'] as $i => $name) {
                if (empty($name)) continue;
                $file = [
                    'name'     => $_FILES['additional_images']['name'][$i],
                    'type'     => $_FILES['additional_images']['type'][$i],
                    'tmp_name' => $_FILES['additional_images']['tmp_name'][$i],
                    'error'    => $_FILES['additional_images']['error'][$i],
                    'size'     => $_FILES['additional_images']['size'][$i],
                ];
                $result = FileUpload::upload($file, UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
                if ($result['success']) {
                    // Create thumbnail for banknote (170x80)
                    $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                    FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
                    
                    $imageModel->create([
                        'item_id'    => $itemId,
                        'filename'   => $result['filename'],
                        'sort_order' => $i,
                    ]);
                }
            }
        }

        // Save variants
        $variantModel = new ItemVariant();
        $conditions = $_POST['variant_condition'] ?? [];
        $variantTypes = $_POST['variant_type'] ?? [];
        $notes = $_POST['variant_note'] ?? [];
        $ownedArr = $_POST['variant_owned'] ?? [];

        foreach ($conditions as $i => $condId) {
            $variantModel->create([
                'item_id'         => $itemId,
                'condition_id'    => (int)($condId) ?: null,
                'variant_type_id' => (int)($variantTypes[$i] ?? 0) ?: null,
                'note'            => trim($notes[$i] ?? ''),
                'owned'           => isset($ownedArr[$i]) ? 1 : 0,
                'sort_order'      => $i,
            ]);
        }

        $view = $_POST['view'] ?? 'grid';
        Session::flash('success', Lang::get('item_created'));
        header('Location: ' . APP_URL . '/subcollections/' . $subcollectionId . '?view=' . urlencode($view));
        exit;
    }

    public function edit(string $id): void
    {
        $item = $this->itemModel->findWithContext((int)$id);
        if (!$item) {
            header('Location: ' . APP_URL . '/home');
            exit;
        }

        $subModel = new Subcollection();
        $subcollection = $subModel->getWithCollection($item['subcollection_id']);
        $conditionOptions = $this->getBanknoteConditionOptions();
        $variantTypeOptions = (new VariantTypeOption())->getAll();
        $variants = (new ItemVariant())->getAllByItem((int)$id);
        $additionalImages = (new ItemImage())->getAllByItem((int)$id);

        require APP_ROOT . '/views/items/edit.php';
    }

    public function update(string $id): void
    {
        if (!Session::verifyCsrfToken($_POST['csrf_token'] ?? '')) {
            Session::flash('error', 'Invalid request.');
            header('Location: ' . APP_URL . '/items/' . $id . '/edit');
            exit;
        }

        
        $item = $this->itemModel->findById((int)$id);
        if (!$item) {
            header('Location: ' . APP_URL . '/home');
            exit;
        }

        $data = [
            'nominal_value'      => trim($_POST['nominal_value'] ?? ''),
            'dimensions'         => trim($_POST['dimensions'] ?? ''),
            'color'              => trim($_POST['color'] ?? ''),
            'description_obverse'=> trim($_POST['description_obverse'] ?? ''),
            'description_reverse'=> trim($_POST['description_reverse'] ?? ''),
            'issue_date'         => trim($_POST['issue_date'] ?? ''),
            'additional_info'    => trim($_POST['additional_info'] ?? ''),
            'catalog_number'     => trim($_POST['catalog_number'] ?? ''),
            'country'            => trim($_POST['country'] ?? ''),
            'purchase_price'     => trim($_POST['purchase_price'] ?? ''),
            'note'               => trim($_POST['note'] ?? ''),
            'image_obverse'      => $item['image_obverse'],
            'image_reverse'      => $item['image_reverse'],
            'sort_order'         => $item['sort_order'],
        ];

        // Handle obverse image upload
        if (!empty($_FILES['image_obverse']['name'])) {
            $result = FileUpload::upload($_FILES['image_obverse'], UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
            if ($result['success']) {
                if ($item['image_obverse'] && !str_starts_with($item['image_obverse'], 'duplicate_')) {
                    FileUpload::delete(UPLOAD_ITEMS_PATH . '/' . $item['image_obverse']);
                    // Delete old thumbnail
                    $oldThumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $item['image_obverse'], UPLOAD_ITEMS_THUMBS_PATH);
                    FileUpload::delete($oldThumbPath);
                }
                $data['image_obverse'] = $result['filename'];
                // Create thumbnail for banknote (170x80)
                $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
            }
        } elseif (!empty($_POST['numista_image_obverse'])) {
            // Handle Numista downloaded image
            if ($item['image_obverse'] && !str_starts_with($item['image_obverse'], 'duplicate_')) {
                FileUpload::delete(UPLOAD_ITEMS_PATH . '/' . $item['image_obverse']);
                // Delete old thumbnail
                $oldThumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $item['image_obverse'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::delete($oldThumbPath);
            }
            $data['image_obverse'] = $_POST['numista_image_obverse'];
            // Create thumbnail for banknote (170x80)
            $thumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_obverse'], UPLOAD_ITEMS_THUMBS_PATH);
            FileUpload::createThumbnail(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_obverse'], $thumbPath, 170, 80, 70);
        }

        // Handle reverse image upload
        if (!empty($_FILES['image_reverse']['name'])) {
            $result = FileUpload::upload($_FILES['image_reverse'], UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
            if ($result['success']) {
                if ($item['image_reverse'] && !str_starts_with($item['image_reverse'], 'duplicate_')) {
                    FileUpload::delete(UPLOAD_ITEMS_PATH . '/' . $item['image_reverse']);
                    // Delete old thumbnail
                    $oldThumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $item['image_reverse'], UPLOAD_ITEMS_THUMBS_PATH);
                    FileUpload::delete($oldThumbPath);
                }
                $data['image_reverse'] = $result['filename'];
                // Create thumbnail for banknote (170x80)
                $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
            }
        } elseif (!empty($_POST['numista_image_reverse'])) {
            // Handle Numista downloaded image
            if ($item['image_reverse'] && !str_starts_with($item['image_reverse'], 'duplicate_')) {
                FileUpload::delete(UPLOAD_ITEMS_PATH . '/' . $item['image_reverse']);
                // Delete old thumbnail
                $oldThumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $item['image_reverse'], UPLOAD_ITEMS_THUMBS_PATH);
                FileUpload::delete($oldThumbPath);
            }
            $data['image_reverse'] = $_POST['numista_image_reverse'];
            // Create thumbnail for banknote (170x80)
            $thumbPath = FileUpload::getThumbnailPath(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_reverse'], UPLOAD_ITEMS_THUMBS_PATH);
            FileUpload::createThumbnail(UPLOAD_ITEMS_PATH . '/' . $_POST['numista_image_reverse'], $thumbPath, 170, 80, 70);
        }

        $this->itemModel->update((int)$id, $data);

        // Delete removed additional images
        $imageModel = new ItemImage();
        $deleteImageIds = $_POST['delete_images'] ?? [];
        foreach ($deleteImageIds as $imgId) {
            $imageModel->delete((int)$imgId);
        }

        // Handle new additional images upload
        if (!empty($_FILES['additional_images']['name'][0])) {
            $existing = $imageModel->getAllByItem((int)$id);
            $nextSort = count($existing);
            foreach ($_FILES['additional_images']['name'] as $i => $name) {
                if (empty($name)) continue;
                $file = [
                    'name'     => $_FILES['additional_images']['name'][$i],
                    'type'     => $_FILES['additional_images']['type'][$i],
                    'tmp_name' => $_FILES['additional_images']['tmp_name'][$i],
                    'error'    => $_FILES['additional_images']['error'][$i],
                    'size'     => $_FILES['additional_images']['size'][$i],
                ];
                $result = FileUpload::upload($file, UPLOAD_ITEMS_PATH, ALLOWED_IMAGE_TYPES);
                if ($result['success']) {
                    // Create thumbnail for banknote (170x80)
                    $thumbPath = FileUpload::getThumbnailPath($result['filepath'], UPLOAD_ITEMS_THUMBS_PATH);
                    FileUpload::createThumbnail($result['filepath'], $thumbPath, 170, 80, 70);
                    
                    $imageModel->create([
                        'item_id'    => (int)$id,
                        'filename'   => $result['filename'],
                        'sort_order' => $nextSort + $i,
                    ]);
                }
            }
        }

        // Replace variants: delete old, insert new
        $variantModel = new ItemVariant();
        $variantModel->deleteByItem((int)$id);

        $conditions = $_POST['variant_condition'] ?? [];
        $variantTypes = $_POST['variant_type'] ?? [];
        $notes = $_POST['variant_note'] ?? [];
        $ownedArr = $_POST['variant_owned'] ?? [];

        foreach ($conditions as $i => $condId) {
            $variantModel->create([
                'item_id'         => (int)$id,
                'condition_id'    => (int)($condId) ?: null,
                'variant_type_id' => (int)($variantTypes[$i] ?? 0) ?: null,
                'note'            => trim($notes[$i] ?? ''),
                'owned'           => isset($ownedArr[$i]) ? 1 : 0,
                'sort_order'      => $i,
            ]);
        }

        $view = $_POST['view'] ?? 'grid';
        Session::flash('success', Lang::get('item_updated'));
        header('Location: ' . APP_URL . '/subcollections/' . $item['subcollection_id'] . '?view=' . urlencode($view));
        exit;
    }

    public function duplicate(string $id): void
    {
        header('Content-Type: application/json');
        
        if (!Session::verifyCsrfToken($_POST['csrf_token'] ?? '')) {
            http_response_code(403);
            echo json_encode(['error' => 'Invalid token']);
            exit;
        }

        $item = $this->itemModel->findWithContext((int)$id);
        if (!$item) {
            http_response_code(404);
            echo json_encode(['error' => 'Item not found']);
            exit;
        }

        // Check if user owns this item through collection
        $collectionModel = new Collection();
        $collection = $collectionModel->findById($item['collection_id']);
        if (!$collection || $collection['user_id'] !== Session::getUserId()) {
            http_response_code(403);
            echo json_encode(['error' => 'Access denied']);
            exit;
        }

        try {
            $this->db = Database::getInstance();
            $this->db->beginTransaction();

            // Copy image files if they exist
            $newObverseImage = null;
            $newReverseImage = null;
            
            if ($item['image_obverse']) {
                $oldPath = APP_ROOT . '/public/uploads/items/' . $item['image_obverse'];
                if (file_exists($oldPath)) {
                    $newObverseImage = 'duplicate_' . time() . '_' . $item['image_obverse'];
                    $newPath = APP_ROOT . '/public/uploads/items/' . $newObverseImage;
                    copy($oldPath, $newPath);
                }
            }
            
            if ($item['image_reverse']) {
                $oldPath = APP_ROOT . '/public/uploads/items/' . $item['image_reverse'];
                if (file_exists($oldPath)) {
                    $newReverseImage = 'duplicate_' . time() . '_' . $item['image_reverse'];
                    $newPath = APP_ROOT . '/public/uploads/items/' . $newReverseImage;
                    copy($oldPath, $newPath);
                }
            }

            // Create new item with same data
            $newItemId = $this->itemModel->create([
                'subcollection_id' => $item['subcollection_id'],
                'image_obverse'    => $newObverseImage,
                'image_reverse'    => $newReverseImage,
                'nominal_value'    => $item['nominal_value'],
                'dimensions'       => $item['dimensions'],
                'color'            => $item['color'],
                'description_obverse' => $item['description_obverse'],
                'description_reverse' => $item['description_reverse'],
                'issue_date'       => $item['issue_date'],
                'additional_info'  => $item['additional_info'],
                'catalog_number'   => $item['catalog_number'],
                'country'          => $item['country'],
                'purchase_price'   => $item['purchase_price'],
                'note'             => $item['note'] . ' (kopija)',
                'sort_order'       => $this->itemModel->getNextSortOrder($item['subcollection_id']),
            ]);

            // Copy all variants
            $variantModel = new ItemVariant();
            $variants = $variantModel->getAllByItem($item['id']);
            foreach ($variants as $variant) {
                $variantModel->create([
                    'item_id'         => $newItemId,
                    'condition_id'    => $variant['condition_id'],
                    'variant_type_id' => $variant['variant_type_id'],
                    'note'            => $variant['note'],
                    'owned'           => $variant['owned'],
                    'sort_order'      => $variant['sort_order'],
                ]);
            }

            // Copy additional images
            $imageModel = new ItemImage();
            $images = $imageModel->getAllByItem($item['id']);
            foreach ($images as $image) {
                // Copy the image file
                $newFilename = null;
                if ($image['filename']) {
                    $oldPath = APP_ROOT . '/public/uploads/items/' . $image['filename'];
                    if (file_exists($oldPath)) {
                        $newFilename = 'duplicate_' . time() . '_' . $image['filename'];
                        $newPath = APP_ROOT . '/public/uploads/items/' . $newFilename;
                        copy($oldPath, $newPath);
                    }
                }
                
                $imageModel->create([
                    'item_id'     => $newItemId,
                    'filename'    => $newFilename,
                    'sort_order'  => $image['sort_order'],
                ]);
            }

            $this->db->commit();
            echo json_encode(['success' => true, 'item_id' => $newItemId]);
        } catch (Exception $e) {
            $this->db->rollBack();
            http_response_code(500);
            echo json_encode(['error' => 'Failed to duplicate item']);
        }
    }

    public function toggleVariantOwned(string $id): void
    {
        header('Content-Type: application/json');
        
        if (!Session::verifyCsrfToken($_POST['csrf_token'] ?? '')) {
            http_response_code(403);
            echo json_encode(['error' => 'Invalid token']);
            exit;
        }

        $variantModel = new ItemVariant();
        $variant = $variantModel->findById((int)$id);
        if (!$variant) {
            http_response_code(404);
            echo json_encode(['error' => 'Not found']);
            exit;
        }

        $variantModel->toggleOwned((int)$id);

        header('Content-Type: application/json');
        echo json_encode(['success' => true, 'owned' => !$variant['owned']]);
        exit;
    }

    public function delete(string $id): void
    {
        $item = $this->itemModel->findById((int)$id);
        $subcollectionId = $item ? $item['subcollection_id'] : null;

        (new ItemImage())->deleteByItem((int)$id);
        $this->itemModel->delete((int)$id);
        Session::flash('success', Lang::get('item_deleted'));

        $redirect = $subcollectionId ? APP_URL . '/subcollections/' . $subcollectionId : APP_URL . '/home';
        header('Location: ' . $redirect);
        exit;
    }

    public function moveUp(string $id): void
    {
        $item = $this->itemModel->findById((int)$id);
        $isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';

        if (!$item) {
            if ($isAjax) {
                header('Content-Type: application/json');
                echo json_encode(['success' => false]);
                exit;
            }
            header('Location: ' . APP_URL . '/home');
            exit;
        }

        $result = $this->itemModel->moveUp((int)$id);

        if ($isAjax) {
            header('Content-Type: application/json');
            echo json_encode(['success' => $result]);
            exit;
        }

        header('Location: ' . APP_URL . '/subcollections/' . $item['subcollection_id']);
        exit;
    }

    public function moveDown(string $id): void
    {
        $item = $this->itemModel->findById((int)$id);
        $isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';

        if (!$item) {
            if ($isAjax) {
                header('Content-Type: application/json');
                echo json_encode(['success' => false]);
                exit;
            }
            header('Location: ' . APP_URL . '/home');
            exit;
        }

        $result = $this->itemModel->moveDown((int)$id);

        if ($isAjax) {
            header('Content-Type: application/json');
            echo json_encode(['success' => $result]);
            exit;
        }

        header('Location: ' . APP_URL . '/subcollections/' . $item['subcollection_id']);
        exit;
    }
}
