<?php

class Journalarpaymentv2 extends MY_Controller
{
    var $db;
    public function index()
    {
        echo "PAYMENT RECEIVE";
    }
    public function __construct()
    {
        parent::__construct();
    }

    function getPeriode()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit();
            }

            $prm = $this->sys_input;

            $search = "";
            $number_limit = 10;
            $tot_count = 0;

            if (isset($prm["search"])) {
                $search = trim($prm["search"]);
                if ($search != "") {
                    $search = "%" . $prm["search"] . "%";
                } else {
                    $search = "%%";
                }
            }

            $sql = "SELECT
                periodeID AS id,
                periodeYear,
                periodeMonth,
                CONCAT(periodeYear, ' - ',periodeMonth) as yearandmonth,
                periodeName,
                CONCAT(DATE_FORMAT(periodeStartDate, '%d %M %Y'), ' - ', DATE_FORMAT(periodeEndDate, '%d %M %Y')) as periode
            FROM periode
            WHERE periodeIsActive = 'Y'
                AND periodeIsClosed = 'N'
            ORDER BY periodeID DESC, periodeMonth DESC
            LIMIT 18";
            $qry = $this->db->query($sql, []);
            if (!$qry) {
                $this->sys_error_db("select period", $this->db);
                exit();
            }
            $rst = $qry->result_array();
            $this->sys_ok($rst);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function search()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit();
            }
            $prm = $this->sys_input;
            $user = $this->sys_user;

            $regionalId = $prm["regionalId"] ?? null;
            $branchCode = $prm["branchCode"] == "" ? $user["M_BranchCode"] : $prm["branchCode"];
            $periodeid = $prm["periodeid"] ?? null;
            $xdate = $prm["xdate"] ?? null;
            $search = $prm["search"] ?? "";
            $search = "%" . trim($search) . "%";

            $loginLevel = $this->sys_user["loginLevel"];
            $where_conditions = [
                "jurnalIsActive = 'Y'",
                "jurnalperiodeID = ?",
                "DATE(jurnalDate) = ?",
                "jurnalNo LIKE ?",
            ];
            $params = [$periodeid, $xdate, $search];

            // Filter login level
            if ($loginLevel == "branch") {
                $where_conditions[] = "jurnalM_BranchCode = ?";
                $params[] = $branchCode;
            } elseif ($loginLevel == "regional") {
                $where_conditions[] = "jurnalS_RegionalID = ?";
                $params[] = $regionalId;

                if (!empty($branchCode)) {
                    $where_conditions[] = "jurnalM_BranchCode = ?";
                    $params[] = $branchCode;
                }
            }

            // Gabungkan WHERE SQL
            $where_sql = implode(" AND ", $where_conditions);

            // SQL utama
            $sql = "SELECT
                    jurnalID,
                    jurnalNo,
                    jurnalTitle,
                    jurnalDescription,
                    jurnalM_BranchCode,
                    DATE_FORMAT(jurnalDate, '%d-%m-%Y') as jurnalDate,
                    jurnalIsPosted,
                    M_BranchCompanyName,
                    S_RegionalID,
                    S_RegionalName,
                    M_BranchID,
                    M_BranchName,
                    periodeID,
                    periodeYear,
                    periodeMonth,
                    periodeName,
                    periodeStartDate,
                    periodeEndDate,
                    JurnalTypeID,
                    JurnalTypeCode,
                    JurnalTypeName,
                    JurnalTypeAccesRight,
                    '' as ErrStatus,
                    '' as ErrMsg,
                    '' as detailtx
                FROM jurnal
                JOIN m_branch_company ON jurnalM_BranchCompanyID = M_BranchCompanyID AND M_BranchCompanyIsActive = 'Y'
                JOIN periode ON jurnalperiodeID = periodeID AND periodeIsActive = 'Y'
                JOIN jurnal_type ON jurnalJurnalTypeID = JurnalTypeID AND JurnalTypeIsActive = 'Y' AND JurnalTypeIsAuto = 'Y'
                    AND JurnalTypeID IN (11, 12,13)
                JOIN s_regional ON JurnalS_RegionalID = S_RegionalID AND S_RegionalIsActive = 'Y'
                LEFT JOIN m_branch ON jurnalM_BranchCode = M_BranchCode AND M_BranchIsActive = 'Y'
                WHERE $where_sql
                GROUP BY jurnalID
                ORDER BY jurnalID DESC
            ";

            // Ambil total count
            $sql_total = "SELECT COUNT(*) AS total FROM ($sql) AS x";
            $qry_total = $this->db->query($sql_total, $params);

            $number_limit = 10;
            $current_page = (int) ($prm["current_page"] ?? 1);
            $number_offset = max(0, ($current_page - 1) * $number_limit);

            // Hitung total halaman
            $totalCount = 0;
            $totalPage = 0;
            if ($qry_total) {
                $totalCount = $qry_total->row()->total ?? 0;
                $totalPage = ceil($totalCount / $number_limit);
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select jurnal count error", $this->db);
                exit();
            }

            // Tambahkan LIMIT OFFSET
            $sql_paginated = $sql . " LIMIT ? OFFSET ?";
            $params_paginated = array_merge($params, [$number_limit, $number_offset]);

            $qry = $this->db->query($sql_paginated, $params_paginated);

            if ($qry) {
                $rows = $qry->result_array();
            } else {
                $this->db->trans_rollback();
                $this->sys_error_db("select jurnal error", $this->db);
                exit();
            }

            foreach ($rows as $key => $value) {
                $sql_err = "SELECT JurnalErr_ID,
                            JurnalErr_Msg
                            FROM jurnal_errors
                            WHERE JurnalErr_IsActive = 'Y'
                            AND JurnalErr_JurnalID = ?";
                $qry_err = $this->db->query($sql_err, [$value["jurnalID"]]);
                if (!$qry_err) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select jurnal msg error", $this->db);
                    exit();
                }

                $rows_err = $qry_err->result_array();

                // Decode JSON di dalam kolom JurnalErr_Msg
                foreach ($rows_err as &$row) {
                    $row["JurnalErr_Msg"] = json_decode($row["JurnalErr_Msg"], true);
                }
                if (count($rows_err) > 0) {
                    $rows[$key]["ErrStatus"] = "Y";
                    $rows[$key]["ErrMsg"] = $rows_err;
                } else {
                    $rows[$key]["ErrStatus"] = "N";
                    $rows[$key]["ErrMsg"] = [];
                }

                $sql_detail = "SELECT
                    jurnalTxID,
                    jurnalTxJurnalID,
                    jurnalTxCoaID,
                    jurnalTxDescription,
                    jurnalTxDebit,
                    jurnalTxCredit,
                    coaID,
                    coaAccountNo,
                    coaDescription,
                    coaSubDescription,
                    coaAccountType,
                    coaIsInput,
                    coaReportSchedule,
                    coaCurrencyCode,
                    coaCashFlowCategory,
                    GROUP_CONCAT(jurnalAddOnCode SEPARATOR ', ') as jurnalAddOnCode,
                    GROUP_CONCAT(jurnalAddOnValue SEPARATOR ' | ') as jurnalAddOnValue,
                    GROUP_CONCAT(M_ItemDesc SEPARATOR ', ') AS jurnalAddOnItem
                FROM jurnal_tx
                JOIN coa ON jurnalTxCoaID = coaID AND coaIsActive = 'Y'
                LEFT JOIN jurnal_addon ON jurnalTxID = jurnalAddOnJurnalTxID AND jurnalAddOnIsActive = 'Y'
                    AND (jurnalAddOnCode = 'ARDATE' OR jurnalAddOnCode = 'CMPNYNAME' OR jurnalAddOnCode = 'CMPNYNUM')
                LEFT JOIN m_item ON M_ItemID = jurnalAddOnM_ItemID
                WHERE jurnalTxIsActive = 'Y'
                    AND jurnalTxJurnalID = ?
                GROUP BY jurnalTxID
                ORDER BY
                CASE
                    WHEN jurnalTxDebit > 0 THEN 0
                    ELSE 1
                END,
                jurnalTxID ASC";
                $qry_detail = $this->db->query($sql_detail, [$value["jurnalID"]]);
                if (!$qry_detail) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("select jurnal tx error", $this->db);
                    exit();
                }

                // echo $this->db->last_query();
                // exit;

                $rows_detail = $qry_detail->result_array();
                if (count($rows_detail) > 0) {
                    $rows[$key]["detailtx"] = $rows_detail;
                } else {
                    $rows[$key]["detailtx"] = [];
                }
            }

            $result = [
                "total" => $totalPage,
                "totalfilter" => $totalCount,
                "records" => $rows,
            ];
            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getRegional()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }
            $prm = $this->sys_input;
            $regionalId = $prm["regionalId"] ?? null;

            $sql = "SELECT S_RegionalID, S_RegionalName
                    FROM s_regional
                    WHERE S_RegionalIsActive = 'Y'
                    AND S_RegionalID = ?
                    ORDER BY S_RegionalName ASC";

            $qry = $this->db->query($sql, [$regionalId]);
            if (!$qry) {
                $this->db->trans_rollback();
                $this->sys_error_db("select regional", $this->db);
                exit();
            }

            $rows = $qry->result_array();
            $selected = null;

            // Cari regional yang sesuai dengan regionalId
            foreach ($rows as $r) {
                if ($r["S_RegionalID"] == $regionalId) {
                    $selected = $r;
                    break;
                }
            }

            $result = [
                "records" => $rows,
                "selected" => $selected,
                "sql" => $this->db->last_query(),
            ];

            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getBranch()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
            }
            $prm = $this->sys_input;

            $regionalId = isset($prm["regionalId"]) ? $prm["regionalId"] : null;
            $branchCode = isset($prm["branchCode"]) ? $prm["branchCode"] : null;
            $query = "SELECT DISTINCT
                      M_BranchCode,
                      M_BranchName
                      FROM m_branch
                      WHERE M_BranchIsActive = 'Y'
                      AND M_BranchS_RegionalID = ?
                      ORDER BY M_BranchName ASC";
            $exec = $this->db->query($query, [$regionalId]);
            if (!$exec) {
                $this->db->trans_rollback();
                $this->sys_error_db("select branch", $this->db);
                exit();
            }

            $rows = $exec->result_array();
            $selected = [
                "M_BranchCode" => "",
                "M_BranchName" => "",
            ];

            // Cari regional yang sesuai dengan regionalId
            if (!empty($branchCode)) {
                foreach ($rows as $r) {
                    if ($r["M_BranchCode"] == $branchCode) {
                        $selected = $r;
                        break;
                    }
                }
            }

            $result = [
                "records" => $rows,
                "selected" => $selected,
                "sql" => $this->db->last_query(),
            ];

            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getUserApproveLevel()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }

            $user = $this->sys_user;
            $sql = "SELECT
                M_ApproveLevelID,
                M_ApproveLevelName,
                DivisionID,
                DivisionName,
                DivisionKodeSurat
            FROM m_user
            JOIN m_approve_level ON M_ApproveLevelID = M_UserM_ApproveLevelID
            JOIN m_userdivision ON M_UserDivisionM_UserID = M_UserID
                AND M_UserDivisionIsActive = 'Y'
            JOIN division ON DivisionID = M_UserDivisionDivisionID
                AND DivisionIsActive = 'Y'
            WHERE M_ApproveLevelIsActive = 'Y'
                AND M_UserID = ?";
            $que = $this->db->query($sql, [$user["M_UserID"]]);
            if (!$que) {
                $this->sys_error_db("[Error] get user approve level");
                exit();
            }

            $result = $que->row_array();
            if (!$result) {
                $result = [
                    "M_ApproveLevelID" => 0,
                    "M_ApproveLevelName" => "",
                ];
            }

            $this->sys_ok($result);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getListingCOA()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }
            $param = $this->sys_input;

            $keyword = "%";
            if ($param["keyword"] != "") {
                $keyword = $param["keyword"] . "%";
            }

            $sql = "SELECT
                coaID,
                coaAccountNo,
                coaDescription
            FROM coa
            WHERE coaIsActive = 'Y'
                AND coaIsInput = 'Y'
                AND coaDescription LIKE ?";
            $que = $this->db->query($sql, [$keyword]);
            if (!$que) {
                $this->sys_error_db("[Error] get listint account");
                exit();
            }

            $data = $que->result_array();
            $this->sys_ok($data);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function saveEditJurnal()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }

            $this->db->trans_begin();

            $param = $this->sys_input;
            $user = $this->sys_user;

            // get current jurnal data
            $sql_data = "SELECT
                jurnalTxID,
                jurnalTxJurnalID,
                jurnalTxCoaID,
                jurnalTxDescription,
                jurnalTxDebit,
                jurnalTxCredit
            FROM jurnal_tx
            WHERE jurnalTxJurnalID = ?";
            $que_current = $this->db->query($sql_data, [$param["jurnalID"]]);
            if (!$que_current) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get current jurnal tx data");
                exit();
            }
            $curr_jurnal = $que_current->result_array();

            $sql_header = "UPDATE jurnal SET
                jurnalEditStatus = 'Y',
                jurnalLastUpdated = NOW()
            WHERE jurnalID = ?";
            $que_header = $this->db->query($sql_header, [$param["jurnalID"]]);
            if (!$que_header) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] update status jurnal edit");
                exit();
            }

            $jurnaldetail = $param["jurnaldetail"];
            $sql = "UPDATE jurnal_tx SET
                jurnalTxCoaID = ?,
                jurnalTxDescription = ?,
                jurnalTxLastUpdated = NOW(),
                jurnalTxM_UserID = ?
            WHERE jurnalTxID = ?
                AND jurnalTxJurnalID = ?
                AND jurnalTxIsActive = 'Y'";

            foreach ($jurnaldetail as $key => $obj) {
                $que = $this->db->query($sql, [
                    $obj["coaID"],
                    $obj["coaDescription"],
                    $user["M_UserID"],
                    $obj["jurnalTxID"],
                    $obj["jurnalID"],
                ]);
                if (!$que) {
                    $this->db->trans_rollback();
                    $this->sys_error_db("[Error] update data jurnal tx");
                    exit();
                }
            }

            // get new jurnal data
            $que_latest = $this->db->query($sql_data, [$param["jurnalID"]]);
            if (!$que_latest) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] get latest jurnal tx data");
                exit();
            }
            $new_jurnal = $que_latest->result_array();

            $sql_log = "INSERT INTO acc_one_log.jurnal_edit_log (
                JurnalEditLogIDJurnalID,
                JurnalEditLogIDJsonBefore,
                JurnalEditLogIDJsonAfter,
                JurnalEditLogUserID,
                JurnalEditLogCreated
            ) VALUES (?,?,?,?,NOW())";
            $que_log = $this->db->query($sql_log, [
                $param["jurnalID"],
                json_encode($curr_jurnal),
                json_encode($new_jurnal),
                $user["M_UserID"],
            ]);
            if (!$que_log) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] insert into acc one jurnal log");
                exit();
            }

            $this->db->trans_commit();
            $this->sys_ok("success update jurnal");
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function changeJurnalToPosted()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }

            $this->db->trans_begin();
            $param = $this->sys_input;
            $user = $this->sys_user;

            $sqlbranch = " ";
            if ($user["M_BranchID"] != "0") {
                $sqlbranch .= " AND jurnalM_BranchCode = " . $user["M_BranchCode"];
            }

            $sql = "UPDATE jurnal SET
                jurnalIsPosted = 'Y',
                jurnalLastUpdated = NOW(),
                jurnalM_UserID = ?
            WHERE jurnalperiodeID = ?
                AND jurnalJurnalTypeID = ?
                AND JurnalS_RegionalID = ?
                AND jurnalIsPosted = 'N'
                AND jurnalEditStatus = 'N'
                AND jurnalIsActive = 'Y'";
            $sql .= $sqlbranch;
            $que = $this->db->query($sql, [
                $user["M_UserID"],
                $param["periodeID"],
                $param["jurnalTypeID"],
                $user["S_RegionalID"],
            ]);
            if (!$que) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] update status jurnal ke posting");
                exit();
            }

            $this->db->trans_commit();
            $this->sys_ok("[Success] update status posting jurnal pada periode ini");
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    function getTotalJurnalNotPostedPerPeriod()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }
            $param = $this->sys_input;
            $user = $this->sys_user;

            $branchcode = "X";
            if ($user["M_BranchCode"] != "") {
                $branchcode = $user["M_BranchCode"];
            }

            $sql = "WITH TargetStatuses AS (
                SELECT 'N' AS status
                UNION ALL
                SELECT 'Y' AS status
            )
            SELECT
                JurnalTypeID,
                TS.status AS jurnalEditStatus,
                COALESCE(COUNT(J.jurnalEditStatus), 0) AS total_jurnal
            FROM
                TargetStatuses TS
            LEFT JOIN jurnal J ON TS.status = J.jurnalEditStatus
                AND J.jurnalperiodeID = ?
                AND J.JurnalS_RegionalID = ?
                AND (J.jurnalM_BranchCode = ? OR ? = 'X')
                AND J.jurnalIsActive = 'Y'
                AND J.jurnalIsPosted = 'N'
            JOIN jurnal_type ON JurnalTypeID = jurnalJurnalTypeID
                AND JurnalTypeID IN (11,12,13)
            GROUP BY TS.status
            ORDER BY TS.status";

            $que = $this->db->query($sql, [
                $param["periodeID"],
                $user["S_RegionalID"],
                $branchcode,
                $branchcode,
            ]);
            if (!$que) {
                $this->sys_error_db("[Error] get total jurnal not posted");
                exit();
            }

            $total = $que->result_array();
            $this->sys_ok($total);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    public function closeJurnalPerPeriode()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("Invalid Token");
                exit();
            }

            $param = $this->sys_input;
            $user = $this->sys_user;

            $this->db->trans_begin();
            $sqlbranch = " ";
            if ($user["M_BranchID"] != "0") {
                $sqlbranch .= " AND jurnalM_BranchCode = '{$user["M_BranchCode"]}'";
            }

            $sql = "UPDATE jurnal SET
                jurnalIsClosed = 'Y',
                jurnalLastUpdated = NOW(),
                jurnalM_UserID = ?
            WHERE jurnalperiodeID = ?
                AND jurnalJurnalTypeID = ?
                AND JurnalS_RegionalID = ?
                AND jurnalIsPosted = 'Y'
                AND jurnalEditStatus = 'N'
                AND jurnalIsActive = 'Y'";
            $sql .= $sqlbranch;
            $que = $this->db->query($sql, [
                $user["M_UserID"],
                $param["periodeID"],
                $param["jurnalTypeID"],
                $user["S_RegionalID"],
            ]);
            if (!$que) {
                $this->db->trans_rollback();
                $this->sys_error_db("[Error] update status jurnal ke closed");
                exit();
            }

            $this->db->trans_commit();
            $this->sys_ok("[Success] update status closed jurnal pada periode ini");
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }

    public function getDataJurnalNotClosedPerPeriod()
    {
        try {
            if (!$this->isLogin) {
                $this->sys_error("invalid token");
                exit();
            }
            $param = $this->sys_input;
            $user = $this->sys_user;

            $branchcode = "X";
            if ($user["M_BranchCode"] != "") {
                $branchcode = $user["M_BranchCode"];
            }

            $sql = "WITH TargetStatuses AS (
                SELECT 'N' AS status
                UNION ALL
                SELECT 'Y' AS status
            ),
            TargetType AS (
                SELECT JurnalTypeID
                FROM jurnal_type
                WHERE JurnalTypeID IN (11,12,13)
            )
            SELECT
                TT.JurnalTypeID,
                TS.status AS jurnalIsPosted,
                COUNT(J.jurnalID) AS total_jurnal
            FROM TargetStatuses TS
            CROSS JOIN TargetType TT
            LEFT JOIN jurnal J ON TS.status = J.jurnalIsPosted
                AND J.jurnalJurnalTypeID = TT.JurnalTypeID
                AND J.jurnalperiodeID = ?
                AND J.JurnalS_RegionalID = ?
                AND (J.jurnalM_BranchCode = ? OR ? = 'X')
                AND J.jurnalIsActive = 'Y'
                AND J.jurnalIsClosed = 'N'
            GROUP BY TT.JurnalTypeID, TS.status
            ORDER BY TS.status";
            $que = $this->db->query($sql, [
                $param["periodeID"],
                $user["S_RegionalID"],
                $branchcode,
                $branchcode,
            ]);
            if (!$que) {
                $this->sys_error_db("[Error] get total jurnal not closed");
                exit();
            }

            $total = $que->result_array();
            $this->sys_ok($total);
        } catch (Exception $exc) {
            $message = $exc->getMessage();
            $this->sys_error($message);
        }
    }
}
