<?php

namespace App\Models;

use PDO;
use PDOException;

class Item {
    private PDO $db;
    private ?int $id;
    private string $name;
    private ?string $description;
    private ?int $categoryId;
    private ?string $categoryName;
    private ?string $idCode;
    private ?string $image;
    private ?string $location;
    private ?string $createdAt;
    private ?string $updatedAt;

    public function __construct(PDO $db, ?int $id = null, string $name = '', ?string $description = null, ?int $categoryId = null, ?string $categoryName = null, ?string $idCode = null, ?string $image = null, ?string $location = null, ?string $createdAt = null, ?string $updatedAt = null) {
        $this->db = $db;
        $this->id = $id;
        $this->name = $name;
        $this->description = $description;
        $this->categoryId = $categoryId;
        $this->categoryName = $categoryName;
        $this->idCode = $idCode;
        $this->image = $image;
        $this->location = $location;
        $this->createdAt = $createdAt;
        $this->updatedAt = $updatedAt;
    }

    public function getId(): ?int {
        return $this->id;
    }

    public function getName(): string {
        return $this->name;
    }

    public function setName(string $name): void {
        $this->name = $name;
    }

    public function getDescription(): ?string {
        return $this->description;
    }

    public function setDescription(?string $description): void {
        $this->description = $description;
    }

    public function getCategoryId(): ?int {
        return $this->categoryId;
    }

    public function setCategoryId(?int $categoryId): void {
        $this->categoryId = $categoryId;
    }

    public function getCategoryName(): ?string {
        return $this->categoryName;
    }

    public function getIdCode(): ?string {
        return $this->idCode;
    }

    public function setIdCode(?string $idCode): void {
        $this->idCode = $idCode;
    }

    public function getImage(): ?string {
        return $this->image;
    }

    public function setImage(?string $image): void {
        $this->image = $image;
    }

    public function getLocation(): ?string {
        return $this->location;
    }

    public function setLocation(?string $location): void {
        $this->location = $location;
    }

    public static function getAll(PDO $db): array {
        return self::getAllFiltered($db, '', null);
    }

    public static function getAllFiltered(PDO $db, string $search, ?int $categoryId): array {
        try {
            $query = 'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location, i.created_at, i.updated_at
                      FROM items i
                      LEFT JOIN categories c ON i.category_id = c.id
                      WHERE 1=1';
            $params = [];

            if (!empty($search)) {
                $query .= ' AND i.name LIKE :search';
                $params[':search'] = '%' . $search . '%';
            }

            if ($categoryId !== null) {
                $query .= ' AND i.category_id = :category_id';
                $params[':category_id'] = $categoryId;
            }

            $query .= ' ORDER BY i.name';

            $stmt = $db->prepare($query);
            $stmt->execute($params);
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            error_log("Model Error: Failed to get filtered items - " . $e->getMessage());
            throw $e;
        }
    }

    public static function getById(PDO $db, int $id): ?array {
        try {
            $stmt = $db->prepare(
                'SELECT i.id, i.name, i.description, c.name as category_name, i.category_id, i.id_code, i.image, i.location, i.created_at, i.updated_at
                 FROM items i
                 LEFT JOIN categories c ON i.category_id = c.id
                 WHERE i.id = :id'
            );
            $stmt->execute([':id' => $id]);
            $item = $stmt->fetch(PDO::FETCH_ASSOC);
            return $item ?: null;
        } catch (PDOException $e) {
            error_log("Model Error: Failed to get item by ID - " . $e->getMessage());
            throw $e;
        }
    }

    public function save(): bool {
        if ($this->id === null) {
            // Add new item
            try {
                $stmt = $this->db->prepare(
                    'INSERT INTO items (name, description, category_id, id_code, image, location)
                     VALUES (:name, :description, :category_id, :id_code, :image, :location)'
                );
                $stmt->execute([
                    ':name' => $this->name,
                    ':description' => $this->description,
                    ':category_id' => $this->categoryId,
                    ':id_code' => $this->idCode,
                    ':image' => $this->image,
                    ':location' => $this->location
                ]);
                $this->id = (int)$this->db->lastInsertId();
                return true;
            } catch (PDOException $e) {
                error_log("Model Error: Failed to save item - " . $e->getMessage());
                throw $e;
            }
        } else {
            // Update item (optional, not implemented in current controllers)
            try {
                $stmt = $this->db->prepare(
                    'UPDATE items
                     SET name = :name, description = :description, category_id = :category_id, id_code = :id_code, image = :image, location = :location
                     WHERE id = :id'
                );
                $stmt->execute([
                    ':name' => $this->name,
                    ':description' => $this->description,
                    ':category_id' => $this->categoryId,
                    ':id_code' => $this->idCode,
                    ':image' => $this->image,
                    ':location' => $this->location,
                    ':id' => $this->id
                ]);
                return true;
            } catch (PDOException $e) {
                error_log("Model Error: Failed to update item - " . $e->getMessage());
                throw $e;
            }
        }
    }

    public static function delete(PDO $db, int $id): bool {
        try {
            $stmt = $db->prepare('DELETE FROM items WHERE id = :id');
            $stmt->execute([':id' => $id]);
            return $stmt->rowCount() > 0;
        } catch (PDOException $e) {
            error_log("Model Error: Failed to delete item - " . $e->getMessage());
            throw $e;
        }
    }

    public function toArray(): array {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'category_id' => $this->categoryId,
            'category_name' => $this->categoryName,
            'id_code' => $this->idCode,
            'image' => $this->image,
            'location' => $this->location,
            'created_at' => $this->createdAt,
            'updated_at' => $this->updatedAt
        ];
    }
}
