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

$user = requireAuth();
$db = getDB();
$id = (int) post('id', 0);
if (!$id)
    apiError('Job card ID required.', 422);

$stmt = $db->prepare("SELECT * FROM job_cards WHERE id = ?");
$stmt->execute([$id]);
$jc = $stmt->fetch();
if (!$jc)
    apiError('Job card not found.', 404);

$newStatus = post('status', $jc['status']);
$completedAt = ($newStatus === 'completed' && $jc['status'] !== 'completed')
    ? date('Y-m-d H:i:s')
    : ($jc['completed_at'] ?: null);

// For every field, only override if explicitly posted — otherwise keep existing DB value.
// This prevents a partial update (e.g. status-only) from nulling out vehicle_id, odo, etc.
$postStr = fn($key) => isset($_POST[$key]) ? post($key) : null;
$postInt = fn($key) => isset($_POST[$key]) && $_POST[$key] !== '' ? (int) post($key) : null;
$postFlt = fn($key) => isset($_POST[$key]) && $_POST[$key] !== '' ? (float) post($key) : null;

$vehicleId = isset($_POST['vehicle_id']) && $_POST['vehicle_id'] !== ''
    ? (int) post('vehicle_id')
    : $jc['vehicle_id'];

$odoStart = isset($_POST['odo_start']) && $_POST['odo_start'] !== ''
    ? (int) post('odo_start')
    : $jc['odo_start'];

$odoEnd = isset($_POST['odo_end']) && $_POST['odo_end'] !== ''
    ? (int) post('odo_end')
    : $jc['odo_end'];

$isInternal = isset($_POST['is_internal']) ? (post('is_internal') ? 1 : 0) : $jc['is_internal'];
$invoiceNo = isset($_POST['invoice_no']) ? (post('invoice_no') ?: null) : $jc['invoice_no'];
$invoiceAmount = isset($_POST['invoice_amount']) && $_POST['invoice_amount'] !== ''
    ? (float) post('invoice_amount')
    : $jc['invoice_amount'];

$db->prepare("
    UPDATE job_cards SET
        title              = ?,
        description        = ?,
        job_type           = ?,
        status             = ?,
        priority           = ?,
        site_name          = ?,
        site_address       = ?,
        scheduled_date     = ?,
        scheduled_time     = ?,
        assigned_to        = ?,
        completed_at       = ?,
        client_name_signed = ?,
        vehicle_id         = ?,
        odo_start          = ?,
        odo_end            = ?,
        is_internal        = ?,
        invoice_no         = ?,
        invoice_amount     = ?
    WHERE id = ?
")->execute([
            isset($_POST['title']) ? post('title') : $jc['title'],
            isset($_POST['description']) ? post('description') : $jc['description'],
            isset($_POST['job_type']) ? post('job_type') : $jc['job_type'],
            $newStatus,
            isset($_POST['priority']) ? post('priority') : $jc['priority'],
            isset($_POST['site_name']) ? post('site_name') : $jc['site_name'],
            isset($_POST['site_address']) ? post('site_address') : $jc['site_address'],
            isset($_POST['scheduled_date']) ? post('scheduled_date') : $jc['scheduled_date'],
            isset($_POST['scheduled_time']) ? post('scheduled_time') : $jc['scheduled_time'],
            isset($_POST['assigned_to']) ? post('assigned_to') : $jc['assigned_to'],
            $completedAt,
            isset($_POST['client_name_signed']) ? post('client_name_signed') : $jc['client_name_signed'],
            $vehicleId,
            $odoStart,
            $odoEnd,
            $isInternal,
            $invoiceNo,
            $invoiceAmount,
            $id,
        ]);

// Auto-log a timeline entry when status changes to a significant milestone
$loggableStatuses = ['completed', 'internal_complete', 'invoiced', 'cancelled'];
if ($newStatus !== $jc['status'] && in_array($newStatus, $loggableStatuses)) {
    // Only insert if this event type hasn't already been logged (avoid duplicates)
    $check = $db->prepare("SELECT id FROM job_card_time_logs WHERE job_card_id=? AND event_type=? LIMIT 1");
    $check->execute([$id, $newStatus]);
    if (!$check->fetch()) {
        $db->prepare("INSERT INTO job_card_time_logs (job_card_id, user_id, event_type, event_time) VALUES (?,?,?,NOW())")
            ->execute([$id, $user['id'], $newStatus]);
    }
}

