<?php
require_once __DIR__ . '/Logger.php';
require_once __DIR__ . '/Notifications.php';

class Disposal {
    private $conn;
    private $logger;
    private $notifications;

    public function __construct($conn, $logger = null) {
        $this->conn = $conn;
        $this->logger = $logger;
        $this->notifications = new Notifications($conn);
        $this->ensureTables();
    }

    private function ensureTables() {
        $this->conn->exec("
            CREATE TABLE IF NOT EXISTS inventory_disposals (
                disposal_id INT AUTO_INCREMENT PRIMARY KEY,
                item_id INT NOT NULL,
                branch_id INT DEFAULT NULL,
                reason ENUM('obsolete','damaged','written_off','lost','other') NOT NULL DEFAULT 'other',
                condition_notes TEXT DEFAULT NULL,
                estimated_value DECIMAL(12,2) DEFAULT 0.00,
                disposal_method VARCHAR(100) DEFAULT NULL,
                status ENUM('pending','approved','rejected','completed') NOT NULL DEFAULT 'pending',
                requested_by INT NOT NULL,
                requested_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                reviewed_by INT DEFAULT NULL,
                reviewed_at DATETIME DEFAULT NULL,
                review_notes TEXT DEFAULT NULL,
                completed_by INT DEFAULT NULL,
                completed_at DATETIME DEFAULT NULL,
                created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                INDEX idx_disposal_item (item_id),
                INDEX idx_disposal_branch (branch_id),
                INDEX idx_disposal_status (status)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
        ");

        $this->conn->exec("
            CREATE TABLE IF NOT EXISTS inventory_disposal_audit (
                audit_id INT AUTO_INCREMENT PRIMARY KEY,
                disposal_id INT NOT NULL,
                action VARCHAR(50) NOT NULL,
                notes TEXT DEFAULT NULL,
                performed_by INT NOT NULL,
                performed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
                INDEX idx_disposal_audit (disposal_id)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
        ");
    }

    public function createRequest($data) {
        $sql = "INSERT INTO inventory_disposals
                (item_id, branch_id, reason, condition_notes, estimated_value, disposal_method, requested_by)
                VALUES
                (:item_id, :branch_id, :reason, :condition_notes, :estimated_value, :disposal_method, :requested_by)";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute([
            ':item_id' => (int)$data['item_id'],
            ':branch_id' => $data['branch_id'] !== null ? (int)$data['branch_id'] : null,
            ':reason' => $data['reason'],
            ':condition_notes' => $data['condition_notes'],
            ':estimated_value' => (float)$data['estimated_value'],
            ':disposal_method' => $data['disposal_method'],
            ':requested_by' => (int)$data['requested_by']
        ]);

        $disposalId = (int)$this->conn->lastInsertId();
        $this->recordAudit($disposalId, 'requested', 'Disposal request submitted.', (int)$data['requested_by']);
        $this->notifications->createNotification((int)($data['branch_id'] ?: 7), "Disposal request #{$disposalId} is waiting for approval.", 'Admin', 0, false);

        if ($this->logger) {
            $this->logger->log('CREATE_DISPOSAL_REQUEST', 'disposals', "Created disposal request #{$disposalId}", $disposalId, 'inventory_disposals', null, $data);
        }

        return $disposalId;
    }

    public function updateStatus($disposalId, $status, $userId, $notes = '') {
        $allowed = ['approved', 'rejected', 'completed'];
        if (!in_array($status, $allowed, true)) {
            return false;
        }

        $this->conn->beginTransaction();
        try {
            $request = $this->getById($disposalId);
            if (!$request) {
                $this->conn->rollBack();
                return false;
            }

            if ($status === 'completed') {
                $sql = "UPDATE inventory_disposals
                        SET status = 'completed', completed_by = :user_id, completed_at = NOW(), review_notes = COALESCE(NULLIF(:notes, ''), review_notes)
                        WHERE disposal_id = :disposal_id";
            } else {
                $sql = "UPDATE inventory_disposals
                        SET status = :status, reviewed_by = :user_id, reviewed_at = NOW(), review_notes = :notes
                        WHERE disposal_id = :disposal_id";
            }

            $stmt = $this->conn->prepare($sql);
            $stmt->bindValue(':user_id', $userId, PDO::PARAM_INT);
            $stmt->bindValue(':notes', $notes);
            $stmt->bindValue(':disposal_id', $disposalId, PDO::PARAM_INT);
            if ($status !== 'completed') {
                $stmt->bindValue(':status', $status);
            }
            $stmt->execute();

            if (in_array($status, ['approved', 'completed'], true)) {
                $itemStatus = $status === 'completed' ? 'disposed' : 'pending_disposal';
                $itemStmt = $this->conn->prepare("UPDATE items SET shelf_status = :status, comment = CONCAT(COALESCE(comment, ''), :comment) WHERE item_id = :item_id");
                $itemStmt->execute([
                    ':status' => $itemStatus,
                    ':comment' => "\nDisposal #{$disposalId}: " . ucfirst($status),
                    ':item_id' => (int)$request['item_id']
                ]);
            }

            $this->recordAudit($disposalId, $status, $notes, $userId);
            $this->conn->commit();

            if ($this->logger) {
                $this->logger->log('UPDATE_DISPOSAL_STATUS', 'disposals', "Marked disposal request #{$disposalId} as {$status}", $disposalId, 'inventory_disposals', $request, ['status' => $status, 'notes' => $notes]);
            }

            return true;
        } catch (Exception $e) {
            $this->conn->rollBack();
            error_log("Disposal status update failed: " . $e->getMessage());
            return false;
        }
    }

    public function getRequests($branchId = null) {
        $sql = "SELECT d.*, i.item_name, i.item_details, i.unique_code, i.shelf_status, b.branch_name, u.username AS requested_by_name
                FROM inventory_disposals d
                LEFT JOIN items i ON i.item_id = d.item_id
                LEFT JOIN branches b ON b.branch_id = d.branch_id
                LEFT JOIN users u ON u.user_id = d.requested_by";
        $params = [];
        if ($branchId !== null) {
            $sql .= " WHERE d.branch_id = :branch_id";
            $params[':branch_id'] = (int)$branchId;
        }
        $sql .= " ORDER BY d.requested_at DESC";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function getById($disposalId) {
        $stmt = $this->conn->prepare("SELECT * FROM inventory_disposals WHERE disposal_id = :disposal_id");
        $stmt->execute([':disposal_id' => (int)$disposalId]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function getAudit($disposalId) {
        $sql = "SELECT a.*, u.username
                FROM inventory_disposal_audit a
                LEFT JOIN users u ON u.user_id = a.performed_by
                WHERE a.disposal_id = :disposal_id
                ORDER BY a.performed_at DESC";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute([':disposal_id' => (int)$disposalId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    private function recordAudit($disposalId, $action, $notes, $userId) {
        $stmt = $this->conn->prepare("INSERT INTO inventory_disposal_audit (disposal_id, action, notes, performed_by) VALUES (:disposal_id, :action, :notes, :performed_by)");
        return $stmt->execute([
            ':disposal_id' => (int)$disposalId,
            ':action' => $action,
            ':notes' => $notes,
            ':performed_by' => (int)$userId
        ]);
    }
}
