<?php
require_once __DIR__ . '/../init.php';
require_once PROJECT_ROOT . '/backend/controllers/common_function.php';
require_once PROJECT_ROOT . '/backend/controllers/db_select_helper.php';

// include other controller
require_once PROJECT_ROOT . '/backend/controllers/ActivityController.php';
require_once PROJECT_ROOT . '/backend/controllers/UserAksesController.php';
require_once PROJECT_ROOT . '/backend/controllers/AttachmentController.php';

class LevelController
{
    private $conn;
    private $table = "level T
    LEFT JOIN (
            SELECT C.IDLevel, COUNT(*) AS TotalTournamen
            FROM tournament_category_level C
            GROUP BY C.IDLevel
        ) AS SK ON SK.IDLevel = T.IDLevel";
    private $pk = "IDLevel";
    private $sv = "Level";

    protected $displayedColumn = [
        'T.IDLevel',
        'T.NamaLevel',
        'T.NamaLevelEN',
        'T.StatusLevel',
        'T.CreateBy',
        'T.CreateAt',
        'T.LastUpdateBy',
        'T.LastUpdateAt',
        'IFNULL(SK.TotalTournamen, 0) AS TotalTournamen',
    ];

    public function __construct($conn)
    {
        $this->conn = $conn;
        $this->activityController = new ActivityController($this->conn);
        $this->attachmentController = new AttachmentController($this->conn);
        $this->userAksesController = new UserAksesController($this->conn);
    }

    public function select($post)
    {
        $listExclude = [];

        $listSearch = [
            'NamaLevel',
            'NamaLevelEN'
        ];

        return runSelect(
            $this->conn,
            $this->table,
            $this->pk,
            $this->displayedColumn,
            $post,
            $listExclude,
            $listSearch
        );
    }

