<?php
require_once "QueryBuilder.php";

class DataFetcher
{

    public static function single($sql, $params = [])
    {
        $stmt = db()->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public static function list($sql, $params = [])
    {
        $stmt = db()->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function getListData($config, $data)
    {
        $page = (int) ($data['page'] ?? 1);
        $rows = (int) ($data['rowsPerPage'] ?? 10);
        $search = $data['search'] ?? '';
        $sortColumn = $data['sortColumn'] ?? '';
        $sortDirection = strtoupper($data['sortDirection'] ?? 'DESC');
        $filters = $data['filter'] ?? [];
 

        $offset = ($page - 1) * $rows;

        // ✅ SORT
        if (!in_array($sortColumn, array_keys($config['allowedSort']))) {
            $sortColumn = $config['defaultSort'];
        } else {
            $sortColumn = $config['allowedSort'][$sortColumn];
        }

        $sortDirection = $sortDirection === 'DESC' ? 'DESC' : 'ASC';

        // ========================
        // 🔥 MAIN QUERY
        // ========================
        $qb = (new QueryBuilder())
            ->select($config['select'])
            ->from($config['from']);

        if (!empty($config['join'])) {
            $qb->join($config['join']);
        }

        // ✅ MULTI WHERE (CONFIG)
        if (!empty($config['where'])) {
            foreach ($config['where'] as $w) {
                $qb->where(
                    $w['column'],
                    $w['value'],
                    $w['operator'] ?? '='
                );
            }
        }

        // ✅ FILTER DARI REQUEST
        $qb->applyFilters($filters, $config['columnMap'])
            ->search($config['searchColumns'], $search)
            ->orderBy("$sortColumn $sortDirection")
            ->limit($rows, $offset);

        list($sql, $params) = $qb->build();

        $stmt = db()->prepare($sql);
        bindParams($stmt, $params);
        $stmt->execute();

        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // ========================
        // 🔥 COUNT QUERY
        // ========================
        $qbCount = (new QueryBuilder())
            ->select('COUNT(*) as total')
            ->from($config['from']);

        if (!empty($config['join'])) {
            $qbCount->join($config['join']);
        }

        // ✅ MULTI WHERE (CONFIG)
        if (!empty($config['where'])) {
            foreach ($config['where'] as $w) {
                $qbCount->where(
                    $w['column'],
                    $w['value'],
                    $w['operator'] ?? '='
                );
            }
        }

        $qbCount->applyFilters($filters, $config['columnMap'])
            ->search($config['searchColumns'], $search);

        list($sqlCount, $paramsCount) = $qbCount->build();

        $stmtCount = db()->prepare($sqlCount);
        bindParams($stmtCount, $paramsCount);
        $stmtCount->execute();

        $total = $stmtCount->fetch(PDO::FETCH_ASSOC)['total'];

        return [
            "listData" => $result,
            "totalData" => (int) $total,
            "totalPage" => ceil($total / $rows)
        ];
    }
}