<?php
class KanbanCrmItem extends Core
{
    function list()
    {
        $step_id = filter_input(INPUT_GET, 'stepId', FILTER_VALIDATE_INT);
        $group_id = filter_input(INPUT_GET, 'groupId', FILTER_VALIDATE_INT);

        if ($step_id === null || $step_id === false) {
            return ['type' => 'ERROR', 'message' => 'Invalid or missing step ID'];
        }

        if ($group_id !== null && $group_id === false) {
            return ['type' => 'ERROR', 'message' => 'Invalid group ID'];
        }

        if ($group_id) {
            $sql = "SELECT * FROM kanban_crm_item WHERE step_id = :step_id AND group_id = :group_id ORDER BY order_group";
            $bind_params = [
                ':step_id' => $step_id,
                ':group_id' => $group_id
            ];
        } else {
            $sql = "SELECT * FROM kanban_crm_item WHERE step_id = :step_id AND visible = 1 ORDER BY `order`";
            $bind_params = [':step_id' => $step_id];
        }

        $stmt = parent::$conn->prepare($sql);
        $stmt->execute($bind_params);
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

        foreach ($result as $index => $card) {
            $children = $this->listByGroup($card['id'], $step_id);
            if (!empty($children)) {
                $result[$index]['data'] = $children;
            } else {
                $json = json_decode($card['data'], true);
                $result[$index]['data'] = $json;
            }
        }

        return ['type' => 'OK', 'result' => $result];
    }

    function listByGroup($group_id, $step_id)
    {
        $sql = "SELECT data FROM kanban_crm_item WHERE group_id = :group_id AND step_id = :step_id ORDER BY `order`";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':group_id' => $group_id,
            ':step_id' => $step_id
        ]);
        return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
    }

    function save()
    {
        $data = filter_input_array(INPUT_POST, [
            'stepId' => FILTER_VALIDATE_INT,
            'name' => FILTER_SANITIZE_SPECIAL_CHARS,
            'order' => FILTER_VALIDATE_INT,
            'data' => FILTER_DEFAULT,
            'type' => FILTER_SANITIZE_SPECIAL_CHARS,
            'visible' => FILTER_VALIDATE_BOOLEAN
        ]);

        if ($data['stepId'] === false || $data['name'] === false || $data['type'] === false) {
            return ['type' => 'ERROR', 'message' => 'Invalid input data'];
        }

        $sql = "INSERT INTO kanban_crm_item (step_id, name, `order`, data, type, visible) 
                VALUES (:step_id, :name, :order, :data, :type, :visible)";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':step_id' => $data['stepId'],
            ':name' => $data['name'],
            ':order' => $data['order'] ?? 1,
            ':data' => isset($data['data']) ? json_encode($data['data']) : null,
            ':type' => $data['type'],
            ':visible' => $data['visible'] ?? true
        ]);

        return ['type' => 'OK', 'id' => parent::$conn->lastInsertId()];
    }

    function update()
    {
        $id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);
        $data = filter_input_array(INPUT_POST, [
            'stepId' => FILTER_VALIDATE_INT,
            'name' => FILTER_SANITIZE_SPECIAL_CHARS,
            'order' => FILTER_VALIDATE_INT,
            'type' => FILTER_SANITIZE_SPECIAL_CHARS,
            'visible' => FILTER_VALIDATE_BOOLEAN
        ]);

        if ($id === false || $data['stepId'] === false || $data['name'] === false || $data['type'] === false) {
            return ['type' => 'ERROR', 'message' => 'Invalid input data'];
        }

        $sql = "UPDATE kanban_crm_item SET step_id = :step_id, name = :name, `order` = :order, 
                type = :type, visible = :visible WHERE id = :id";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':step_id' => $data['stepId'],
            ':name' => $data['name'],
            ':order' => $data['order'],
            ':type' => $data['type'],
            ':visible' => $data['visible'],
            ':id' => $id
        ]);

        return ['OK' => $stmt->rowCount() > 0];
    }

    function delete()
    {
        $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
        if ($id === false) {
            return ['type' => 'ERROR', 'message' => 'Invalid ID'];
        }

        $sql = "DELETE FROM kanban_crm_item WHERE id = :id OR group_id = :id";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([':id' => $id]);

        return ['OK' => $stmt->rowCount() > 0];
    }

    function reorderCards()
    {
        $orders = filter_input(INPUT_POST, 'orders', FILTER_DEFAULT);
        $step_id = filter_input(INPUT_POST, 'stepId', FILTER_VALIDATE_INT);
        $remove_from_group = filter_input(INPUT_POST, 'removeFromGroup', FILTER_VALIDATE_BOOLEAN);

        if ($orders === null || $step_id === null) {
            return ['type' => 'ERROR', 'message' => 'Invalid input data'];
        }

        $sql = "UPDATE kanban_crm_item SET `order` = :order, step_id = :step_id WHERE id = :id";
        $stmt = parent::$conn->prepare($sql);
        $orders = json_decode($orders, true);

        foreach ($orders as $order) {
            $stmt->execute([
                ':id' => $order['id'],
                ':order' => $order['order'],
                ':step_id' => $step_id
            ]);

            if ($remove_from_group)
                $this->removeFromGroup($order['id']);
        }

        return ['type' => 'OK'];
    }

    function removeFromGroup($id)
    {
        $sql = "UPDATE kanban_crm_item SET group_id = NULL, visible = 1 WHERE id = :id";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([':id' => $id]);
    }

    function listGroup()
    {
        $sql = "SELECT A.*, B.name as step_name FROM kanban_crm_item A
                LEFT JOIN kanban_crm B ON B.id = A.step_id
                WHERE A.type = 'group'";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute();

        return ['type' => 'OK', 'result' => $stmt->fetchAll(PDO::FETCH_ASSOC)];
    }
}
