<?php

//the global file operation
include("../public/impOpreation.php");

//get the do the action
$do = $_GET['do'];

$langs = $_SESSION['erp_lang'];
include_once("../views/languages/$langs/success.php");
include_once("../views/languages/$langs/error.php");

$userID = $_SESSION['userid'];
$today = date("Y-m-d H:i:s");

// AJAX actions that skip header/footer
$ajaxActions = array('getChildren', 'searchAccounts', 'getNextCode', 'searchMembers', 'checkMemberLinked');

if (!in_array($do, $ajaxActions)) {
    $smarty->display("header.html");
}

$smarty->assign("accCommon", 1);
$smarty->assign("accAccount", 1);

// Helper: build nested tree from flat array
function buildAccountTree($flatAccounts, $parentId = 0) {
    $tree = array();
    foreach ($flatAccounts as $account) {
        if ((int)$account['parent_id'] == $parentId) {
            $account['children'] = buildAccountTree($flatAccounts, (int)$account['id']);
            $tree[] = $account;
        }
    }
    return $tree;
}

// Helper: render tree HTML recursively
function renderTreeHTML($nodes) {
    $html = '';
    foreach ($nodes as $node) {
        $hasChildren = !empty($node['children']);
        $level = (int)$node['level'];
        $id = (int)$node['id'];
        $code = htmlspecialchars($node['code']);
        $name = htmlspecialchars($node['name']);
        $type = htmlspecialchars($node['account_type']);

        $html .= '<div class="acc-tree-node ' . ($hasChildren ? 'has-children' : '') . '" data-id="' . $id . '" data-level="' . $level . '">';
        $html .= '<div class="acc-tree-row">';

        // Toggle
        if ($hasChildren) {
            $html .= '<span class="acc-tree-toggle collapsed"><span class="glyphicon glyphicon-triangle-right"></span></span>';
        } else {
            $html .= '<span class="acc-tree-toggle leaf"><span class="glyphicon glyphicon-record" style="font-size:6px;color:#bbb;"></span></span>';
        }

        // Icon
        if ($hasChildren) {
            $html .= '<span class="acc-tree-icon"><span class="glyphicon glyphicon-folder-close text-warning" style="font-size:18px;"></span></span>';
        } else {
            $html .= '<span class="acc-tree-icon"><span class="glyphicon glyphicon-file text-info" style="font-size:16px;"></span></span>';
        }

        $html .= '<span class="acc-tree-code">' . $code . '</span>';
        $html .= '<span class="acc-tree-name">' . $name . '</span>';

        if ($type) {
            $html .= '<span class="acc-tree-type">' . $type . '</span>';
        }

        $html .= '<span class="acc-tree-actions noprint">';
        $html .= '<a href="accAccountController.php?do=edit&id=' . $id . '" class="acc-btn-edit" title="تعديل"><span class="glyphicon glyphicon-pencil"></span></a>';
        if (!$hasChildren) {
            $html .= '<a href="accAccountController.php?do=delete&id=' . $id . '" class="acc-btn-delete" title="حذف" onclick="return confirm(\'هل أنت متأكد من حذف هذا الحساب؟\');"><span class="glyphicon glyphicon-trash"></span></a>';
        }
        $html .= '<a href="accAccountController.php?do=add&parent_id=' . $id . '" class="acc-btn-add" title="إضافة حساب فرعي"><span class="glyphicon glyphicon-plus"></span></a>';
        $html .= '</span>';
        $html .= '</div>'; // end acc-tree-row

        if ($hasChildren) {
            $html .= '<div class="acc-tree-children" style="display:none;">';
            $html .= renderTreeHTML($node['children']);
            $html .= '</div>';
        }

        $html .= '</div>'; // end acc-tree-node
    }
    return $html;
}

//check and use the condition that suits this action
if (empty($do)) {
    header("location:accAccountController.php?do=show");
}

elseif ($do == "show") {
    $flat = R::getAll("SELECT * FROM acc_account WHERE del = 0 ORDER BY code ASC");
    $accounts = buildAccountTree($flat, 0);
    $treeHTML = renderTreeHTML($accounts);
    $smarty->assign("treeHTML", $treeHTML);
    $smarty->assign("accountCount", count($flat));
    $smarty->display("accAccountview/tree.html");
}

