<?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';

class MembershipPaymentSettingController
{
    private $conn;
    private $table = "membership_payment_setting T";
    private $pk = "IDMembershipPaymentSetting";
    private $sv = "MembershipPaymentSetting";

    protected $displayedColumn = [
        'T.IDMembershipPaymentSetting',
        'T.NamaPaket',
        'T.KodePaket',
        'T.Nominal',
        'T.DurasiTahun',
        'T.DurasiBulan',
        'T.Deskripsi',
        'T.Bank',
        'T.NomorRekening',
        'T.NamaRekening',
        'T.Benefits',
        'T.IsActive',
        'T.IsDefault',
        'T.Urutan',
        'T.CreateBy',
        'T.CreateAt',
        'T.LastUpdateBy',
        'T.LastUpdateAt'
    ];

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

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

        $listSearch = [
            'T.NamaPaket',
            'T.KodePaket',
            'T.Deskripsi'
        ];

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

    public function update($post, $files)
    {
        try {
            // Validasi required fields
            if (empty($post['NamaPaket'])) {
                throw new Exception("Nama Paket tidak boleh kosong");
            }

            if (empty($post['KodePaket'])) {
                throw new Exception("Kode Paket tidak boleh kosong");
            }

            if (!isset($post['Nominal']) || !is_numeric($post['Nominal']) || $post['Nominal'] < 0) {
                throw new Exception("Nominal harus diisi dengan angka minimal 0");
            }

            $DurasiTahun = isset($post['DurasiTahun']) ? intval($post['DurasiTahun']) : 0;
            $DurasiBulan = isset($post['DurasiBulan']) ? intval($post['DurasiBulan']) : 0;

            // Validasi durasi: minimal salah satu harus > 0
            if ($DurasiTahun === 0 && $DurasiBulan === 0) {
                throw new Exception("Durasi Tahun atau Durasi Bulan minimal salah satu harus diisi");
            }

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

                $NamaPaket = trim($post['NamaPaket']);
                $KodePaket = trim($post['KodePaket']);
                $Nominal = floatval($post['Nominal']);
                $Deskripsi = trim($post['Deskripsi'] ?? '');
                $Bank = trim($post['Bank'] ?? '');
                $NomorRekening = trim($post['NomorRekening'] ?? '');
                $NamaRekening = trim($post['NamaRekening'] ?? '');
                $Benefits = trim($post['Benefits'] ?? '');
                $IsActive = isset($post['IsActive']) ? intval($post['IsActive']) : 1;
                $IsDefault = isset($post['IsDefault']) ? intval($post['IsDefault']) : 0;
                $Urutan = isset($post['Urutan']) ? intval($post['Urutan']) : 0;
                
                $isUpdate = !empty($post['IDMembershipPaymentSetting']) && intval($post['IDMembershipPaymentSetting']) > 0;

                // --------------------------------------
                // MULAI USER AKSES
                // --------------------------------------
                $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'] ?? "Akses pengguna tidak valid";
                    throw new Exception($msg);
                }
                // --------------------------------------
                // END USER AKSES
                // --------------------------------------

                // =========================
                // START - cek duplikat
                // ========================= 
                $duplikatDataFilter = [];
                $duplikatDataFilter[] = ["KodePaket", $KodePaket, 1];

                if ($isUpdate) {
                    $duplikatDataFilter[] = ["IDMembershipPaymentSetting", $post['IDMembershipPaymentSetting'], 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 = "Kode Paket sudah terpakai, mohon diganti";
                    throw new Exception($msg);
                }
                // =========================
                // END - cek duplikat
                // =========================

                // =========================
                // START - Jika IsDefault = 1, unset default yang lain
                // =========================
                if ($IsDefault == 1) {
                    $excludeCondition = $isUpdate ? " AND IDMembershipPaymentSetting != " . intval($post['IDMembershipPaymentSetting']) : "";
                    $sqlUnsetDefault = "UPDATE membership_payment_setting 
                                        SET IsDefault = 0 
                                        WHERE IsDefault = 1" . $excludeCondition;
                    $conn->query($sqlUnsetDefault);
                }
                // =========================
                // END - Handle default
                // =========================

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

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

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

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

                    if ($oldDataResult['Status'] == 1 && !empty($oldDataResult['list_data'])) {
                        $oldData = $oldDataResult['list_data'][0];
                    } else {
                        $msg = $oldDataResult['Keterangan'] ?? "Data tidak ditemukan";
                        throw new Exception($msg);
                    }
                }
                // =========================
                // END - ambil data lama
                // =========================

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

                if ($isUpdate) {
                    // Update membership_payment_setting
                    $sql = "UPDATE membership_payment_setting 
                            SET 
                                NamaPaket = ?,
                                KodePaket = ?,
                                Nominal = ?,
                                DurasiTahun = ?,
                                DurasiBulan = ?,
                                Deskripsi = ?, 
                                Bank = ?,
                                NomorRekening = ?,
                                NamaRekening = ?,
                                Benefits = ?,
                                LastUpdateBy = ?,
                                LastUpdateAt = NOW()
                            WHERE IDMembershipPaymentSetting = ?";

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

                    $stmt->bind_param(
                        "ssssssssssss",
                        $NamaPaket,
                        $KodePaket,
                        $Nominal,
                        $DurasiTahun,
                        $DurasiBulan,
                        $Deskripsi, 
                        $Bank,
                        $NomorRekening,
                        $NamaRekening,
                        $Benefits,
                        $UserLogin,
                        $post['IDMembershipPaymentSetting']
                    );

                    $stmt->execute();

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

                    $stmt->close();
                    $NewID = $post['IDMembershipPaymentSetting'];
                } else {
                    // Insert membership_payment_setting baru
                    $sql = "INSERT INTO membership_payment_setting 
                            (NamaPaket, KodePaket, Nominal, DurasiTahun, DurasiBulan, Deskripsi, 
                                Bank, NomorRekening, NamaRekening, Benefits,
                             IsActive, IsDefault, Urutan, CreateBy, CreateAt) 
                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())";

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

                    $stmt->bind_param(
                        "ssdiisssssiisis",
                        $NamaPaket,
                        $KodePaket,
                        $Nominal,
                        $DurasiTahun,
                        $DurasiBulan,
                        $Deskripsi,
                        $Bank,
                        $NomorRekening,
                        $NamaRekening,
                        $Benefits,
                        $IsActive,
                        $IsDefault,
                        $Urutan,
                        $UserLogin
                    );

                    $stmt->execute();

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

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

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

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

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

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

                    if ($newDataResult['Status'] == 1 && !empty($newDataResult['list_data'])) {
                        $newData = $newDataResult['list_data'][0];
                    } else {
                        $msg = $newDataResult['Keterangan'] ?? "Gagal mengambil data baru";
                        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 = $post['IP'] ?? ($_SERVER['REMOTE_ADDR'] ?? '');

                $Category = "membership_payment_setting";
                $KodeUnik = $NewID;
                $TipeActivity = $isUpdate ? "Modify" : "Insert";
                
                $queryAcitivy = g_generateActivityQuery(
                    $Category,
                    $TipeActivity,
                    $newData,
                    $oldData,
                    []
                );
                
                if (!empty($queryAcitivy)) {
                    $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] ?? null;
            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";

                $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 
                // --------------------------------------
                $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 = [
                    ["IDMembershipPaymentSetting", $idArray, 7]
                ];

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

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

                if ($oldDataResult['Status'] != 1 || empty($oldDataResult['list_data'])) {
                    throw new Exception($oldDataResult['Keterangan'] ?? "Data tidak ditemukan");
                }

                $oldData = $oldDataResult['list_data'];

                // --------------------------------------
                // PROSES DELETE
                // --------------------------------------
                $deleteID = [];
                foreach ($oldData as $row) {
                    $deleteID[] = $row['IDMembershipPaymentSetting'];
                }

                if (empty($deleteID)) {
                    return [
                        "Status" => 0,
                        "Keterangan" => "Tidak ada data yang akan dihapus",
                        "listErrorMessage" => []
                    ];
                }

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

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

                    if ($stmtDel->affected_rows <= 0) {
                        throw new Exception("Tidak ada data yang dihapus");
                    }

                    $stmtDel->close();
                } catch (Exception $e) {
                    throw new Exception("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 = "membership_payment_setting";

                foreach ($oldData as $row) {
                    $whitelist = ["NamaPaket", "KodePaket", "Nominal", "DurasiTahun", "DurasiBulan"];
                    $queryAcitivy = g_generateActivityQuery(
                        $Category,
                        "Delete",
                        $row,
                        null,
                        [],
                        $whitelist
                    );
                    
                    if (!empty($queryAcitivy)) {
                        $this->activityController->generateActivity(
                            $post['IDUserLogin'],
                            $UserLogin,
                            $queryAcitivy,
                            $FullDevice,
                            $IP,
                            $Category,
                            $row['IDMembershipPaymentSetting']
                        );
                    }
                }

                // --------------------------------------
                // FINAL RETURN
                // --------------------------------------
                return [
                    "Status" => 1,
                    "Keterangan" => "Data berhasil dihapus",
                    "listErrorMessage" => []
                ];
            });
        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage(),
                "listErrorMessage" => []
            ];
        }
    }

    /**
     * Get default payment setting
     */
    public function getDefault()
    {
        try {
            $sql = "SELECT * FROM membership_payment_setting 
                    WHERE IsActive = 1 AND IsDefault = 1 
                    LIMIT 1";
            
            $result = $this->conn->query($sql);
            $data = $result->fetch_assoc();

            return [
                "Status" => 1,
                "Keterangan" => "Success",
                "data" => $data
            ];
        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage()
            ];
        }
    }

    /**
     * Get active payment settings
     */
    public function getActiveSettings()
    {
        try {
            $sql = "SELECT * FROM membership_payment_setting 
                    WHERE IsActive = 1 
                    ORDER BY Urutan ASC, NamaPaket ASC";
            
            $result = $this->conn->query($sql);
            $data = [];
            while ($row = $result->fetch_assoc()) {
                $data[] = $row;
            }

            return [
                "Status" => 1,
                "Keterangan" => "Success",
                "data" => $data
            ];
        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage()
            ];
        }
    }

    /**
     * Toggle active status
     */
    public function toggleActive($post)
    {
        try {
            if (empty($post['IDMembershipPaymentSetting'])) {
                throw new Exception("ID Membership Payment Setting tidak boleh kosong");
            }

            $ID = intval($post['IDMembershipPaymentSetting']);
            $IsActive = isset($post['IsActive']) ? intval($post['IsActive']) : 0;

            $sql = "UPDATE membership_payment_setting SET IsActive = ? WHERE IDMembershipPaymentSetting = ?";
            $stmt = $this->conn->prepare($sql);
            $stmt->bind_param("ii", $IsActive, $ID);
            $stmt->execute();

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

            $stmt->close();

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