<?php
/**
 * Member Functions - Adopsi dari SLiMS member.inc.php
 * Path: plugins/multi_opac_path/pages/member_functions.php
 * Version: 1.0.1 (Fixed missing simbio_datagrid class)
 */

if (!defined('INDEX_AUTH')) {
    die("Direct access not allowed");
}

// ============================================================
// LOAD REQUIRED CLASSES DARI SLiMS CORE
// ============================================================
require_once SIMBIO . 'simbio_GUI/table/simbio_table.inc.php';
require_once SIMBIO . 'simbio_DB/datagrid/simbio_dbgrid.inc.php';
require_once SIMBIO . 'simbio_GUI/paging/simbio_paging.inc.php';
require_once SIMBIO . 'simbio_UTILS/simbio_date.inc.php';
// ============================================================

// Definisikan konstanta untuk password
if (!defined('CURR_PASSWD_WRONG')) define('CURR_PASSWD_WRONG', -1);
if (!defined('PASSWD_NOT_MATCH')) define('PASSWD_NOT_MATCH', -2);
if (!defined('CANT_UPDATE_PASSWD')) define('CANT_UPDATE_PASSWD', -3);

// ============================================================
// 1. SHOW LOAN LIST (PEMINJAMAN AKTIF) - DIPERBAIKI
// ============================================================
function showLoanList($num_recs_show = 20)
{
    global $dbs, $_SESSION;
    
    // ============================================================
    // AMBIL library_id DARI SESSION ATAU DATABASE
    // ============================================================
    $library_id = $_SESSION['multi_opac']['library_id'] ?? null;
    
    if (!$library_id && isset($_SESSION['mid'])) {
        $stmt = $dbs->prepare("SELECT library_id FROM member WHERE member_id = ?");
        $stmt->execute([$_SESSION['mid']]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($row) {
            $library_id = $row['library_id'];
            $_SESSION['multi_opac']['library_id'] = $library_id;
        }
    }
    
    $library_filter = '';
    if ($library_id) {
        $library_filter = " AND l.library_id = " . intval($library_id);
    }
    // ============================================================
    
    // ============================================================
    // QUERY MANUAL DENGAN JOIN ke library, fines, loan_rules
    // ============================================================
    $sql = "
        SELECT 
            l.loan_id,
            l.item_code,
            b.title,
            l.loan_date,
            l.due_date,
            l.is_lent,
            l.is_return,
            lib.library_code,
            lib.library_name,
            lr.loan_limit,
            lr.loan_periode,
            lr.reborrow_limit,
            lr.fine_each_day,
            lr.grace_periode,
            lr.member_type_id,
            (
                SELECT SUM(f.debet - f.credit - f.discount_amount) 
                FROM fines f 
                WHERE f.member_id = l.member_id 
                  AND f.library_id = l.library_id
                  AND f.status IN ('unpaid', 'partial')
            ) AS total_fines,
            (
                SELECT COUNT(*) 
                FROM fines f 
                WHERE f.member_id = l.member_id 
                  AND f.library_id = l.library_id
                  AND f.status IN ('unpaid', 'partial')
            ) AS fines_count
        FROM loan l
        LEFT JOIN item i ON l.item_code = i.item_code AND i.library_id = l.library_id
        LEFT JOIN biblio b ON i.biblio_id = b.biblio_id AND b.library_id = l.library_id
        LEFT JOIN mst_library lib ON l.library_id = lib.library_id
        LEFT JOIN mst_loan_rules lr ON l.loan_rules_id = lr.loan_rules_id 
            AND lr.library_id = l.library_id
        WHERE l.member_id = '" . $dbs->escape_string($_SESSION['mid']) . "'
          AND l.is_lent = 1 
          AND l.is_return = 0
          $library_filter
        GROUP BY l.loan_id
        ORDER BY l.loan_date DESC
        LIMIT " . intval($num_recs_show)
    ;
    
    $query = $dbs->query($sql);
    
    // ============================================================
    // AMBIL DATA DENGAN fetch_assoc() (TIDAK PAKAI fetchAll)
    // ============================================================
    $rows = [];
    $total_all_fines = 0;
    while ($row = $query->fetch_assoc()) {
        $rows[] = $row;
        $total_all_fines += (float)($row['total_fines'] ?? 0);
    }
    // ============================================================
    
    $result = '<div class="memberLoanListInfo my-3">';
    $result .= count($rows) . ' ' . __('item(s) currently on loan');
    if ($total_all_fines > 0) {
        $result .= ' | <span class="text-danger"><strong>⚠️ Total Denda: Rp ' . number_format($total_all_fines, 0, ',', '.') . '</strong></span>';
    }
    $result .= '</div>';
    
    if (count($rows) > 0) {
        $result .= '<table class="table table-striped table-bordered">';
        $result .= '<thead><tr>
                        <th>' . __('Item Code') . '</th>
                        <th>' . __('Title') . '</th>
                        <th>' . __('Library') . '</th>
                        <th>' . __('Loan Date') . '</th>
                        <th>' . __('Due Date') . '</th>
                        <th>' . __('Status') . '</th>
                    </tr></thead><tbody>';
        
        $curr_date = date('Y-m-d');
        foreach ($rows as $row) {
            // Cek overdue
            $is_overdue = ($row['due_date'] < $curr_date);
            $status_text = ($is_overdue) ? '<span class="text-danger">⚠️ Overdue</span>' : '<span class="text-success">✅ Active</span>';
            
            // Cek denda per item
            $fine_text = '';
            if (!empty($row['total_fines']) && $row['total_fines'] > 0) {
                $fine_text = ' <span class="text-danger">(Rp ' . number_format($row['total_fines'], 0, ',', '.') . ')</span>';
            }
            
            $result .= '<tr>';
            $result .= '<td><code>' . htmlspecialchars($row['item_code']) . '</code></td>';
            $result .= '<td>' . htmlspecialchars($row['title'] ?? '-') . '</td>';
            $result .= '<td>';
            $result .= '<span class="badge bg-info text-dark">' . htmlspecialchars($row['library_code'] ?? '-') . '</span>';
            $result .= '<br><small>' . htmlspecialchars($row['library_name'] ?? '-') . '</small>';
            $result .= '</td>';
            $result .= '<td>' . $row['loan_date'] . '</td>';
            $result .= '<td>' . $row['due_date'] . $fine_text . '</td>';
            $result .= '<td>' . $status_text . '</td>';
            $result .= '</tr>';
            
            // ============================================================
            // LOAN RULES (Detail di bawah setiap item)
            // ============================================================
            if (!empty($row['loan_limit']) || !empty($row['loan_periode'])) {
                $result .= '<tr class="table-light">';
                $result .= '<td colspan="6" class="text-muted small">';
                $result .= '<strong>Loan Rules:</strong> ';
                if ($row['loan_limit']) $result .= 'Limit: <strong>' . $row['loan_limit'] . '</strong> | ';
                if ($row['loan_periode']) $result .= 'Periode: <strong>' . $row['loan_periode'] . '</strong> hari | ';
                if ($row['reborrow_limit']) $result .= 'Reborrow: <strong>' . $row['reborrow_limit'] . '</strong> | ';
                if ($row['fine_each_day']) $result .= 'Denda/hari: <strong>Rp ' . number_format($row['fine_each_day'], 0, ',', '.') . '</strong> | ';
                if ($row['grace_periode']) $result .= 'Grace Periode: <strong>' . $row['grace_periode'] . '</strong> hari';
                $result .= '</td>';
                $result .= '</tr>';
            }
        }
        
        $result .= '</tbody></table>';
    } else {
        $result .= '<div class="alert alert-info">' . __('No items currently on loan.') . '</div>';
    }
    
    return $result;
}

// ============================================================
// 2. SHOW BOOKMARK LIST
// ============================================================
function showBookmarkList($num_recs_show = 20)
{
    global $dbs, $_SESSION;
    
    $table_spec = 'biblio_mark AS bm
        INNER JOIN biblio AS b ON b.biblio_id=bm.biblio_id';
    
    $mark_list = new simbio_datagrid();
    $mark_list->disable_paging = false;
    $mark_list->table_ID = 'bookmarklist';
    $mark_list->setSQLColumn(
        'b.title AS \'' . __('Title') . '\'',
        'bm.created_at AS \'' . __('Marked At') . '\'',
        'bm.biblio_id AS \'' . __('Action') . '\''
    );
    $mark_list->setSQLorder('bm.created_at DESC');
    $criteria = sprintf('bm.member_id=\'%s\'', $_SESSION['mid']);
    $mark_list->setSQLCriteria($criteria);
    $mark_list->modifyColumnContent(0, 'callback{showBookCover}');
    $mark_list->modifyColumnContent(1, 'callback{showDetailDate}');
    $mark_list->modifyColumnContent(2, 'callback{showMarkDetail}');
    $mark_list->table_attr = 'class="table table-striped"';
    $mark_list->table_header_attr = 'class="dataListHeader"';
    $mark_list->using_AJAX = false;
    
    $result = $mark_list->createDataGrid($dbs, $table_spec, $num_recs_show);
    $result = '<div class="memberBookmarkListInfo my-3">' . $mark_list->num_rows . ' ' . __('title currently on list') . '</div>' . "\n" . $result;
    return $result;
}

// ============================================================
// 3. SHOW BASKET (KERANJANG JUDUL - CUSTOM)
// ============================================================
function showBasket($num_recs_show = 20)
{
    // Gunakan member_basket.php yang sudah ada
    ob_start();
    include __DIR__ . '/member_basket.php';
    return ob_get_clean();
}

// ============================================================
// 4. SHOW LOAN HISTORY - DIPERBAIKI
// ============================================================
function showLoanHist($num_recs_show = 20)
{
    global $dbs, $_SESSION;
    
    // ============================================================
    // AMBIL library_id DARI SESSION ATAU DATABASE
    // ============================================================
    $library_id = $_SESSION['multi_opac']['library_id'] ?? null;
    
    if (!$library_id && isset($_SESSION['mid'])) {
        $stmt = $dbs->prepare("SELECT library_id FROM member WHERE member_id = ?");
        $stmt->execute([$_SESSION['mid']]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($row) {
            $library_id = $row['library_id'];
            $_SESSION['multi_opac']['library_id'] = $library_id;
        }
    }
    
    $library_filter = '';
    if ($library_id) {
        $library_filter = " AND l.library_id = " . intval($library_id);
    }
    // ============================================================
    
    // ============================================================
    // QUERY MANUAL UNTUK LOAN HISTORY
    // ============================================================
    $sql = "
        SELECT 
            l.item_code,
            b.title,
            l.loan_date,
            l.return_date,
            lib.library_code,
            lib.library_name,
            (
                SELECT SUM(f.debet - f.credit - f.discount_amount) 
                FROM fines f 
                WHERE f.member_id = l.member_id 
                  AND f.library_id = l.library_id
                  AND f.status = 'paid'
            ) AS total_paid_fines
        FROM loan l
        LEFT JOIN item i ON l.item_code = i.item_code AND i.library_id = l.library_id
        LEFT JOIN biblio b ON i.biblio_id = b.biblio_id AND b.library_id = l.library_id
        LEFT JOIN mst_library lib ON l.library_id = lib.library_id
        WHERE l.member_id = '" . $dbs->escape_string($_SESSION['mid']) . "'
          AND l.is_lent = 1 
          AND l.is_return = 1
          $library_filter
        GROUP BY l.loan_id
        ORDER BY l.loan_date DESC
        LIMIT " . intval($num_recs_show)
    ;
    
    $query = $dbs->query($sql);
    
    // ============================================================
    // AMBIL DATA DENGAN fetch_assoc()
    // ============================================================
    $rows = [];
    while ($row = $query->fetch_assoc()) {
        $rows[] = $row;
    }
    // ============================================================
    
    $result = '<div class="memberLoanHistInfo my-3">' . count($rows) . ' ' . __('item(s) loan history') . '</div>';
    
    if (count($rows) > 0) {
        $result .= '<table class="table table-striped table-bordered">';
        $result .= '<thead><tr>
                        <th>' . __('Item Code') . '</th>
                        <th>' . __('Title') . '</th>
                        <th>' . __('Library') . '</th>
                        <th>' . __('Loan Date') . '</th>
                        <th>' . __('Return Date') . '</th>
                        <th>' . __('Fines') . '</th>
                    </tr></thead><tbody>';
        
        foreach ($rows as $row) {
            $fine_text = (!empty($row['total_paid_fines']) && $row['total_paid_fines'] > 0) 
                        ? 'Rp ' . number_format($row['total_paid_fines'], 0, ',', '.') 
                        : '-';
            
            $result .= '<tr>';
            $result .= '<td><code>' . htmlspecialchars($row['item_code']) . '</code></td>';
            $result .= '<td>' . htmlspecialchars($row['title'] ?? '-') . '</td>';
            $result .= '<td>';
            $result .= '<span class="badge bg-info text-dark">' . htmlspecialchars($row['library_code'] ?? '-') . '</span>';
            $result .= '<br><small>' . htmlspecialchars($row['library_name'] ?? '-') . '</small>';
            $result .= '</td>';
            $result .= '<td>' . $row['loan_date'] . '</td>';
            $result .= '<td>' . $row['return_date'] . '</td>';
            $result .= '<td>' . $fine_text . '</td>';
            $result .= '</tr>';
        }
        
        $result .= '</tbody></table>';
    } else {
        $result .= '<div class="alert alert-info">' . __('No loan history found.') . '</div>';
    }
    
    return $result;
}

// ============================================================
// 5. SHOW MEMBER DETAIL (PROFIL MEMBER)
// ============================================================
function showMemberDetail()
{
    global $_SESSION;
    
    $detail = '<table class="table table-striped">' . "\n";
    if ($_SESSION['m_membership_pending'] || $_SESSION['m_is_expired']) {
        $detail .= '<tr><td colspan="2" class="alert alert-warning">';
        if ($_SESSION['m_is_expired']) {
            $detail .= '<div style="color: #f00;">' . __('Your Membership Already EXPIRED! Please extend your membership.') . '</div>';
        }
        if ($_SESSION['m_membership_pending']) {
            $detail .= '<div style="color: #f00;">' . __('Membership currently in pending state, no loan transaction can be made yet.') . '</div>';
        }
        $detail .= '</td></tr>' . "\n";
    }
    $detail .= '<tr><td><strong>' . __('Member Name') . '</strong></td><td>' . $_SESSION['m_name'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Member ID') . '</strong></td><td>' . $_SESSION['mid'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Member Email') . '</strong></td><td>' . $_SESSION['m_email'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Member Type') . '</strong></td><td>' . $_SESSION['m_member_type'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Register Date') . '</strong></td><td>' . $_SESSION['m_register_date'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Expiry Date') . '</strong></td><td>' . $_SESSION['m_expire_date'] . '</td></tr>' . "\n";
    $detail .= '<tr><td><strong>' . __('Institution') . '</strong></td><td>' . $_SESSION['m_institution'] . '</td></tr>' . "\n";
    $detail .= '</table>' . "\n";
    return $detail;
}

// ============================================================
// 6. CHANGE PASSWORD FORM
// ============================================================
function changePassword()
{
    global $sysconf;
    
    $form = '<form id="memberChangePassword" method="post" action="' . $_SERVER['REQUEST_URI'] . '">' . "\n";
    $form .= '<table class="table table-striped">' . "\n";
    $form .= '<tr><td><strong>' . __('Current Password') . '</strong></td><td><input type="password" name="currPass" class="form-control" placeholder="Enter current password" /></td></tr>' . "\n";
    $form .= '<tr><td><strong>' . __('New Password') . '</strong></td><td><input type="password" name="newPass" class="form-control" placeholder="Enter new password" /></td></tr>' . "\n";
    $form .= '<tr><td><strong>' . __('Confirm Password') . '</strong></td><td><input type="password" name="newPass2" class="form-control" placeholder="Confirm new password" /></td></tr>' . "\n";
    $form .= '<tr><td colspan="2"><input class="btn btn-primary" type="submit" name="changePass" value="' . __('Change Password') . '" /></td></tr>' . "\n";
    $form .= '</table>' . "\n";
    $form .= '</form>' . "\n";
    return $form;
}

// ============================================================
// 7. OVERDUE CALLBACK
// ============================================================
function showOverdue($obj_db, $array_data)
{
    $_curr_date = date('Y-m-d');
    if (simbio_date::compareDates($array_data[3], $_curr_date) == $_curr_date) {
        return '<strong style="color: #f00;">' . $array_data[3] . ' ' . __('OVERDUED') . '</strong>';
    } else {
        return $array_data[3];
    }
}

// ============================================================
// 8. BOOKMARK CALLBACKS
// ============================================================
function showDetailDate($obj_db, $data)
{
    global $sysconf;
    if (isset($_COOKIE['select_lang'])) $sysconf['default_lang'] = trim(strip_tags($_COOKIE['select_lang']));
    return \Carbon\Carbon::parse($data[1])->locale($sysconf['default_lang'])->isoFormat('dddd, LL');
}

function showBookCover($obj_db, $data)
{
    $author = $obj_db->query('select ma.author_name from biblio_author as ba 
        inner join mst_author as ma on ba.author_id = ma.author_id where ba.biblio_id = ' . $obj_db->escape_string($data[2]));
    $list = [];
    if ($author->num_rows > 0) {
        while ($result = $author->fetch_row()) {
            $list[] = $result[0];
        }
    }
    return '<strong><a title="'.__('Click to view detail').'" href="'.SWB.'index.php?p=show_detail&id=' . $data[2] . '">'.$data[0].'</a></strong>
            <br>
            <div class="d-flex flex-row"><span class="text-muted text-sm">'.implode('</span>,<span class="text-muted text-sm">', $list).'</span></div>';
}

function showMarkDetail($obj_db, $data)
{
    return '<button class="btn btn-danger btn-sm deleteBookmark" data-id="' . $data[2] . '"><i class="fa fa-trash"></i></button>';
}

// ============================================================
// 9. PROCESS CHANGE PASSWORD
// ============================================================
function procChangePassword($str_curr_pass, $str_new_pass, $str_conf_new_pass)
{
    global $dbs, $sysconf, $_SESSION;
    
    if ($sysconf['password_policy_strong'] && ($str_new_pass AND $str_conf_new_pass) 
        && ($str_new_pass === $str_conf_new_pass) 
        && !simbio_security::validatePassword($str_conf_new_pass, $sysconf['password_policy_min_length'])) {
        return CANT_UPDATE_PASSWD;
    }
    
    $_str_pass_sql = sprintf('SELECT mpasswd FROM member WHERE member_id=\'%s\'', $dbs->escape_string(trim($_SESSION['mid'])));
    $_str_pass_q = $dbs->query($_str_pass_sql);
    $_str_pass_d = $_str_pass_q->fetch_row();
    $verified = password_verify($str_curr_pass, $_str_pass_d[0]);
    
    if ($verified) {
        $str_new_pass = trim($str_new_pass);
        $str_conf_new_pass = trim($str_conf_new_pass);
        if ($str_new_pass && $str_conf_new_pass && ($str_new_pass === $str_conf_new_pass)) {
            $_new_password = password_hash($str_conf_new_pass, PASSWORD_BCRYPT);
            $_sql_update_mpasswd = sprintf('UPDATE member SET mpasswd=\'%s\' WHERE member_id=\'%s\'', 
                $dbs->escape_string($_new_password), $dbs->escape_string(trim($_SESSION['mid'])));
            @$dbs->query($_sql_update_mpasswd);
            if (!$dbs->error) {
                return true;
            } else {
                return CANT_UPDATE_PASSWD;
            }
        } else {
            return PASSWD_NOT_MATCH;
        }
    } else {
        return CURR_PASSWD_WRONG;
    }
}

// ============================================================
// 10. BASKET AJAX HANDLER (UNTUK BOOKMARK)
// ============================================================
function handleBookmarkAjax()
{
    global $dbs, $_SESSION;
    
    if (isset($_POST['bookmark_id'])) {
        try {
            if (isset($_POST['delete_bookmark'])) {
                $dbs->prepare('DELETE FROM `biblio_mark` WHERE `biblio_id` = ? AND `member_id` = ?')
                    ->execute([$_POST['bookmark_id'], $_SESSION['mid']]);
                unset($_SESSION['bookmark'][$_POST['bookmark_id']]);
                exit(json_encode(['status' => true, 'message' => __('Data has been deleted')]));
            }
            
            $dbs->prepare('INSERT IGNORE INTO `biblio_mark` SET `biblio_id` = ?, `member_id` = ?, `id` = ?')
                ->execute([$_POST['bookmark_id'], $_SESSION['mid'], md5($_POST['bookmark_id'] . $_SESSION['mid'])]);
            $_SESSION['bookmark'][$_POST['bookmark_id']] = $_POST['bookmark_id'];
            exit(json_encode(['status' => true, 'message' => __('Data has been saved'), 'label' => __('Bookmarked')]));
        } catch (Exception $e) {
            exit(json_encode(['status' => false, 'message' => isDev() ? $e->getMessage() : __('Data failed saved')]));
        }
    }
}

// ============================================================
// 11. BASKET CLEAR / REMOVE HANDLER
// ============================================================
function handleBasketActions()
{
    global $_SESSION;
    
    if (isset($_POST['clear_biblio'])) {
        $_SESSION['m_mark_biblio'] = array();
        header('Location: ' . $_SERVER['REQUEST_URI']);
        exit;
    }
    
    if (isset($_POST['basketRemove']) && isset($_POST['basket']) && count($_POST['basket']) > 0) {
        foreach ($_POST['basket'] as $basket_item) {
            unset($_SESSION['m_mark_biblio'][$basket_item]);
        }
        header('Location: ' . $_SERVER['REQUEST_URI']);
        exit;
    }
}