    public function update($post, $files)
    {
        try {

            if (empty($post['NamaLevel'])) {
                throw new Exception("Nama Level tidak boleh kosong");
            }

            return runWithTransaction($this->conn, function ($conn) use ($post, $files) {

                $NamaLevel = trim($post['NamaLevel']);
                $NamaLevelEN = $post['NamaLevelEN'] ?? '';
                $StatusLevel = $post['StatusLevel'] ?? '';
                $isUpdate = !empty($post['IDLevel']) && intval($post['IDLevel']) > 0;

                // --------------------------------------
                // MULAI USER AKSES
                // --------------------------------------
                // Cek mode: Insert atau Update
                $UserLogin = "";
                $AksesNeeded = $isUpdate ? $this->sv . ".Modify" : $this->sv . ".Insert";

                $userAksesFilterParam = [
                    ["IDUser", $post['IDUserLogin'], 1]
                ];

                $userAksesselectParam = [
                    "filters" => $userAksesFilterParam,
                    "rows_per_page" => 1,
                    "page_number" => 1,
                    "no_count" => true
                ];

                $userAksesresult = $this->userAksesController->select($userAksesselectParam);
                $listAkses = array_column($userAksesresult['list_data'], 'AksesName');

                if ($userAksesresult['Status'] == 1 && !empty($listAkses)) {
                    if (!in_array($AksesNeeded, $listAkses)) {
                        $msg = "User tidak memiliki otoritas akses - [" . $AksesNeeded . "]";
                        throw new Exception($msg);
                    }

                    $UserLogin = $userAksesresult['Username'];
                } else {
                    $msg = $userAksesresult['Keterangan'];
                    throw new Exception($msg);
                }
                // --------------------------------------
                // END USER AKSES
                // --------------------------------------

                // =========================
                // START - cek duplikat
                // ========================= 
                $duplikatDataFilter = [];
                $duplikatDataFilter[] = ["NamaLevel", $post['NamaLevel'], 1];

                if ($isUpdate) {
                    $duplikatDataFilter[] = ["IDLevel", $post['IDLevel'], 6];
                }

                $duplikatDataSelectParam = [
                    "filters" => $duplikatDataFilter,
                    "rows_per_page" => 1,
                    "page_number" => 1,
                    "no_count" => true
                ];
                $duplikatDataResult = $this->select($duplikatDataSelectParam);

                if ($duplikatDataResult['Status'] == 1 && count($duplikatDataResult['list_data']) > 0) {
                    $msg = "Level sudah terpakai, mohon diganti";
                    throw new Exception($msg);
                }
                // =========================
                // END - cek duplikat
                // =========================


                // =========================
                // START - ambil data lama
                // =========================
                $oldData = [];
                if ($isUpdate && !empty($post['IDLevel'])) {

                    $oldDataFilter = [
                        ["IDLevel", $post['IDLevel'], 1]
                    ];

                    $oldDataSelectParam = [
                        "filters" => $oldDataFilter,
                        "rows_per_page" => 1,
                        "page_number" => 1,
                        "no_count" => true
                    ];



                    $oldDataResult = $this->select($oldDataSelectParam);

                    if ($oldDataResult['Status'] == 1) {
                        $oldData = $oldDataResult['list_data'][0];
                    } else {
                        $msg = $oldDataResult['Keterangan'];
                        throw new Exception($msg);
                    }
                }
                // =========================
                // END - ambil data lama
                // =========================




                // =========================
                // QUERY DATABASE
                // =========================
                $NewID = 0;

                if ($isUpdate) {
                    // Update level
                    $sql = "UPDATE level 
                        SET NamaLevel = ?, 
                            NamaLevelEN = ?, 
                            StatusLevel = ?,
                            LastUpdateBy = ?, 
                            LastUpdateAt = NOW()
                        WHERE IDLevel = ?";

                    $stmt = $conn->prepare($sql);
                    if (!$stmt) {
                        throw new Exception("Prepare statement gagal: " . $conn->error);
                    }

                    $stmt->bind_param(
                        "ssssi",
                        $NamaLevel,
                        $NamaLevelEN,
                        $StatusLevel,
                        $UserLogin,
                        $post['IDLevel']
                    );

                    $stmt->execute();

                    if ($stmt->affected_rows < 0) {
                        throw new Exception("Gagal update level");
                    }

                    $stmt->close();
                    $NewID = $post['IDLevel'];
                } else {

                    // Insert level baru
                    $sql = "INSERT INTO level 
                        (NamaLevel, NamaLevelEN, StatusLevel, CreateBy, CreateAt) 
                        VALUES (?, ?, ?, ?, NOW())";

                    $stmt = $conn->prepare($sql);
                    if (!$stmt) {
                        throw new Exception("Prepare statement gagal: " . $conn->error);
                    }

                    $stmt->bind_param(
                        "ssss",
                        $NamaLevel,
                        $NamaLevelEN,
                        $StatusLevel,
                        $UserLogin
                    );

                    $stmt->execute();

                    if ($stmt->affected_rows <= 0) {
                        throw new Exception("Gagal insert level baru");
                    }

                    $NewID = $stmt->insert_id;
                    $stmt->close();

                }

                // =========================
                // START - ambil data baru
                // =========================
                $newData = [];
                if ($NewID > 0) {

                    $newDataFilter = [
                        ["IDLevel", $NewID, 1]
                    ];

                    $newDataSelectParam = [
                        "filters" => $newDataFilter,
                        "rows_per_page" => 1,
                        "page_number" => 1,
                        "no_count" => true
                    ];



                    $newDataResult = $this->select($newDataSelectParam);

                    if ($newDataResult['Status'] == 1) {
                        $newData = $newDataResult['list_data'][0];
                    } else {
                        $msg = $newDataResult['Keterangan'];

                        throw new Exception($msg);
                    }


                }
                // =========================
                // END - ambil data baru
                // =========================



                // =========================
                // START HANDLE Activity
                // =========================
                $di = json_decode($post['DeviceInfo'], true);
                $Platform = $di['platform'] ?? '';
                $DeviceName = $di['device_name'] ?? '';
                $FullDevice = $di['FullDevice'] ?? $Platform . " - " . $DeviceName;

                $IP = "";
                if (isset($post['IP'])) {
                    $IP = $post['IP'];
                } else {
                    if (isset($_SERVER['REMOTE_ADDR'])) {
                        $IP = $_SERVER['REMOTE_ADDR'];
                    }
                }

                $Category = "level";
                $KodeUnik = $NewID;
                $TipeActivity = $isUpdate ? "Modify" : "Insert";
                $queryAcitivy = g_generateActivityQuery(
                    $Category,
                    $TipeActivity,
                    $newData,
                    $oldData,
                    []
                );
                $activityResult = $this->activityController->generateActivity(
                    $post['IDUserLogin'],
                    $UserLogin,
                    $queryAcitivy,
                    $FullDevice,
                    $IP,
                    $Category,
                    $KodeUnik
                );
                // =========================
                // END HANDLE Activity
                // =========================

                return [
                    "Status" => 1,
                    "Keterangan" => $isUpdate ? "Data berhasil diupdate" : "Data berhasil ditambahkan",
                    "ID" => $NewID
                ];
            });
        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage()
            ];
        }
    }

    public function delete($post)
    { 

        try {
            $MainID = $post[$this->pk];
            if (empty($MainID)) {
                throw new Exception("Parameter tidak lengkap");
            }

            return runWithTransaction($this->conn, function ($conn) use ($MainID, $post) {

                // --------------------------------------
                // VALIDASI AKSES USER
                // --------------------------------------
                $UserLogin = "";
                $AksesNeeded = $this->sv . ".Delete"; // Level.Delete
                $userAksesFilterParam = [
                    ["IDUser", $post['IDUserLogin'], 1]
                ];

                $userAksesselectParam = [
                    "filters" => $userAksesFilterParam,
                    "rows_per_page" => 1,
                    "page_number" => 1,
                    "no_count" => true
                ];

                $userAksesresult = $this->userAksesController->select($userAksesselectParam);
                $listAkses = array_column($userAksesresult['list_data'], 'AksesName');

                if ($userAksesresult['Status'] == 1 && !empty($listAkses)) {
                    if (!in_array($AksesNeeded, $listAkses)) {
                        throw new Exception("User tidak memiliki otoritas akses - [" . $AksesNeeded . "]");
                    }
                    $UserLogin = $userAksesresult['Username'];
                } else {
                    throw new Exception($userAksesresult['Keterangan'] ?? "Akses pengguna tidak valid");
                }

                // --------------------------------------
                // AMBIL DATA LAMA 
                // --------------------------------------
                $oldData = [];
                $idArray = is_array($MainID)
                    ? $MainID
                    : array_filter(array_unique(array_map('trim', explode(',', $MainID))));

                if (empty($idArray)) {
                    throw new Exception("Tidak ada ID valid untuk dihapus.");
                }

                if (count($idArray) > 1000) {
                    throw new Exception("Maksimal 1000 data yang dapat dihapus sekaligus.");
                }

                $oldDataFilter = [
                    ["IDLevel", $MainID, 7]
                ];

                $oldDataSelectParam = [
                    "filters" => $oldDataFilter,
                    "rows_per_page" => 0,
                    "page_number" => 1,
                    "no_count" => true
                ];

                $oldDataResult = $this->select($oldDataSelectParam);

                if ($oldDataResult['Status'] == 1) {
                    $oldData = $oldDataResult['list_data'];
                } else {
                    $msg = $oldDataResult['Keterangan'];
                    throw new Exception($msg);
                }


                // --------------------------------------
                // VALIDASI: ADA BARANG?
                // --------------------------------------
                $errorList = [];
                $deleteID = [];

                foreach ($oldData as $row) {
                    $canDelete = true;

                    if ($row['TotalTournamen'] > 0) {
                        $errorList[] = [
                            "IDLevel" => $row['IDLevel'],
                            "NamaLevel" => $row['NamaLevel'],
                            "Keterangan" => "Level ini masih memiliki {$row['TotalTournamen']} turnamen. Mohon hapus turnamen terlebih dahulu."
                        ];
                        $canDelete = false;
                    }

                    if ($canDelete) {
                        $deleteID[] = $row['IDLevel'];
                    }
                }

                // --------------------------------------
                // PROSES DELETE
                // --------------------------------------
                $statusDelete = 2;

                if (!empty($deleteID)) {
                    $statusDelete = 1;
                    try {
                        $conn->begin_transaction();

                        $placeholders = implode(',', array_fill(0, count($deleteID), '?'));
                        $types = str_repeat('i', count($deleteID));

                        $sqlDelLevel = "DELETE FROM level WHERE IDLevel IN ($placeholders)";
                        $stmtDel = $conn->prepare($sqlDelLevel);
                        if (!$stmtDel) {
                            throw new Exception("Gagal prepare delete level: " . $conn->error);
                        }
                        $stmtDel->bind_param($types, ...$deleteID);
                        $stmtDel->execute();

                        if ($stmtDel->affected_rows <= 0) {
                            $statusDelete = 2;
                            $errorList[] = [
                                "IDLevel" => implode(',', $deleteID),
                                "NamaLevel" => "-",
                                "Keterangan" => "Tidak ada data yang dihapus dari tabel level."
                            ];
                        }

                        $stmtDel->close();
                        $conn->commit();
                    } catch (Exception $e) {
                        $conn->rollback();
                        $statusDelete = 2;
                        $errorList[] = [
                            "IDLevel" => implode(',', $deleteID),
                            "NamaLevel" => "-",
                            "Keterangan" => "Terjadi kesalahan saat menghapus data: " . $e->getMessage()
                        ];
                    }
                }



                // --------------------------------------
                // LOG AKTIVITAS
                // --------------------------------------
                $di = json_decode($post['DeviceInfo'], true);
                $Platform = $di['platform'] ?? '';
                $DeviceName = $di['device_name'] ?? '';
                $FullDevice = $di['FullDevice'] ?? $Platform . " - " . $DeviceName;
                $IP = $post['IP'] ?? ($_SERVER['REMOTE_ADDR'] ?? '');
                $Category = "level";

                if (!empty($deleteID)) {
                    foreach ($oldData as $row) {
                        if (in_array($row['IDLevel'], $deleteID)) {
                            $KodeUnik = $row['IDLevel'];
                            $blacklist = [];
                            $whitelist = ["NamaLevel", "NamaLevelEN"];
                            $queryAcitivy = g_generateActivityQuery("level", "Delete", $row, null, $blacklist, $whitelist);
                            $this->activityController->generateActivity(
                                $post['IDUserLogin'],
                                $UserLogin,
                                $queryAcitivy,
                                $FullDevice,
                                $IP,
                                $Category,
                                $KodeUnik
                            );
                        }
                    }
                }

                // --------------------------------------
                // FINAL RETURN
                // --------------------------------------
                if ($statusDelete === 1 && empty($errorList)) {
                    return [
                        "Status" => 1,
                        "Keterangan" => "Semua data berhasil dihapus",
                        "listErrorMessage" => []
                    ];
                } else {
                    return [
                        "Status" => 0,
                        "Keterangan" => "",
                        "listErrorMessage" => $errorList
                    ];
                }
            });
        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage(),
                "listErrorMessage" => []
            ];
        }
    }
}
?>