<?php

require_once APP_ROOT . '/models/ItemVariant.php';
require_once APP_ROOT . '/models/ItemImage.php';
require_once APP_ROOT . '/models/Coin.php';
require_once APP_ROOT . '/models/CoinImage.php';

class Collection
{
    private PDO $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    public function getAllByUser(int $userId): array
    {
        $stmt = $this->db->prepare(
            'SELECT * FROM collections WHERE user_id = :user_id ORDER BY sort_order ASC, name ASC'
        );
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetchAll();
    }

    public function findById(int $id): ?array
    {
        $stmt = $this->db->prepare('SELECT * FROM collections WHERE id = :id LIMIT 1');
        $stmt->execute(['id' => $id]);
        $row = $stmt->fetch();
        return $row ?: null;
    }

    public function create(array $data): int
    {
        $stmt = $this->db->prepare(
            'INSERT INTO collections (user_id, name, description, sort_order, type) VALUES (:user_id, :name, :description, :sort_order, :type)'
        );
        $stmt->execute([
            'user_id'     => $data['user_id'],
            'name'        => $data['name'],
            'description' => $data['description'] ?? null,
            'sort_order'  => $data['sort_order'] ?? 0,
            'type'        => $data['type'] ?? 'banknote',
        ]);
        return (int)$this->db->lastInsertId();
    }

    public function update(int $id, array $data): bool
    {
        $stmt = $this->db->prepare(
            'UPDATE collections SET name = :name, description = :description, sort_order = :sort_order WHERE id = :id'
        );
        return $stmt->execute([
            'name'        => $data['name'],
            'description' => $data['description'] ?? null,
            'sort_order'  => $data['sort_order'] ?? 0,
            'id'          => $id,
        ]);
    }

    public function delete(int $id): bool
    {
        $stmt = $this->db->prepare('DELETE FROM collections WHERE id = :id');
        return $stmt->execute(['id' => $id]);
    }

    public function countSubcollections(int $collectionId): int
    {
        $stmt = $this->db->prepare('SELECT COUNT(*) FROM subcollections WHERE collection_id = :id');
        $stmt->execute(['id' => $collectionId]);
        return (int)$stmt->fetchColumn();
    }

    public function countItems(int $collectionId): int
    {
        // Proveri tip kolekcije
        $stmt = $this->db->prepare('SELECT type FROM collections WHERE id = :id LIMIT 1');
        $stmt->execute(['id' => $collectionId]);
        $collectionType = $stmt->fetchColumn();

        if ($collectionType === 'coin') {
            $stmt = $this->db->prepare(
                'SELECT COUNT(*) FROM coins c JOIN subcollections s ON c.subcollection_id = s.id WHERE s.collection_id = :id'
            );
        } else {
            $stmt = $this->db->prepare(
                'SELECT COUNT(*) FROM items i JOIN subcollections s ON i.subcollection_id = s.id WHERE s.collection_id = :id'
            );
        }
        $stmt->execute(['id' => $collectionId]);
        return (int)$stmt->fetchColumn();
    }

    public function countAll(): int
    {
        return (int)$this->db->query('SELECT COUNT(*) FROM collections')->fetchColumn();
    }

    public function updateSortOrder(int $id, int $sortOrder): bool
    {
        $stmt = $this->db->prepare('UPDATE collections SET sort_order = :sort_order WHERE id = :id');
        return $stmt->execute(['sort_order' => $sortOrder, 'id' => $id]);
    }

    public function swap(int $id1, int $id2, int $userId): void
    {
        $all = $this->getAllByUser($userId);
        $pos1 = $pos2 = null;
        foreach ($all as $i => $c) {
            if ($c['id'] == $id1) $pos1 = $i;
            if ($c['id'] == $id2) $pos2 = $i;
        }
        if ($pos1 !== null && $pos2 !== null) {
            $this->updateSortOrder($id1, $pos2);
            $this->updateSortOrder($id2, $pos1);
        }
    }

