<?php
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/_costing_engine.php';

$user = requireAuth();
$db = getDB();
$p = getPagination();

$search = post('search', '');
$status = post('status', '');
$type = post('type', '');
$internal = post('internal', '');
$myOnly = post('my_only', '');
$where = ['1=1'];
$params = [];

if ($search) {
    $where[] = '(jc.title LIKE ? OR jc.job_number LIKE ? OR jc.site_name LIKE ? OR c.company_name LIKE ?)';
    $params = array_merge($params, ["%$search%", "%$search%", "%$search%", "%$search%"]);
}

// Handle meta-status filters
if ($status === 'active') {
    $where[] = "jc.status IN ('travelling','on_site','working')";
} elseif ($status === 'pending') {
    $where[] = "jc.status IN ('draft','assigned')";
} elseif ($status) {
    $where[] = 'jc.status = ?';
    $params[] = $status;
}

// For techs (role 4) on job cards page: never show completed/invoiced/internal_complete/cancelled
// In bookout/return context: exclude draft, invoiced, no_charge for ALL users
$context = post('context', '');
if ($context === 'bookout') {
    $where[] = "jc.status NOT IN ('draft','invoiced','no_charge','cancelled')";
} elseif ($user['role_id'] == 4) {
    $where[] = "jc.status NOT IN ('completed','invoiced','internal_complete','no_charge','cancelled')";
}

if ($type) {
    $where[] = 'jc.job_type = ?';
    $params[] = $type;
}

if ($internal !== '') {
    $where[] = 'jc.is_internal = ?';
    $params[] = (int) $internal;
}

$dateFrom = post('date_from', '');
$dateTo = post('date_to', '');
if ($dateFrom) {
    $where[] = 'DATE(jc.scheduled_date) >= ?';
    $params[] = $dateFrom;
}
if ($dateTo) {
    $where[] = 'DATE(jc.scheduled_date) <= ?';
    $params[] = $dateTo;
}

// Exclude specific statuses (used by stock bookout to hide invoiced)
$excludeStatus = post('exclude_status', '');
if ($excludeStatus) {
    $excluded = array_map('trim', explode(',', $excludeStatus));
    $placeholders = implode(',', array_fill(0, count($excluded), '?'));
    $where[] = "jc.status NOT IN ($placeholders)";
    $params = array_merge($params, $excluded);
}

// Enforce own-jobs restriction server-side
// A user is restricted to their own jobs if view_own permission is explicitly set to 1
$forceMyOnly = false;
if ($context !== 'bookout' && (int)$user['role_id'] !== 1) {
    try {
        $permStmt = $db->prepare("
            SELECT
                MAX(CASE WHEN action='view_own' THEN allowed ELSE 0 END) AS can_view_own
            FROM role_permissions
            WHERE role_id = ? AND module = 'jobcards'
        ");
        $permStmt->execute([$user['role_id']]);
        $row = $permStmt->fetch();

        if ($row && (int)$row['can_view_own'] === 1) {
            // view_own is ticked — always restrict to own jobs
            $forceMyOnly = true;
        } elseif (!$row || (int)$row['can_view_own'] === 0) {
            // No permissions or view_own off — use role 4 legacy fallback
            if ((int)$user['role_id'] === 4) $forceMyOnly = true;
        }
    } catch (Exception $e) {
        if ((int)$user['role_id'] === 4) $forceMyOnly = true;
    }
}

if ($context !== 'bookout' && ($myOnly || $forceMyOnly)) {
    $where[] = '(jc.assigned_to = ? OR EXISTS (SELECT 1 FROM job_card_technicians jct WHERE jct.job_card_id = jc.id AND jct.user_id = ?))';
    $params[] = $user['id'];
    $params[] = $user['id'];
}

$whereStr = implode(' AND ', $where);

$countStmt = $db->prepare("SELECT COUNT(*) FROM job_cards jc LEFT JOIN clients c ON c.id = jc.client_id WHERE $whereStr");
$countStmt->execute($params);
$total = (int) $countStmt->fetchColumn();

$stmt = $db->prepare("
    SELECT jc.*, c.company_name AS client_name, u.full_name AS assigned_name
    FROM job_cards jc
    LEFT JOIN clients c ON c.id = jc.client_id
    LEFT JOIN users u   ON u.id = jc.assigned_to
    WHERE $whereStr
    ORDER BY
      FIELD(jc.status,'working','on_site','travelling','assigned','draft','completed','internal_complete','invoiced','cancelled'),
      jc.scheduled_date ASC, jc.created_at DESC
    LIMIT {$p['limit']} OFFSET {$p['offset']}
");
$stmt->execute($params);
$rows = $stmt->fetchAll();

// ── Enrich with exact costing (same logic as costing tab) ───
// Only calculate for admin users — tech list doesn't need costs
$isAdmin = in_array((int) $user['role_id'], [1, 2, 5]);
if ($isAdmin) {
    $defaultDays = 21.67;
    $defaultHours = 8;
    try {
        foreach ($db->query("SELECT setting_key, setting_value FROM settings WHERE setting_group IN ('hr','finance')")->fetchAll() as $s) {
            if ($s['setting_key'] === 'working_days_per_month')
                $defaultDays = (float) $s['setting_value'];
            if ($s['setting_key'] === 'working_hours_per_day')
                $defaultHours = (float) $s['setting_value'];
        }
    } catch (Exception $ignored) {
    }

    foreach ($rows as &$row) {
        $costs = calcJobCostSummary($db, (int) $row['id'], $defaultDays, $defaultHours);
        $row['labour_cost'] = $costs['labour_cost'];
        $row['travel_cost'] = $costs['travel_cost'];
        $row['stock_cost'] = $costs['consumables_cost'];
        $row['slips_cost'] = $costs['slips_total'];
        $row['estimated_cost'] = $costs['total_cost'];
        $row['net_profit'] = $costs['net_profit'];
    }
    unset($row);
}

apiSuccess([
    'job_cards' => $rows,
    'pagination' => ['total' => $total, 'page' => $p['page'], 'limit' => $p['limit'], 'pages' => ceil($total / $p['limit'])]
]);