elseif ($do == "add") {
    // Load all non-leaf accounts as potential parents, plus include any account that currently has no children (they'll become parents)
    $parentAccounts = R::getAll("SELECT * FROM acc_account WHERE del = 0 ORDER BY code ASC");
    $smarty->assign("parentAccounts", $parentAccounts);

    // Pre-select parent if passed via URL
    $preParent = isset($_GET['parent_id']) ? (int)$_GET['parent_id'] : 0;
    $smarty->assign("preParent", $preParent);

    // Auto-generate next code based on parent
    $nextCode = '';
    $parentData = null;
    if ($preParent > 0) {
        $parentData = R::getRow("SELECT * FROM acc_account WHERE id = ? AND del = 0", [$preParent]);
        if (!empty($parentData)) {
            // Find the last child code under this parent
            $lastChild = R::getRow("SELECT code FROM acc_account WHERE parent_id = ? AND del = 0 ORDER BY code DESC LIMIT 1", [$preParent]);
            if (!empty($lastChild)) {
                // Increment last child code by 1
                $nextCode = (string)((int)$lastChild['code'] + 1);
            } else {
                // First child: parent code + "1"
                $nextCode = $parentData['code'] . '1';
            }
        }
    }
    $smarty->assign("nextCode", $nextCode);
    $smarty->assign("parentData", $parentData);

    $smarty->display("accAccountview/add.html");
}

elseif ($do == "savedata") {
    try {
        $code = isset($_POST['code']) ? trim($_POST['code']) : '';
        $name = isset($_POST['name']) ? trim($_POST['name']) : '';
        $parent_id = isset($_POST['parent_id']) ? (int)$_POST['parent_id'] : 0;
        $account_nature = isset($_POST['account_nature']) ? trim($_POST['account_nature']) : '';
        $account_type = isset($_POST['account_type']) ? trim($_POST['account_type']) : '';
        $is_leaf = isset($_POST['is_leaf']) ? 1 : 0;
        $member_id = isset($_POST['member_id']) && $_POST['member_id'] != '' ? (int)$_POST['member_id'] : null;

        // Check member not already linked to another active account
        /*if ($member_id) {
            $existing = R::getRow("SELECT id FROM acc_account WHERE member_id = ? AND del = 0", [$member_id]);
            if (!empty($existing)) {
                header("location:accAccountController.php?do=error");
                exit;
            }
        }*/

        // Calculate level from parent
        $level = 1;
        if ($parent_id > 0) {
            $parent = R::getRow("SELECT * FROM acc_account WHERE id = ? AND del = 0", [$parent_id]);
            if (!empty($parent)) {
                $level = (int)$parent['level'] + 1;
                // Update parent's is_leaf to 0 since it now has children
                R::exec("UPDATE acc_account SET is_leaf = 0 WHERE id = ?", [$parent_id]);
            }
        }

        R::exec("INSERT INTO acc_account (code, name, parent_id, account_nature, account_type, level, is_leaf, balance, member_id, userid, created_at, del) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, 0)",
            [$code, $name, $parent_id, $account_nature, $account_type, $level, $is_leaf, $member_id, $userID, $today]);

        header("location:accAccountController.php?do=show");
    } catch (Exception $e) {
        header("location:accAccountController.php?do=error");
    }
}

elseif ($do == "edit") {
    $id = (int)$_GET['id'];
    $account = R::getRow("SELECT * FROM acc_account WHERE id = ? AND del = 0", [$id]);
    $parentAccounts = R::getAll("SELECT * FROM acc_account WHERE is_leaf = 0 AND del = 0 AND id != ? ORDER BY code ASC", [$id]);

    // Load linked member info
    $linkedMember = null;
    if (!empty($account['member_id'])) {
        $linkedMember = R::getRow("SELECT id, member_name, phone FROM memberships WHERE id = ?", [$account['member_id']]);
    }

    $smarty->assign("account", $account);
    $smarty->assign("parentAccounts", $parentAccounts);
    $smarty->assign("linkedMember", $linkedMember);
    $smarty->display("accAccountview/edit.html");
}

elseif ($do == "update") {
    try {
        $id = (int)$_POST['id'];
        $code = isset($_POST['code']) ? trim($_POST['code']) : '';
        $name = isset($_POST['name']) ? trim($_POST['name']) : '';
        $parent_id = isset($_POST['parent_id']) ? (int)$_POST['parent_id'] : 0;
        $account_nature = isset($_POST['account_nature']) ? trim($_POST['account_nature']) : '';
        $account_type = isset($_POST['account_type']) ? trim($_POST['account_type']) : '';
        $is_leaf = isset($_POST['is_leaf']) ? 1 : 0;
        $member_id = isset($_POST['member_id']) && $_POST['member_id'] != '' ? (int)$_POST['member_id'] : null;

        // Check member not already linked to another active account (excluding current)
        if ($member_id) {
            $existing = R::getRow("SELECT id FROM acc_account WHERE member_id = ? AND del = 0 AND id != ?", [$member_id, $id]);
            if (!empty($existing)) {
                header("location:accAccountController.php?do=error");
                exit;
            }
        }

        // Calculate level from parent
        $level = 1;
        if ($parent_id > 0) {
            $parent = R::getRow("SELECT * FROM acc_account WHERE id = ? AND del = 0", [$parent_id]);
            if (!empty($parent)) {
                $level = (int)$parent['level'] + 1;
            }
        }

        R::exec("UPDATE acc_account SET code = ?, name = ?, parent_id = ?, account_nature = ?, account_type = ?, is_leaf = ?, level = ?, member_id = ?, userid = ?, created_at = ? WHERE id = ?",
            [$code, $name, $parent_id, $account_nature, $account_type, $is_leaf, $level, $member_id, $userID, $today, $id]);

        header("location:accAccountController.php?do=show");
    } catch (Exception $e) {
        header("location:accAccountController.php?do=error");
    }
}