    public function getTemplates(): array
    {
        $stmt = $this->db->query(
            'SELECT c.*, u.display_name AS owner_name,
                    (SELECT COUNT(*) FROM subcollections WHERE collection_id = c.id) AS sub_count,
                    (SELECT COUNT(*) FROM items i JOIN subcollections s ON i.subcollection_id = s.id WHERE s.collection_id = c.id) AS item_count
             FROM collections c
             JOIN users u ON c.user_id = u.id
             WHERE c.is_template = 1 AND c.allow_sharing = 1
             ORDER BY c.name ASC'
        );
        return $stmt->fetchAll();
    }

    public function setTemplate(int $id, bool $isTemplate): bool
    {
        $stmt = $this->db->prepare('UPDATE collections SET is_template = :is_template WHERE id = :id');
        return $stmt->execute(['is_template' => $isTemplate ? 1 : 0, 'id' => $id]);
    }

    public function setAllowSharing(int $id, bool $allowSharing): bool
    {
        $stmt = $this->db->prepare('UPDATE collections SET allow_sharing = :allow_sharing WHERE id = :id');
        return $stmt->execute(['allow_sharing' => $allowSharing ? 1 : 0, 'id' => $id]);
    }

    public function getAllForAdmin(): array
    {
        $stmt = $this->db->query(
            'SELECT c.*, u.display_name AS owner_name,
                    (SELECT COUNT(*) FROM subcollections WHERE collection_id = c.id) AS sub_count,
                    (SELECT COUNT(*) FROM items i JOIN subcollections s ON i.subcollection_id = s.id WHERE s.collection_id = c.id) AS item_count
             FROM collections c
             JOIN users u ON c.user_id = u.id
             WHERE c.allow_sharing = 1
             ORDER BY c.name ASC'
        );
        return $stmt->fetchAll();
    }