// ── Email notifications on status change ─────────────────
if ($newStatus !== $jc['status']) {
    try {
        require_once __DIR__ . '/../config/mailer.php';
        require_once __DIR__ . '/../emails/templates.php';

        $cfg = getMailerConfig($db);
        $appUrl = $cfg['email_app_url'] ?? '';

        $companyStmt = $db->query("SELECT setting_value FROM settings WHERE setting_key='company_name' LIMIT 1");
        $companyName = $companyStmt ? ($companyStmt->fetchColumn() ?: 'Elegant Work') : 'Elegant Work';

        // Build full JC data
        $jcFull = $jc;
        $jcFull['_app_url'] = rtrim($appUrl, '/');

        // Client — fetch primary contact email from client_contacts
        if ($jc['client_id']) {
            $cs = $db->prepare("SELECT c.company_name, cc.email AS contact_email, cc.full_name AS contact_name
                FROM clients c
                LEFT JOIN client_contacts cc ON cc.client_id = c.id AND cc.is_primary = 1
                WHERE c.id = ? LIMIT 1");
            $cs->execute([$jc['client_id']]);
            $clientRow = $cs->fetch();
            $jcFull['client_name'] = $clientRow['company_name'] ?? null;
            $jcFull['client_email'] = $clientRow['contact_email'] ?? null;
            $jcFull['client_contact_name'] = $clientRow['contact_name'] ?? $clientRow['company_name'] ?? null;
        }

        // Current assigned tech (from DB — the tech who IS assigned right now)
        $techEmail = null;
        $techName = null;
        if ($jc['assigned_to']) {
            $ts = $db->prepare("SELECT email, full_name AS name FROM users WHERE id=? LIMIT 1");
            $ts->execute([$jc['assigned_to']]);
            $tr = $ts->fetch();
            $techEmail = $tr['email'] ?? null;
            $techName = $tr['name'] ?? null;
        }

        // New assigned tech (from POST — may differ from current)
        $newTechId = isset($_POST['assigned_to']) ? (int) post('assigned_to') : null;
        $newTechEmail = null;
        $newTechName = null;
        if ($newTechId && $newTechId !== (int) $jc['assigned_to']) {
            $nts = $db->prepare("SELECT email, full_name AS name FROM users WHERE id=? LIMIT 1");
            $nts->execute([$newTechId]);
            $ntr = $nts->fetch();
            $newTechEmail = $ntr['email'] ?? null;
            $newTechName = $ntr['name'] ?? null;
        }

        $changedByName = $user['full_name'];
        $adminEmail = getAdminEmail($db);

        // ── job_status_changed — admin + tech ───────────
        $rule = getNotifRule($db, 'job_status_changed');
        if ($rule && $rule['is_enabled']) {
            $subject = "🔄 Job Status Updated: {$jc['job_number']}";
            if ($rule['notify_admin'] && $adminEmail) {
                $html = tplJobStatusChanged($jcFull, 'Admin', $jc['status'], $newStatus, $changedByName, $appUrl);
                queueEmail($db, 'job_status_changed', $adminEmail, 'Admin', $subject, $html, 'job_card', $id);
            }
            if ($rule['notify_assigned_tech'] && $techEmail && $techEmail !== $adminEmail && $user['id'] != $jc['assigned_to']) {
                $html = tplJobStatusChanged($jcFull, $techName, $jc['status'], $newStatus, $changedByName, $appUrl);
                queueEmail($db, 'job_status_changed', $techEmail, $techName, $subject, $html, 'job_card', $id);
            }
        }

        // ── status → assigned: send client "Job Confirmed" ──
        if ($newStatus === 'assigned') {
            $rule = getNotifRule($db, 'job_assigned');
            if ($rule && $rule['is_enabled'] && $rule['notify_client'] && !empty($jcFull['client_email']) && !$jc['is_internal']) {
                // Get the assigned tech name to include in the email
                $jcFull['tech_name'] = $techName;
                $jcFull['assigned_name'] = $techName;
                $recipientName = $jcFull['client_contact_name'] ?? $jcFull['client_name'];
                $html = tplClientJobConfirmed($jcFull, $recipientName, $companyName);
                queueEmail(
                    $db,
                    'job_assigned',
                    $jcFull['client_email'],
                    $recipientName,
                    "Your Job is Confirmed — {$jcFull['title']}",
                    $html,
                    'job_card',
                    $id
                );
            }
        }

        // ── job_completed — admin + tech + client ────────
        if (in_array($newStatus, ['completed', 'internal_complete'])) {
            $rule = getNotifRule($db, 'job_completed');
            if ($rule && $rule['is_enabled']) {
                $subject = "✅ Job Completed: {$jc['job_number']}";
                if ($rule['notify_admin'] && $adminEmail) {
                    $html = tplJobCompleted($jcFull, 'Admin', false, $appUrl);
                    queueEmail($db, 'job_completed', $adminEmail, 'Admin', $subject, $html, 'job_card', $id);
                }
                if ($rule['notify_assigned_tech'] && $techEmail && $techEmail !== $adminEmail) {
                    $html = tplJobCompleted($jcFull, $techName, false, $appUrl);
                    queueEmail($db, 'job_completed', $techEmail, $techName, $subject, $html, 'job_card', $id);
                }
                if ($rule['notify_client'] && !empty($jcFull['client_email']) && !$jc['is_internal']) {
                    $recipientName = $jcFull['client_contact_name'] ?? $jcFull['client_name'];
                    $html = tplJobCompleted($jcFull, $recipientName, true, '');
                    queueEmail($db, 'job_completed', $jcFull['client_email'], $recipientName, $subject, $html, 'job_card', $id);
                }
            }
        }

        // ── job_invoiced / no_charge — admin + tech + client (with PDF) ──
        if (in_array($newStatus, ['invoiced', 'no_charge'])) {
            $rule = getNotifRule($db, 'job_invoiced');
            if ($rule && $rule['is_enabled']) {
                $jcFull['invoice_no'] = $invoiceNo;
                $jcFull['invoice_amount'] = $invoiceAmount;

                $isNoCharge = $newStatus === 'no_charge';
                $subject = $isNoCharge
                    ? "🆓 No Charge: {$jc['job_number']}"
                    : "🧾 Invoice: {$jc['job_number']}";

                // Generate PDFs
                require_once __DIR__ . '/_pdf_generator.php';
                $clientPdfPath = generateJobCardPdf($db, $id, 'client');
                $internalPdfPath = generateJobCardPdf($db, $id, 'internal');
                $pdfFileName = $jc['job_number'] . '_' . ($isNoCharge ? 'no_charge' : 'invoice') . '.pdf';

                // Admin — internal PDF
                if ($rule['notify_admin'] && $adminEmail) {
                    $html = tplJobInvoiced($jcFull, 'Admin', false, $appUrl);
                    queueEmail(
                        $db,
                        'job_invoiced',
                        $adminEmail,
                        'Admin',
                        $subject,
                        $html,
                        'job_card',
                        $id,
                        $internalPdfPath,
                        $pdfFileName
                    );
                }
                // Tech — internal PDF
                if ($rule['notify_assigned_tech'] && $techEmail && $techEmail !== $adminEmail) {
                    $html = tplJobInvoiced($jcFull, $techName, false, $appUrl);
                    queueEmail(
                        $db,
                        'job_invoiced',
                        $techEmail,
                        $techName,
                        $subject,
                        $html,
                        'job_card',
                        $id,
                        $internalPdfPath,
                        $pdfFileName
                    );
                }
                // Client — client PDF with tailored subject
                if ($rule['notify_client'] && !empty($jcFull['client_email']) && !$jc['is_internal']) {
                    $recipientName = $jcFull['client_contact_name'] ?? $jcFull['client_name'];
                    $clientSubject = "Job Card Document for {$jcFull['job_number']} — {$jcFull['title']}";
                    $jcFull['_pdf_url'] = generatePdfAccessToken($db, $id, 'client', $appUrl);
                    $html = $isNoCharge
                        ? tplClientNoCharge($jcFull, $recipientName, $companyName)
                        : tplClientInvoice($jcFull, $recipientName, $companyName);
                    queueEmail(
                        $db,
                        'job_invoiced',
                        $jcFull['client_email'],
                        $recipientName,
                        $clientSubject,
                        $html,
                        'job_card',
                        $id,
                        $clientPdfPath,
                        $pdfFileName
                    );
                } else {
                    if ($clientPdfPath)
                        @unlink($clientPdfPath);
                }
            }
        }
    } catch (Exception $ignored) {
    }
}

// ── job_assigned fires independently of status change ────
$newTechId2 = isset($_POST['assigned_to']) ? (int) post('assigned_to') : null;
if ($newTechId2 && $newTechId2 !== (int) $jc['assigned_to']) {
    try {
        require_once __DIR__ . '/../config/mailer.php';
        require_once __DIR__ . '/../emails/templates.php';

        $cfg = getMailerConfig($db);
        $appUrl = $cfg['email_app_url'] ?? '';
        $companyStmt = $db->query("SELECT setting_value FROM settings WHERE setting_key='company_name' LIMIT 1");
        $companyName = $companyStmt ? ($companyStmt->fetchColumn() ?: 'Elegant Work') : 'Elegant Work';
        $adminEmail = getAdminEmail($db);

        // New tech details
        $nts = $db->prepare("SELECT email, full_name AS name FROM users WHERE id=? LIMIT 1");
        $nts->execute([$newTechId2]);
        $ntr = $nts->fetch();
        $newTechEmail = $ntr['email'] ?? null;
        $newTechName = $ntr['name'] ?? null;

        // Full JC for templates
        $jcFull2 = $jc;
        $jcFull2['tech_name'] = $newTechName;
        $jcFull2['assigned_name'] = $newTechName;

        // Client email
        $clientEmail2 = null;
        $clientName2 = $jc['client_name'] ?? null;
        if ($jc['client_id']) {
            $cc = $db->prepare("SELECT c.company_name, cc.email, cc.full_name
                FROM clients c
                LEFT JOIN client_contacts cc ON cc.client_id = c.id AND cc.is_primary = 1
                WHERE c.id = ? LIMIT 1");
            $cc->execute([$jc['client_id']]);
            $ccRow = $cc->fetch();
            $jcFull2['client_name'] = $ccRow['company_name'] ?? null;
            $clientEmail2 = $ccRow['email'] ?? null;
            $clientName2 = $ccRow['full_name'] ?? $ccRow['company_name'] ?? null;
            $jcFull2['client_email'] = $clientEmail2;
            $jcFull2['client_contact_name'] = $clientName2;
        }

        $rule = getNotifRule($db, 'job_assigned');
        if ($rule && $rule['is_enabled']) {
            // Tech
            if ($rule['notify_assigned_tech'] && $newTechEmail) {
                $html = tplJobAssigned($jcFull2, $newTechName, $appUrl);
                queueEmail(
                    $db,
                    'job_assigned',
                    $newTechEmail,
                    $newTechName,
                    "🔧 Job Assigned to You: {$jc['job_number']}",
                    $html,
                    'job_card',
                    $id
                );
            }
            // Admin
            if ($rule['notify_admin'] && $adminEmail) {
                $html = tplJobCreated($jcFull2, 'Admin', $appUrl);
                queueEmail(
                    $db,
                    'job_assigned',
                    $adminEmail,
                    'Admin',
                    "👤 Tech Assigned: {$jc['job_number']} → {$newTechName}",
                    $html,
                    'job_card',
                    $id
                );
            }
            // Client — confirmed
            if ($rule['notify_client'] && $clientEmail2 && !$jc['is_internal']) {
                $html = tplClientJobConfirmed($jcFull2, $clientName2, $companyName);
                queueEmail(
                    $db,
                    'job_assigned',
                    $clientEmail2,
                    $clientName2,
                    "Your Job is Confirmed — {$jcFull2['title']}",
                    $html,
                    'job_card',
                    $id
                );
            }
        }
    } catch (Exception $e) {
        error_log('[EWG Email] job_assigned trigger failed: ' . $e->getMessage());
    }
}

apiSuccess([], 'Job card updated.');