<?php
function stock_role()
{
    $role = $_SESSION['role'] ?? '';
    if ($role === '' && !empty($_SESSION['admintype'])) {
        $role = $_SESSION['admintype'];
    }
    return $role;
}

function stock_is_admin()
{
    return in_array(stock_role(), array('super_admin', 'ge_admin'), true) || ($_SESSION['admintype'] ?? '') === 'admin';
}

function stock_is_bso()
{
    return stock_role() === 'bso';
}

function stock_is_department()
{
    return stock_role() === 'department_admin';
}

function stock_is_contractor()
{
    return stock_role() === 'contractor';
}

function stock_can_view()
{
    return stock_is_admin() || stock_is_bso() || stock_is_department() || stock_is_contractor();
}

function stock_ensure_consumption_schema($conn)
{
    $conn->query("
        ALTER TABLE stock_transactions
        MODIFY from_holder_type ENUM('external','bso','department','contractor','br','em','consumed') NOT NULL
    ");
    $conn->query("
        ALTER TABLE stock_transactions
        MODIFY to_holder_type ENUM('external','bso','department','contractor','br','em','consumed') NOT NULL
    ");
}

function stock_material_table()
{
    return 'matrial';
}

function stock_material_select_sql($where = '')
{
    $whereSql = trim($where);
    if ($whereSql !== '') {
        $whereSql = ' WHERE '.$whereSql;
    }

    return "
        SELECT
            m_id AS id,
            material_name,
            serial_number AS material_code,
            s_code,
            m_unit AS unit
        FROM ".stock_material_table()."
        $whereSql
        ORDER BY material_name ASC
    ";
}

function stock_material_label($material, $includeUnit = true)
{
    $label = $material['material_name'] ?? '';
    $codeParts = array();

    if (!empty($material['material_code'])) {
        $codeParts[] = $material['material_code'];
    }
    if (!empty($material['s_code'])) {
        $codeParts[] = 'S.Code '.$material['s_code'];
    }

    if (!empty($codeParts)) {
        $label .= ' - '.implode(' / ', $codeParts);
    }

    if ($includeUnit && !empty($material['unit'])) {
        $label .= ' ('.$material['unit'].')';
    }

    return $label;
}

function stock_holder_options($conn, $holder_type)
{
    if ($holder_type === 'bso') {
        return $conn->query("SELECT id, name FROM admin WHERE (role='bso' OR type='bso') AND status='1' ".stock_admin_holder_scope_sql('AND', false)." ORDER BY name ASC");
    }

    if ($holder_type === 'department') {
        return $conn->query("SELECT id, name FROM departments WHERE status='1' ".stock_department_scope_sql('AND')." ORDER BY name ASC");
    }

    if ($holder_type === 'contractor') {
        return $conn->query("SELECT id, name FROM admin WHERE (role='contractor' OR type='contractor') AND status='1' ".stock_admin_holder_scope_sql('AND', true)." ORDER BY name ASC");
    }

    return false;
}

function stock_admin_holder_scope_sql($prefix = 'AND', $includeDepartment = false)
{
    if (stock_is_admin() && stock_role() !== 'ge_admin') {
        return '';
    }

    $division_id = (int)($_SESSION['division_id'] ?? 0);
    $department_id = (int)($_SESSION['department_id'] ?? 0);
    $clauses = array();

    if ($division_id > 0) {
        $clauses[] = "division_id='$division_id'";
    }

    if ($includeDepartment && (stock_is_department() || stock_is_contractor()) && $department_id > 0) {
        $clauses[] = "department_id='$department_id'";
    }

    if (empty($clauses)) {
        return '';
    }

    return ' '.$prefix.' '.implode(' AND ', $clauses).' ';
}

function stock_department_scope_sql($prefix = 'AND')
{
    if (stock_is_admin() && stock_role() !== 'ge_admin') {
        return '';
    }

    $division_id = (int)($_SESSION['division_id'] ?? 0);
    $department_id = (int)($_SESSION['department_id'] ?? 0);
    $clauses = array();

    if (stock_is_department() || stock_is_contractor()) {
        if ($department_id > 0) {
            $clauses[] = "id='$department_id'";
        }
    } elseif ($division_id > 0) {
        $clauses[] = "division_id='$division_id'";
    }

    if (empty($clauses)) {
        return '';
    }

    return ' '.$prefix.' '.implode(' AND ', $clauses).' ';
}

function stock_department_allowed($conn, $department_id)
{
    $department_id = (int)$department_id;
    if ($department_id <= 0) {
        return false;
    }

    $scopeSql = stock_department_scope_sql('AND');
    $q = $conn->query("SELECT id FROM departments WHERE id='$department_id' AND status='1' $scopeSql LIMIT 1");
    return $q && $q->num_rows > 0;
}

function stock_holder_allowed($conn, $holder_type, $holder_id)
{
    $holder_id = (int)$holder_id;
    if ($holder_id <= 0) {
        return false;
    }

    if ($holder_type === 'department') {
        return stock_department_allowed($conn, $holder_id);
    }

    if ($holder_type === 'bso') {
        $scopeSql = stock_admin_holder_scope_sql('AND', false);
        if ((stock_is_department() || stock_is_contractor()) && !empty($_SESSION['division_id'])) {
            $division_id = (int)$_SESSION['division_id'];
            $scopeSql = " AND (division_id='$division_id' OR division_id IS NULL OR division_id='0') ";
        }
        $q = $conn->query("SELECT id FROM admin WHERE id='$holder_id' AND (role='bso' OR type='bso') AND status='1' $scopeSql LIMIT 1");
        return $q && $q->num_rows > 0;
    }

    if ($holder_type === 'contractor') {
        $scopeSql = stock_admin_holder_scope_sql('AND', true);
        $joinSql = '';
        if (stock_is_department()) {
            $department_id = (int)($_SESSION['department_id'] ?? 0);
            $division_id = (int)($_SESSION['division_id'] ?? 0);
            $joinSql = " LEFT JOIN departments dep ON dep.id = a.department_id ";
            $scopeSql = " AND (a.department_id='$department_id'";
            if ($division_id > 0) {
                $scopeSql .= " OR a.division_id='$division_id' OR dep.division_id='$division_id'";
            }
            $scopeSql .= ") ";
        }
        $q = $conn->query("SELECT a.id FROM admin a $joinSql WHERE a.id='$holder_id' AND (a.role='contractor' OR a.type='contractor') AND a.status='1' $scopeSql LIMIT 1");
        return $q && $q->num_rows > 0;
    }

    return false;
}

function stock_holder_label($conn, $holder_type, $holder_id)
{
    $holder_id = (int)$holder_id;

    if ($holder_type === 'bso') {
        if ($holder_id > 0) {
            $q = $conn->query("SELECT name FROM admin WHERE id='$holder_id' AND (role='bso' OR type='bso') LIMIT 1");
            if ($q && $q->num_rows > 0) {
                return 'BSO - '.$q->fetch_assoc()['name'];
            }
        }
        return 'BSO';
    }

    if ($holder_type === 'department') {
        $q = $conn->query("SELECT name FROM departments WHERE id='$holder_id' LIMIT 1");
        if ($q && $q->num_rows > 0) {
            return 'Department - '.$q->fetch_assoc()['name'];
        }
        return 'Department';
    }

    if ($holder_type === 'contractor') {
        $q = $conn->query("SELECT name FROM admin WHERE id='$holder_id' AND (role='contractor' OR type='contractor') LIMIT 1");
        if ($q && $q->num_rows > 0) {
            return 'Contractor - '.$q->fetch_assoc()['name'];
        }
        return 'Contractor';
    }

    if ($holder_type === 'br') {
        return 'B/R Stock';
    }

    if ($holder_type === 'em') {
        return 'E/M Stock';
    }

    if ($holder_type === 'consumed') {
        if ($holder_id > 0) {
            $q = $conn->query("SELECT docketNumber FROM users_complaint WHERE ucid='$holder_id' LIMIT 1");
            if ($q && $q->num_rows > 0) {
                $row = $q->fetch_assoc();
                return 'Consumed / Used - Complaint #'.($row['docketNumber'] ?: $holder_id);
            }
            return 'Consumed / Used - Complaint #'.$holder_id;
        }
        return 'Consumed / Used';
    }

    if ($holder_type === 'external') {
        return 'External';
    }

    return '-';
}

function stock_balance($conn, $material_id, $holder_type, $holder_id)
{
    $material_id = (int)$material_id;
    $holder_id = (int)$holder_id;
    $holder_type = mysqli_real_escape_string($conn, $holder_type);

    $in = 0;
    $out = 0;

    $inq = $conn->query("
        SELECT COALESCE(SUM(quantity), 0) AS qty
        FROM stock_transactions
        WHERE material_id='$material_id'
        AND to_holder_type='$holder_type'
        AND to_holder_id='$holder_id'
    ");
    if ($inq) {
        $in = (float)$inq->fetch_assoc()['qty'];
    }

    $outq = $conn->query("
        SELECT COALESCE(SUM(quantity), 0) AS qty
        FROM stock_transactions
        WHERE material_id='$material_id'
        AND from_holder_type='$holder_type'
        AND from_holder_id='$holder_id'
    ");
    if ($outq) {
        $out = (float)$outq->fetch_assoc()['qty'];
    }

    return $in - $out;
}

function stock_redirect($message, $url)
{
    echo '<script>alert("'.addslashes($message).'");window.location.href="'.$url.'";</script>';
    exit;
}

function stock_complaint_category_holder($conn, $ucid)
{
    $ucid = (int)$ucid;
    $q = $conn->query("
        SELECT cl.complaint_type, uc.subdivision
        FROM users_complaint uc
        LEFT JOIN complaint_list cl ON cl.cid = uc.c_list
        WHERE uc.ucid='$ucid'
        LIMIT 1
    ");

    if ($q && $q->num_rows > 0) {
        $row = $q->fetch_assoc();
        if ($row['complaint_type'] === 'EM' || (int)$row['subdivision'] === 1) {
            return 'em';
        }
    }

    return 'br';
}

function stock_complaint_source_holder($conn, $complaint)
{
    if (stock_is_contractor()) {
        return ['contractor', (int)$_SESSION['admin']];
    }

    if (stock_is_department()) {
        return ['department', (int)$_SESSION['department_id']];
    }

    if (stock_is_bso()) {
        return ['bso', (int)$_SESSION['admin']];
    }

    if (!empty($complaint['department'])) {
        $departmentAdminId = (int)$complaint['department'];
        $adminQ = $conn->query("SELECT department_id FROM admin WHERE id='$departmentAdminId' LIMIT 1");
        if ($adminQ && $adminQ->num_rows > 0) {
            $admin = $adminQ->fetch_assoc();
            if (!empty($admin['department_id'])) {
                return ['department', (int)$admin['department_id']];
            }
        }

        return ['department', $departmentAdminId];
    }

    return ['', 0];
}

function stock_insert_transaction($conn, $material_id, $quantity, $transaction_type, $from_type, $from_id, $to_type, $to_id, $reference_no, $remarks, $created_by)
{
    $material_id = (int)$material_id;
    $quantity = (float)$quantity;
    $from_id = (int)$from_id;
    $to_id = (int)$to_id;
    $created_by = (int)$created_by;
    $transaction_type = mysqli_real_escape_string($conn, $transaction_type);
    $from_type = mysqli_real_escape_string($conn, $from_type);
    $to_type = mysqli_real_escape_string($conn, $to_type);
    $reference_no = mysqli_real_escape_string($conn, $reference_no);
    $remarks = mysqli_real_escape_string($conn, $remarks);

    return $conn->query("
        INSERT INTO stock_transactions
        (material_id, quantity, transaction_type, from_holder_type, from_holder_id, to_holder_type, to_holder_id, reference_no, remarks, created_by)
        VALUES
        ('$material_id', '$quantity', '$transaction_type', '$from_type', '$from_id', '$to_type', '$to_id', '$reference_no', '$remarks', '$created_by')
    ");
}

function stock_record_complaint_material_usage($conn, $ucid, $materialRows, $created_by)
{
    stock_ensure_consumption_schema($conn);

    $ucid = (int)$ucid;
    $created_by = (int)$created_by;
    $reference = 'COMPLAINT-'.$ucid;

    $complaintQ = $conn->query("SELECT * FROM users_complaint WHERE ucid='$ucid' LIMIT 1");
    if (!$complaintQ || $complaintQ->num_rows == 0) {
        return 'Complaint not found.';
    }

    $complaint = $complaintQ->fetch_assoc();
    list($sourceType, $sourceId) = stock_complaint_source_holder($conn, $complaint);
    $categoryType = stock_complaint_category_holder($conn, $ucid);

    $conn->query("DELETE FROM stock_transactions WHERE reference_no='$reference'");

    foreach ($materialRows as $row) {
        $material_id = (int)$row['material_id'];
        $qty = (float)$row['qty'];
        if ($material_id <= 0 || $qty <= 0) {
            continue;
        }

        if ($sourceType !== '' && $sourceId > 0) {
            stock_insert_transaction(
                $conn,
                $material_id,
                $qty,
                'issue',
                $sourceType,
                $sourceId,
                'consumed',
                $ucid,
                $reference,
                'Material used in complaint #'.$ucid,
                $created_by
            );
        }

        stock_insert_transaction(
            $conn,
            $material_id,
            $qty,
            'issue',
            $categoryType,
            0,
            'consumed',
            $ucid,
            $reference,
            strtoupper($categoryType).' complaint category material used #'.$ucid,
            $created_by
        );
    }

    return '';
}
?>