elseif ($do == "delete") {
    try {
        $id = (int)$_GET['id'];

        // Check no journal lines reference this account
        $journalLineCount = R::getRow("SELECT COUNT(*) as cnt FROM acc_journal_entry_line WHERE account_id = ?", [$id]);
        if ($journalLineCount['cnt'] > 0) {
            header("location:accAccountController.php?do=error");
            exit;
        }

        // Check no children exist
        $childCount = R::getRow("SELECT COUNT(*) as cnt FROM acc_account WHERE parent_id = ? AND del = 0", [$id]);
        if ($childCount['cnt'] > 0) {
            header("location:accAccountController.php?do=error");
            exit;
        }

        // Soft delete
        R::exec("UPDATE acc_account SET del = 1, userid = ?, created_at = ? WHERE id = ?", [$userID, $today, $id]);

        header("location:accAccountController.php?do=show");
    } catch (Exception $e) {
        header("location:accAccountController.php?do=error");
    }
}

elseif ($do == "getChildren") {
    $parent_id = (int)$_GET['parent_id'];
    $children = R::getAll("SELECT * FROM acc_account WHERE parent_id = ? AND del = 0 ORDER BY code ASC", [$parent_id]);
    echo json_encode(array('status' => 1, 'data' => $children));
    exit;
}

elseif ($do == "getNextCode") {
    $parent_id = isset($_GET['parent_id']) ? (int)$_GET['parent_id'] : 0;
    $nextCode = '';
    if ($parent_id > 0) {
        $parent = R::getRow("SELECT code FROM acc_account WHERE id = ? AND del = 0", [$parent_id]);
        if (!empty($parent)) {
            $lastChild = R::getRow("SELECT code FROM acc_account WHERE parent_id = ? AND del = 0 ORDER BY code DESC LIMIT 1", [$parent_id]);
            if (!empty($lastChild)) {
                $nextCode = (string)((int)$lastChild['code'] + 1);
            } else {
                $nextCode = $parent['code'] . '1';
            }
        }
    }
    echo json_encode(array('status' => 1, 'code' => $nextCode));
    exit;
}

elseif ($do == "searchAccounts") {
    $term = isset($_GET['term']) ? trim($_GET['term']) : '';
    $accounts = R::getAll("SELECT id, code, name, CONCAT(code, ' - ', name) AS text FROM acc_account WHERE del = 0 AND (name LIKE ? OR code LIKE ?) ORDER BY code ASC LIMIT 30",
        ["%$term%", "%$term%"]);
    echo json_encode(array('results' => $accounts));
    exit;
}

elseif ($do == "searchMembers") {
    $term = isset($_GET['term']) ? trim($_GET['term']) : '';
    if ($term == '') {
        $members = R::getAll("SELECT id, member_name, phone FROM memberships WHERE (isdel = 0 OR isdel IS NULL) ORDER BY member_name ASC LIMIT 10");
    } else {
        $members = R::getAll("SELECT id, member_name, phone FROM memberships WHERE (isdel = 0 OR isdel IS NULL) AND (member_name LIKE ? OR phone LIKE ? OR id_num LIKE ?) ORDER BY member_name ASC LIMIT 20",
            ["%$term%", "%$term%", "%$term%"]);
    }
    $results = array();
    foreach ($members as $m) {
        $results[] = array('id' => $m['id'], 'text' => $m['member_name'] . ($m['phone'] ? ' - ' . $m['phone'] : ''));
    }
    echo json_encode(array('results' => $results));
    exit;
}

elseif ($do == "checkMemberLinked") {
    $member_id = isset($_GET['member_id']) ? (int)$_GET['member_id'] : 0;
    $exclude_account = isset($_GET['exclude_account']) ? (int)$_GET['exclude_account'] : 0;
    $where = "member_id = ? AND del = 0";
    $params = [$member_id];
    if ($exclude_account > 0) {
        $where .= " AND id != ?";
        $params[] = $exclude_account;
    }
    $existing = R::getRow("SELECT id, code, name FROM acc_account WHERE $where", $params);
    if (!empty($existing)) {
        echo json_encode(array('linked' => 1, 'account_code' => $existing['code'], 'account_name' => $existing['name']));
    } else {
        echo json_encode(array('linked' => 0));
    }
    exit;
}

elseif ($do == "sucess") {
    $smarty->display("succes.html");
}

elseif ($do == "error") {
    $smarty->display("error.html");
}

if (!in_array($do, $ajaxActions)) {
    $smarty->display("footer.html");
}
?>