    public function deepCopy(int $sourceCollectionId, int $targetUserId, bool $copyVariants = true): int
    {
        $source = $this->findById($sourceCollectionId);
        if (!$source) {
            return 0;
        }

        $newCollectionId = $this->create([
            'user_id'     => $targetUserId,
            'name'        => $source['name'],
            'description' => $source['description'],
            'sort_order'  => $source['sort_order'],
            'type'        => $source['type'],
        ]);

        error_log("deepCopy: source_id=$sourceCollectionId, target_user_id=$targetUserId, new_collection_id=$newCollectionId");

        $subModel = new Subcollection();
        
        $subcollections = $subModel->getAllByCollection($sourceCollectionId);
        foreach ($subcollections as $sub) {
            $newSubId = $subModel->create([
                'collection_id' => $newCollectionId,
                'name'          => $sub['name'],
                'description'   => $sub['description'],
                'sort_order'    => $sub['sort_order'],
            ]);

            if ($source['type'] === 'coin') {
                // Handle coins
                $coinModel = new Coin();
                $coins = $coinModel->getAllBySubcollection($sub['id']);
                foreach ($coins as $coin) {
                    $newObverse = $this->copyImage($coin['image_obverse'], 'coin');
                    $newReverse = $this->copyImage($coin['image_reverse'], 'coin');

                    $coinModel->create([
                        'subcollection_id'   => $newSubId,
                        'image_obverse'      => $newObverse,
                        'image_reverse'      => $newReverse,
                        'country'            => $coin['country'],
                        'year_minted'        => $coin['year_minted'],
                        'nominal_value'      => $coin['nominal_value'],
                        'catalog_number'     => $coin['catalog_number'],
                        'material'           => $coin['material'],
                        'alloy_details'      => $coin['alloy_details'],
                        'weight'             => $coin['weight'],
                        'diameter'           => $coin['diameter'],
                        'thickness'          => $coin['thickness'],
                        'orientation'        => $coin['orientation'],
                        'description_obverse'=> $coin['description_obverse'],
                        'description_reverse'=> $coin['description_reverse'],
                        'legends'            => $coin['legends'],
                        'mintage'            => $coin['mintage'],
                        'condition_id'       => null, // Reset condition when sharing
                        'owned'              => 0, // Reset owned status when sharing
                        'origin'             => null,
                        'purchase_price'     => null,
                        'current_value'      => null,
                        'additional_info'     => null,
                        'note'               => null,
                        'sort_order'         => $coin['sort_order'],
                    ]);

                    $newCoinId = $coinModel->getLastInsertId();

                    // Copy additional images for coins
                    $additionalImages = (new CoinImage())->getAllByCoin($coin['id']);
                    foreach ($additionalImages as $img) {
                        $newFilename = $this->copyImage($img['filename'], 'coin');
                        if ($newFilename) {
                            (new CoinImage())->create([
                                'coin_id'    => $newCoinId,
                                'filename'   => $newFilename,
                                'sort_order' => $img['sort_order'],
                            ]);
                        }
                    }
                }
            } else {
                // Handle banknotes (existing code)
                $itemModel = new Item();
                $variantModel = new ItemVariant();

                $items = $itemModel->getAllBySubcollection($sub['id']);
                foreach ($items as $item) {
                    $newObverse = $this->copyImage($item['image_obverse'], 'banknote');
                    $newReverse = $this->copyImage($item['image_reverse'], 'banknote');

                    $newItemId = $itemModel->create([
                        'subcollection_id'    => $newSubId,
                        'image_obverse'       => $newObverse,
                        'image_reverse'       => $newReverse,
                        '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'      => null,
                        'note'                => null,
                        'sort_order'          => $item['sort_order'],
                    ]);

                    if ($copyVariants) {
                        $variants = $variantModel->getAllByItem($item['id']);
                        foreach ($variants as $v) {
                            $variantModel->create([
                                'item_id'         => $newItemId,
                                'condition_id'    => $v['condition_id'],
                                'variant_type_id' => $v['variant_type_id'],
                                'note'            => $v['note'],
                                'owned'           => 0,
                                'sort_order'      => $v['sort_order'],
                            ]);
                        }
                    }

                    $additionalImages = (new ItemImage())->getAllByItem($item['id']);
                    foreach ($additionalImages as $img) {
                        $newFilename = $this->copyImage($img['filename'], 'banknote');
                        if ($newFilename) {
                            (new ItemImage())->create([
                                'item_id'    => $newItemId,
                                'filename'   => $newFilename,
                                'sort_order' => $img['sort_order'],
                            ]);
                        }
                    }
                }
            }
        }

        return $newCollectionId;
    }

    private function copyImage(?string $filename, string $collectionType = 'banknote'): ?string
    {
        if (empty($filename)) {
            return null;
        }
        $sourcePath = UPLOAD_ITEMS_PATH . '/' . $filename;
        if (!file_exists($sourcePath)) {
            return null;
        }
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        $newFilename = uniqid('img_', true) . '.' . $ext;
        $destPath = UPLOAD_ITEMS_PATH . '/' . $newFilename;
        
        if (copy($sourcePath, $destPath)) {
            // Create thumbnail for the copied image
            $this->createThumbnailForImage($destPath, $newFilename, $collectionType);
            return $newFilename;
        }
        return null;
    }

    private function createThumbnailForImage(string $imagePath, string $filename, string $collectionType = 'banknote'): void
    {
        $thumbPath = FileUpload::getThumbnailPath($imagePath, UPLOAD_ITEMS_THUMBS_PATH);
        
        // Skip if thumbnail already exists
        if (file_exists($thumbPath)) {
            return;
        }
        
        // Create thumbnail with appropriate dimensions based on collection type
        if ($collectionType === 'coin') {
            // Square thumbnail for coins (160x160)
            FileUpload::createThumbnail($imagePath, $thumbPath, 160, 160, 70);
        } else {
            // Rectangular thumbnail for banknotes (170x80)
            FileUpload::createThumbnail($imagePath, $thumbPath, 170, 80, 70);
        }
    }
}
