<?php
// CRITICAL DEBUGGING LINES: These lines must be at the very top.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// PHP Expense Manager - Single File Application

// --- 1. CONFIGURATION AND INITIAL SETUP ---

// Constants
const PASSWORD = 'admin'; // Replace with a strong password for production!
const DATA_DIR = 'data/';
const RATE_PER_MILE = 0.37;
const API_KEY = 'AIzaSyAXH8rkgliY-fmyVDniKHYz_SCSV7nDYjw'; // Google Maps Directions API Key
const HOME_POSTCODE = 'G12 0DL'; // Defined 'Home' postcode for quick entry

// Start session for authentication and state management
session_start();

// --- 2. DEPENDENCY AND FILE HANDLING UTILITIES (HARDENED) ---

/**
 * Checks for required PHP extensions. Must run early in the script.
 */
function check_dependencies() {
    if (!function_exists('json_encode')) {
        die('*** FATAL ERROR: The PHP JSON extension is missing. Please ensure it is enabled in your hosting configuration (php.ini). ***');
    }
    if (!function_exists('curl_init')) {
        die('*** FATAL ERROR: The PHP cURL extension is missing. This is required for Google Maps API distance calculation. Please enable cURL. ***');
    }
}

/**
 * Creates the data directory and initializes JSON files if they don't exist.
 */
function init_data_structure() {
    // 1. ATTEMPT TO CREATE DIRECTORY
    if (!is_dir(DATA_DIR)) {
        // Use @ to suppress PHP warnings if permission is denied, then check the result
        if (!@mkdir(DATA_DIR, 0777, true)) {
            // Fatal error if we cannot create the directory. This is often the cause of a 500.
            die('*** FATAL ERROR: Failed to create the required data directory "' . DATA_DIR . '". Check file permissions (CHMOD) for the parent directory (usually 755 or 777 temporarily). ***');
        }
    }

    // 2. CHECK IF DIRECTORY IS WRITABLE (CRITICAL FOR FILE OPS)
    if (!is_writable(DATA_DIR)) {
        die('*** FATAL ERROR: The data directory "' . DATA_DIR . '" is not writable. Check file permissions (CHMOD). ***');
    }

    // 3. INITIALIZE FILES
    $files = [
        'locations.json' => [
            ["postcode" => "G12 0DL", "name" => "Home"],
            ["postcode" => "PA16 0EQ", "name" => "McGills Greenock"],
            ["postcode" => "IV1 1TB", "name" => "McGills Inverness"],
            ["postcode" => "EH54 8JY", "name" => "McGills Livingston"],
            ["postcode" => "G32 8EY", "name" => "Andrew Strain Construction"],
            ["postcode" => "G3 8EP", "name" => "Startline Motor Finance"],
            ["postcode" => "EH2 2EN", "name" => "McGills Edinburgh"],
            ["postcode" => "FK5 3NJ", "name" => "McGills Larbert"],
            ["postcode" => "FK7 8AD", "name" => "McGills Dundee"]
        ],
        'projects.json' => [
            "McGills",
            "ASC.PeopleCare"
        ],
        'trips.json' => [],
        'archive.json' => [],
        'state.json' => [
            'last_project' => 'McGills',
            'last_end_location_postcode' => HOME_POSTCODE,
            'current_date' => date('Y-m-d')
        ],
    ];

    foreach ($files as $filename => $initial_data) {
        $filepath = DATA_DIR . $filename;
        if (!file_exists($filepath)) {
            if (!write_json($filename, $initial_data)) {
                 error_log("FATAL: Failed to write initial data to $filepath. Permissions issue likely.");
            }
        }
    }
}

/**
 * Reads and decodes JSON from the data directory.
 * @param string $filename The name of the JSON file.
 * @return array The decoded data or an empty array on failure.
 */
function read_json($filename) {
    $filepath = DATA_DIR . $filename;
    // Check if the file exists and is readable before proceeding
    if (!file_exists($filepath) || !is_readable($filepath)) {
         return [];
    }
    
    $content = file_get_contents($filepath);
    
    if ($content === false || trim($content) === '') {
        return [];
    }
    
    $data = json_decode($content, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
         error_log("JSON decode error for $filepath: " . json_last_error_msg());
         return [];
    }
    
    return is_array($data) ? $data : [];
}

/**
 * Encodes and writes data to a JSON file in the data directory.
 * @param string $filename The name of the JSON file.
 * @param array $data The data to encode and write.
 * @return bool True on success, false on failure.
 */
function write_json($filename, $data) {
    $filepath = DATA_DIR . $filename;
    $content = json_encode($data, JSON_PRETTY_PRINT);
    
    if ($content === false) {
         error_log("JSON encode error for $filepath: " . json_last_error_msg());
         return false;
    }
    
    if (file_put_contents($filepath, $content) === false) {
        error_log("Failed to write content to file: $filepath. Check directory permissions.");
        return false;
    }
    
    return true;
}

// --- 3. GOOGLE MAPS API INTEGRATION ---

/**
 * Calls Google Maps Directions API to get distance between two postcodes.
 * @param string $start_postcode Start location (postcode).
 * @param string $end_postcode End location (postcode).
 * @return float|null Distance in miles, or null on failure.
 */
function get_distance($start_postcode, $end_postcode) {
    // Dependency check already run, so cURL should exist, but we keep the logic clean.
    if (!function_exists('curl_init')) {
        return null; 
    }

    $start = urlencode($start_postcode);
    $end = urlencode($end_postcode);
    $url = "https://maps.googleapis.com/maps/api/directions/json?origin={$start}&destination={$end}&units=imperial&key=" . API_KEY;

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    $response = curl_exec($ch);

    if ($response === false) {
        error_log("cURL execution failed: " . curl_error($ch));
        curl_close($ch);
        return null; // Return null on execution failure
    }

    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code !== 200) {
        error_log("Google Maps API call failed. HTTP Code: $http_code.");
        return null;
    }

    $data = json_decode($response, true);

    if (
        !isset($data['status']) || $data['status'] !== 'OK' || 
        !isset($data['routes'][0]['legs'][0]['distance']['value'])
    ) {
        error_log("Google Maps API status not OK or distance missing. Status: " . ($data['status'] ?? 'Unknown'));
        return null;
    }

    // Distance is in meters, convert to miles and round to 2 decimal places
    $distance_meters = $data['routes'][0]['legs'][0]['distance']['value'];
    $distance_miles = round($distance_meters * 0.000621371, 2);

    return $distance_miles;
}

// --- 4. GET REQUEST HANDLER (FOR DOWNLOADS) ---

/**
 * Handles all GET requests that require action (specifically CSV download).
 */
function handle_download_request() {
    // Check for the specific GET action for CSV export
    if (isset($_GET['action']) && $_GET['action'] === 'download_archive_csv') {

        // --- AUTHENTICATION CHECK (Optional but recommended for security) ---
        if (!isset($_SESSION['authenticated'])) {
            die('Authentication Required for Download.');
        }

        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="expense_archive_' . date('Ymd_His') . '.csv"');

        // Output to buffer
        $output = fopen('php://output', 'w');

        // CSV Header
        fputcsv($output, ['Date', 'Project', 'Start Location Name', 'Start Postcode', 'End Location Name', 'End Postcode', 'Distance (miles)', 'Cost (£)', 'Scored']);

        $archive_data = read_json('archive.json');
        $locations = read_json('locations.json');
        $locations_map = array_column($locations, 'name', 'postcode');

        foreach ($archive_data as $trip) {
            // Retrieve location names using the postcode map
            $row = [
                $trip['date'],
                $trip['project'],
                $locations_map[$trip['start']] ?? $trip['start'],
                $trip['start'],
                $locations_map[$trip['end']] ?? $trip['end'],
                $trip['end'],
                $trip['distance'],
                $trip['cost'],
                $trip['scored'] ? 'Yes' : 'No'
            ];
            fputcsv($output, $row);
        }

        fclose($output);
        exit; // Terminate execution after file download is served
    }
}


// --- 5. POST REQUEST HANDLER (FOR API/AJAX ACTIONS) ---

/**
 * Handles all POST requests for application logic.
 */
function handle_post_request() {
    if (!isset($_POST['action'])) {
        return;
    }

    $action = $_POST['action'];
    $trips = read_json('trips.json');
    $locations = read_json('locations.json');
    $projects = read_json('projects.json');
    $state = read_json('state.json');

    $response = ['success' => false, 'message' => ''];

    switch ($action) {
        case 'add_trip':
            $date = $_POST['date'] ?? null;
            $start = $_POST['start'] ?? null;
            $end = $_POST['end'] ?? null;
            $project = $_POST['project'] ?? null;

            if (!$date || !$start || !$end || !$project) {
                $response = ['success' => false, 'message' => 'All fields are required.'];
                break;
            }
            if ($start === $end) {
                $response = ['success' => false, 'message' => 'Start and End locations must be different.'];
                break;
            }

            $new_trip = [
                'id' => uniqid(),
                'date' => $date,
                'start' => $start,
                'end' => $end,
                'project' => $project,
                'distance' => null,
                'cost' => null,
                'scored' => false
            ];

            $trips[] = $new_trip;
            write_json('trips.json', $trips);

            // Update state for next entry
            $state['last_project'] = $project;
            $state['last_end_location_postcode'] = $end;
            $state['current_date'] = $date;
            write_json('state.json', $state);

            $response = ['success' => true, 'message' => 'Trip added.'];
            break;

        case 'quick_asc_trip':
            $date = $_POST['date'] ?? date('Y-m-d');
            $project = 'ASC.PeopleCare';
            $asc_postcode = 'G32 8EY';
            $home_postcode = HOME_POSTCODE;

            // 1. Home -> ASC
            $trip1 = [
                'id' => uniqid(), 'date' => $date, 'start' => $home_postcode, 'end' => $asc_postcode,
                'project' => $project, 'distance' => null, 'cost' => null, 'scored' => false
            ];
            // 2. ASC -> Home
            $trip2 = [
                'id' => uniqid(), 'date' => $date, 'start' => $asc_postcode, 'end' => $home_postcode,
                'project' => $project, 'distance' => null, 'cost' => null, 'scored' => false
            ];

            $trips[] = $trip1;
            $trips[] = $trip2;
            write_json('trips.json', $trips);

            // Update state
            $state['last_project'] = $project;
            $state['last_end_location_postcode'] = $home_postcode;
            $state['current_date'] = $date;
            write_json('state.json', $state);

            $response = ['success' => true, 'message' => 'ASC.PeopleCare trip added.'];
            break;

        case 'quick_back_home':
            $date = $_POST['date'] ?? date('Y-m-d');
            $project = $_POST['project'] ?? $state['last_project'] ?? 'McGills';
            $start = $_POST['last_end'] ?? HOME_POSTCODE;
            $end = HOME_POSTCODE;

            if ($start === $end) {
                $response = ['success' => false, 'message' => 'Already at home.'];
                break;
            }

            $new_trip = [
                'id' => uniqid(), 'date' => $date, 'start' => $start, 'end' => $end,
                'project' => $project, 'distance' => null, 'cost' => null, 'scored' => false
            ];

            $trips[] = $new_trip;
            write_json('trips.json', $trips);

            // Update state
            $state['last_end_location_postcode'] = $end;
            $state['current_date'] = $date;
            write_json('state.json', $state);

            $response = ['success' => true, 'message' => 'Back Home trip added.'];
            break;

        case 'delete_trip':
            $id = $_POST['id'] ?? null;
            $trips = array_filter($trips, function($t) use ($id) {
                return $t['id'] !== $id;
            });
            write_json('trips.json', array_values($trips)); // Reindex array
            $response = ['success' => true, 'message' => 'Trip deleted.'];
            break;

        case 'toggle_scored':
            $id = $_POST['id'] ?? null;
            $trips = array_map(function($t) use ($id) {
                if ($t['id'] === $id) {
                    $t['scored'] = !$t['scored'];
                }
                return $t;
            }, $trips);
            write_json('trips.json', $trips);
            $response = ['success' => true];
            break;

        case 'calculate_distances':
            $updated_trips = 0;
            // Use reference (&) to modify the array in place
            foreach ($trips as &$trip) { 
                if ($trip['distance'] === null) {
                    $distance = get_distance($trip['start'], $trip['end']);
                    if ($distance !== null) {
                        $trip['distance'] = $distance;
                        $trip['cost'] = round($distance * RATE_PER_MILE, 2);
                        $updated_trips++;
                    }
                }
            }
            // Dereference the last element to avoid issues
            unset($trip); 
            
            write_json('trips.json', $trips);
            $response = ['success' => true, 'message' => "Calculated distances for $updated_trips trips."];
            break;

        case 'archive_trips':
            $archive = read_json('archive.json');
            $archive = array_merge($archive, $trips);
            write_json('archive.json', $archive);
            write_json('trips.json', []); // Clear main trips
            $response = ['success' => true, 'message' => 'Trips archived.'];
            break;
            
        case 'clear_archive':
            write_json('archive.json', []); // Clear main archive
            $response = ['success' => true, 'message' => 'Archive cleared successfully.'];
            break;

        case 'add_location':
            $name = trim($_POST['name'] ?? '');
            $postcode = trim($_POST['postcode'] ?? '');
            if (!$name || !$postcode) {
                $response = ['success' => false, 'message' => 'Name and Postcode required.'];
                break;
            }
            // Validate unique postcode
            $postcodes = array_column($locations, 'postcode');
            if (in_array(strtoupper($postcode), $postcodes)) {
                $response = ['success' => false, 'message' => 'Postcode already exists.'];
                break;
            }
            $locations[] = ['name' => $name, 'postcode' => strtoupper($postcode)];
            write_json('locations.json', $locations);
            $response = ['success' => true, 'message' => 'Location added.', 'locations' => $locations];
            break;

        case 'remove_location':
            $postcode = $_POST['postcode'] ?? null;
            $locations = array_filter($locations, function($l) use ($postcode) {
                return $l['postcode'] !== $postcode;
            });
            write_json('locations.json', array_values($locations));
            $response = ['success' => true, 'message' => 'Location removed.', 'locations' => array_values($locations)];
            break;

        case 'add_project':
            $name = trim($_POST['name'] ?? '');
            if (!$name) {
                $response = ['success' => false, 'message' => 'Project name required.'];
                break;
            }
            // Validate unique name
            if (in_array($name, $projects)) {
                $response = ['success' => false, 'message' => 'Project name already exists.'];
                break;
            }
            $projects[] = $name;
            write_json('projects.json', $projects);
            $response = ['success' => true, 'message' => 'Project added.', 'projects' => $projects];
            break;

        case 'remove_project':
            $name = $_POST['name'] ?? null;
            $projects = array_filter($projects, function($p) use ($name) {
                return $p !== $name;
            });
            write_json('projects.json', array_values($projects));
            $response = ['success' => true, 'message' => 'Project removed.', 'projects' => array_values($projects)];
            break;
    }

    // Send JSON response for AJAX requests
    if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        header('Content-Type: application/json');
        echo json_encode($response);
        exit;
    }
}

// --- 6. EXECUTION FLOW ---

// 1. Dependency Check (New, most likely cause of 500)
check_dependencies();

// 2. Check/create data files and structure
init_data_structure();

// 3. Handle file download requests first (must be before session rendering)
handle_download_request();

// 4. Handle all AJAX POST submissions
handle_post_request();

// --- AUTHENTICATION ---
if (!isset($_SESSION['authenticated'])) {
    if (isset($_POST['password']) && $_POST['password'] === PASSWORD) {
        $_SESSION['authenticated'] = true;
        header('Location: ' . $_SERVER['PHP_SELF']); // Redirect to clear POST data
        exit;
    }
    // If not authenticated, render the password form and stop
    render_login_page();
    exit;
}

// --- MAIN APPLICATION DATA AND STATE ---

$is_archive_view = isset($_GET['view']) && $_GET['view'] === 'archive';

$trips_raw = $is_archive_view ? read_json('archive.json') : read_json('trips.json');
$locations = read_json('locations.json');
$projects = read_json('projects.json');
$state = read_json('state.json');
$archive_is_empty = empty(read_json('archive.json'));

// Helper map for quick lookup of location details (name/postcode)
$locations_map = [];
// CRITICAL: Ensure $locations is an array before iterating
if (is_array($locations)) {
    foreach ($locations as $loc) {
        $locations_map[$loc['postcode']] = $loc;
    }
}


// Group trips by date for display
$trips_grouped = [];
// CRITICAL: Ensure $trips_raw is an array before iterating
if (is_array($trips_raw)) {
    foreach ($trips_raw as $trip) {
        // Ensure all required fields exist for sorting/grouping, even if null
        $trip = array_merge(['date' => date('Y-m-d'), 'project' => 'N/A', 'distance' => null, 'cost' => null, 'scored' => false], $trip);
        $trips_grouped[$trip['date']][] = $trip;
    }
    krsort($trips_grouped); // Sort dates descending
}


// Prepare initial form values
$form_project = $state['last_project'] ?? $projects[0] ?? '';
$form_start_loc = $state['last_end_location_postcode'] ?? HOME_POSTCODE;
$form_date = $state['current_date'] ?? date('Y-m-d');

// Find last end location name for Back Home button
$last_end_name = $locations_map[$form_start_loc]['name'] ?? 'Unknown Location';


// --- 7. RENDER FUNCTIONS ---

/**
 * Renders the full login page.
 */
function render_login_page() {
    echo '
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login - Travel Expenses</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        body { font-family: "Inter", sans-serif; background-color: #f3f4f6; }
    </style>
</head>
<body>
    <div class="min-h-screen flex items-center justify-center">
        <div class="bg-white p-8 rounded-xl shadow-2xl w-full max-w-sm">
            <h2 class="text-2xl font-bold mb-6 text-gray-800 text-center">Travel Expenses Login</h2>
            <form method="POST">
                <input type="password" name="password" placeholder="Enter Password" required
                       class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-sky-500 mb-4 text-sm" autofocus>
                <button type="submit"
                        class="w-full bg-sky-600 hover:bg-sky-700 text-white font-semibold py-3 rounded-lg transition duration-200 shadow-md">
                    Log In
                </button>
            </form>
        </div>
    </div>
</body>
</html>
    ';
}

/**
 * Renders the main application HTML (after authentication).
 */
function render_main_app($trips_grouped, $locations, $projects, $locations_map, $is_archive_view, $form_project, $form_start_loc, $form_date, $last_end_name, $archive_is_empty) {
    // Inject PHP data into JS for client-side functionality
    $js_locations = json_encode($locations);
    $js_projects = json_encode($projects);
    $js_last_end_loc = json_encode($form_start_loc);

    // Conditional classes for layout adjustment
    $list_container_classes = "bg-white p-4 rounded-xl shadow-md order-1 lg:order-2 ";
    if ($is_archive_view) {
        // Take up full width, and center within a maximum width for desktop view
        $list_container_classes .= "lg:col-span-4 max-w-6xl lg:mx-auto ";
    } else {
        // Take up 3 columns on desktop, part of the 4-column grid
        $list_container_classes .= "lg:col-span-3 ";
    }

    ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Travel Expenses Manager</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        :root {
            --header-bg: #0e7490; /* Sky-700 */
            --primary-color: #0369a1; /* Sky-800 */
        }
        body { font-family: "Inter", sans-serif; background-color: #f3f4f6; }
        .compact-field { padding: 0.25rem 0.5rem; font-size: 0.875rem; height: 2rem; }
        .compact-btn { padding: 0.25rem 0.75rem; font-size: 0.875rem; height: 2rem; }

        /* IMPROVED TABLE STYLING */
        .table-header { 
            font-size: 0.85rem; 
            font-weight: 700; /* Bolder header */
            color: #1f2937; /* Darker header text */
            background-color: #e2e8f0; /* Light blue-gray for visibility */
            border-bottom: 2px solid #94a3b8;
        }
        .list-row { 
            font-size: 0.85rem; /* Slightly larger text */
            border-bottom: 1px solid #e5e7eb;
            color: #374151; /* Default dark text color for clarity */
        }
        .list-row:nth-child(even) {
            background-color: #fcfcfc; /* Subtle alternating background */
        }
        /* Ensure Archive View rows are NOT struck through */
        .list-row.strike-through { 
            text-decoration: line-through; 
            color: #9ca3af; 
            background-color: #fcfcfc; /* Keep light background */
        }
        /* End IMPROVED TABLE STYLING */
        
        /* Custom Toast Notification styles */
        #toast-container { 
            position: fixed; 
            top: 20px;
            right: 20px;
            z-index: 50; /* Ensure toast is visible over content (z-20) */
            pointer-events: none; /* Allows clicks to pass through */
        }
        .toast {
            background-color: var(--primary-color);
            color: white;
            padding: 8px 12px;
            border-radius: 6px;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
            opacity: 0;
            transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
            transform: translateY(10px);
            margin-bottom: 10px; /* Space between multiple toasts */
            pointer-events: all; /* Allow toasts to be interacted with */
        }
        .toast.show { opacity: 1; transform: translateY(0); }
        .popup-overlay { background-color: rgba(0, 0, 0, 0.5); }
    </style>
</head>
<body class="p-2 sm:p-4">
    <!-- Toast Notification Container -->
    <div id="toast-container" class="top-4 right-4 flex flex-col items-end"></div>

    <!-- Header and Management Buttons -->
    <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-4 p-2 bg-white rounded-xl shadow-md sticky top-0 z-20 max-w-7xl mx-auto">
        <h1 class="text-xl font-bold text-gray-800"><?= $is_archive_view ? 'Trip Archive' : 'Live Trip Entries' ?></h1>
        <div class="flex flex-wrap gap-2 mt-2 sm:mt-0">
            <!-- ARCHIVE/LIVE TOGGLE -->
            <?php if ($is_archive_view): ?>
                <button onclick="window.location.href='<?= $_SERVER['PHP_SELF'] ?>'"
                        class="compact-btn bg-yellow-500 hover:bg-yellow-600 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                    Return to Live List
                </button>
                <button onclick="document.getElementById('archive-management-modal').classList.remove('hidden')"
                        class="compact-btn bg-red-600 hover:bg-red-700 text-white font-semibold rounded-lg shadow-sm transition duration-150"
                        <?= $archive_is_empty ? 'disabled' : '' ?> title="<?= $archive_is_empty ? 'Archive is empty' : 'Manage Archive' ?>">
                    Manage Archive
                </button>
            <?php else: ?>
                <button onclick="document.getElementById('archive-modal').classList.remove('hidden')"
                        class="compact-btn bg-red-600 hover:bg-red-700 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                    Archive Trips
                </button>
                <button onclick="window.location.href='<?= $_SERVER['PHP_SELF'] ?>?view=archive'"
                        class="compact-btn bg-yellow-500 hover:bg-yellow-600 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                    View Archive
                </button>
            <?php endif; ?>

            <!-- MANAGEMENT BUTTONS (TOP RIGHT) -->
            <button onclick="openProjectModal()"
                    class="compact-btn bg-gray-500 hover:bg-gray-600 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                Manage Projects
            </button>
            <button onclick="openLocationModal()"
                    class="compact-btn bg-gray-500 hover:bg-gray-600 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                Manage Locations
            </button>
        </div>
    </div>

    <!-- MAIN CONTENT -->
    <main class="grid grid-cols-1 <?= !$is_archive_view ? 'lg:grid-cols-4' : '' ?> gap-4 max-w-7xl mx-auto">

        <!-- Trip Entry Form (Hidden in Archive View) -->
        <?php if (!$is_archive_view): ?>
        <div id="entry-form-panel" class="lg:col-span-1 bg-white p-4 rounded-xl shadow-md order-2 lg:order-1">
            <h2 class="text-lg font-semibold mb-3 text-gray-700 border-b pb-2">New Trip Entry</h2>
            <form id="trip-entry-form" class="space-y-2 text-xs">
                <div>
                    <label for="date" class="block text-gray-600">Date</label>
                    <input type="date" id="date" name="date" required value="<?= $form_date ?>"
                           class="compact-field w-full border border-gray-300 rounded-lg focus:ring-sky-500 focus:border-sky-500">
                </div>
                <div>
                    <label for="project" class="block text-gray-600">Customer/Project</label>
                    <select id="project" name="project" required
                            class="compact-field w-full border border-gray-300 rounded-lg bg-white focus:ring-sky-500 focus:border-sky-500">
                        <?php 
                        // CRITICAL: Ensure $projects is an array before iterating
                        $projects = is_array($projects) ? $projects : [];
                        foreach ($projects as $p): ?>
                            <option value="<?= $p ?>" <?= $p === $form_project ? 'selected' : '' ?>><?= $p ?></option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div>
                    <label for="start_loc" class="block text-gray-600">Start Location</label>
                    <select id="start_loc" name="start" required
                            class="compact-field w-full border border-gray-300 rounded-lg bg-white focus:ring-sky-500 focus:border-sky-500">
                        <?php 
                        // CRITICAL: Ensure $locations is an array before iterating
                        $locations = is_array($locations) ? $locations : [];
                        foreach ($locations as $l): ?>
                            <option value="<?= $l['postcode'] ?>" data-name="<?= $l['name'] ?>"
                                    <?= $l['postcode'] === $form_start_loc ? 'selected' : '' ?>>
                                <?= $l['name'] ?> (<?= $l['postcode'] ?>)
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <div>
                    <label for="end_loc" class="block text-gray-600">End Location</label>
                    <select id="end_loc" name="end" required
                            class="compact-field w-full border border-gray-300 rounded-lg bg-white focus:ring-sky-500 focus:border-sky-500">
                        <?php 
                        // CRITICAL: Ensure $locations is an array before iterating
                        $locations = is_array($locations) ? $locations : [];
                        foreach ($locations as $l): ?>
                            <option value="<?= $l['postcode'] ?>" data-name="<?= $l['name'] ?>">
                                <?= $l['name'] ?> (<?= $l['postcode'] ?>)
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                <button type="submit" data-action="add_trip"
                        class="compact-btn w-full bg-sky-600 hover:bg-sky-700 text-white font-bold rounded-lg transition duration-150 mt-4">
                    Add Entry
                </button>
            </form>

            <div class="mt-4 pt-4 border-t border-gray-200 space-y-2">
                 <button onclick="handleQuickEntry(event, 'quick_asc_trip')"
                        class="compact-btn w-full bg-blue-500 hover:bg-blue-600 text-white rounded-lg shadow-sm transition duration-150">
                    ASC.PeopleCare (Return Trip)
                </button>
                <button onclick="handleQuickEntry(event, 'quick_back_home')"
                        class="compact-btn w-full bg-purple-500 hover:bg-purple-600 text-white rounded-lg shadow-sm transition duration-150">
                    Back Home (<?= $last_end_name ?>)
                </button>
            </div>
        </div>
        <?php endif; ?>

        <!-- Trips List -->
        <div class="<?= $list_container_classes ?>">
            <h2 class="text-lg font-semibold mb-3 text-gray-700 border-b pb-2"><?= $is_archive_view ? 'Archived' : 'Current' ?> Trips</h2>

            <!-- Action Buttons for Live List -->
            <?php if (!$is_archive_view): ?>
                <div class="flex flex-wrap gap-2 mb-4">
                    <button onclick="handleAction(event, 'calculate_distances')"
                            class="compact-btn bg-indigo-600 hover:bg-indigo-700 text-white font-semibold rounded-lg shadow-sm transition duration-150">
                        Calculate Distance & Costs
                    </button>
                </div>
            <?php endif; ?>

            <?php if (empty($trips_grouped)): ?>
                <div class="text-center py-10 text-gray-500">No trips found.</div>
            <?php else: ?>
                <div class="overflow-x-auto">
                    <!-- Column Headers -->
                    <div class="min-w-[1000px] flex table-header py-2 px-1 rounded-t-lg">
                        <div class="w-1/12 text-center">Date</div>
                        <div class="w-2/12">Start Location & Postcode</div>
                        <div class="w-2/12">End Location & Postcode</div>
                        <div class="w-1/12 text-center">Distance (mi)</div>
                        <div class="w-2/12">Project</div>
                        <div class="w-1/12 text-right">Cost (£)</div>
                        <div class="w-1/12 text-center">Scored</div>
                        <div class="w-1/12 text-center">Action</div>
                    </div>

                    <?php
                    $running_distance = 0;
                    $running_cost = 0;
                    $row_count = 0; // for alternating row colors
                    foreach ($trips_grouped as $date => $trips):
                    ?>
                        <!-- Date Group Header -->
                        <div class="min-w-[1000px] bg-sky-100 text-sky-800 font-bold text-sm px-2 py-1 sticky top-14 z-10 shadow-sm border-t border-b border-sky-300">
                            <?= date('l, d M Y', strtotime($date)) ?>
                        </div>

                        <?php
                        $date_distance = 0;
                        $date_cost = 0;
                        foreach ($trips as $trip):
                            $start_loc = $locations_map[$trip['start']] ?? ['name' => '?', 'postcode' => $trip['start']];
                            $end_loc = $locations_map[$trip['end']] ?? ['name' => '?', 'postcode' => $trip['end']];
                            $distance = $trip['distance'] ?? 'N/A';
                            $cost = $trip['cost'] ?? 'N/A';

                            $running_distance += is_numeric($distance) ? $distance : 0;
                            $running_cost += is_numeric($cost) ? $cost : 0;
                            $date_distance += is_numeric($distance) ? $distance : 0;
                            $date_cost += is_numeric($cost) ? $cost : 0;
                            $row_count++;
                        ?>
                            <!-- Trip Row -->
                            <div class="min-w-[1000px] flex list-row items-center hover:bg-gray-100 <?= !$is_archive_view && $trip['scored'] ? 'strike-through' : '' ?>">
                                <div class="w-1/12 text-center py-1"><?= date('d/m', strtotime($trip['date'])) ?></div>

                                <!-- Start Location (Click to Copy Postcode) -->
                                <div class="w-2/12 cursor-pointer text-sky-700 hover:underline"
                                     onclick="copyToClipboard(this, '<?= $start_loc['postcode'] ?>')">
                                    <div class="truncate" title="<?= $start_loc['name'] ?>"><?= $start_loc['name'] ?></div>
                                    <div class="font-mono text-xs"><?= $start_loc['postcode'] ?></div>
                                </div>

                                <!-- End Location (Click to Copy Postcode) -->
                                <div class="w-2/12 cursor-pointer text-sky-700 hover:underline"
                                     onclick="copyToClipboard(this, '<?= $end_loc['postcode'] ?>')">
                                    <div class="truncate" title="<?= $end_loc['name'] ?>"><?= $end_loc['name'] ?></div>
                                    <div class="font-mono text-xs"><?= $end_loc['postcode'] ?></div>
                                </div>

                                <!-- Distance (Click to Copy Value) -->
                                <div class="w-1/12 text-center cursor-pointer hover:underline"
                                     onclick="copyToClipboard(this, '<?= is_numeric($distance) ? $distance : '' ?>')">
                                    <?= $distance ?>
                                </div>

                                <!-- Project (Click to Copy Value) -->
                                <div class="w-2/12 truncate cursor-pointer hover:underline"
                                     onclick="copyToClipboard(this, '<?= $trip['project'] ?>')">
                                    <?= $trip['project'] ?>
                                </div>

                                <!-- Cost -->
                                <div class="w-1/12 text-right font-semibold">
                                    <?= is_numeric($cost) ? '£' . number_format($cost, 2) : $cost ?>
                                </div>

                                <!-- Scored Checkbox (Only on Live List) -->
                                <div class="w-1/12 text-center">
                                    <?php if (!$is_archive_view): ?>
                                        <input type="checkbox" data-id="<?= $trip['id'] ?>" onchange="toggleScored(this)"
                                               class="h-4 w-4 text-green-600 border-gray-300 rounded focus:ring-green-500"
                                               <?= $trip['scored'] ? 'checked' : '' ?>>
                                    <?php endif; ?>
                                </div>

                                <!-- Delete Button (Only on Live List) -->
                                <div class="w-1/12 text-center">
                                    <?php if (!$is_archive_view): ?>
                                        <button onclick="deleteTrip('<?= $trip['id'] ?>')"
                                                class="text-red-500 hover:text-red-700 text-xs">
                                            &#x2715; <!-- X mark -->
                                        </button>
                                    <?php endif; ?>
                                </div>
                            </div>
                        <?php endforeach; // End trips loop ?>

                        <!-- Date Sub-Total Row -->
                        <div class="min-w-[1000px] flex list-row items-center bg-gray-100 font-bold text-sm text-gray-700 border-t border-gray-200">
                            <div class="w-5/12 text-right pr-2">Total for <?= date('d M Y', strtotime($date)) ?>:</div>
                            <div class="w-1/12 text-center"><?= number_format($date_distance, 2) ?></div>
                            <div class="w-2/12"></div>
                            <div class="w-1/12 text-right"><?= '£' . number_format($date_cost, 2) ?></div>
                            <div class="w-2/12"></div>
                        </div>

                    <?php endforeach; // End date groups loop ?>

                    <!-- GRAND TOTALS -->
                    <div class="min-w-[1000px] flex list-row items-center bg-sky-200 font-extrabold text-base text-sky-900 mt-2 p-2 rounded-b-lg shadow-inner">
                        <div class="w-5/12 text-right pr-2">GRAND TOTAL:</div>
                        <div class="w-1/12 text-center"><?= number_format($running_distance, 2) ?></div>
                        <div class="w-2/12"></div>
                        <div class="w-1/12 text-right"><?= '£' . number_format($running_cost, 2) ?></div>
                        <div class="w-2/12"></div>
                    </div>
                </div>
            <?php endif; ?>
        </div>
    </main>

    <!-- MODAL POPUPS - Z-INDEX z-[90] for top-most visibility and flex for centering -->

    <!-- Location Management Modal -->
    <div id="location-modal" class="popup-overlay fixed inset-0 z-[90] hidden flex items-center justify-center p-4" onclick="if(event.target.id==='location-modal') closeModal('location-modal')">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-lg p-6">
            <h3 class="text-xl font-bold mb-4 border-b pb-2">Manage Locations</h3>
            <div id="location-message" class="text-xs text-red-500 mb-2"></div>

            <div class="mb-4 p-3 border rounded-lg bg-gray-50 space-y-2">
                <h4 class="font-semibold text-sm">Add New Location</h4>
                <input type="text" id="add-loc-name" placeholder="Location Name" class="compact-field w-full border rounded">
                <input type="text" id="add-loc-postcode" placeholder="Postcode (e.g., AB1 2CD)" class="compact-field w-full border rounded">
                <button onclick="manageLocation('add')" class="compact-btn bg-green-500 hover:bg-green-600 text-white rounded-lg w-full">Add Location</button>
            </div>

            <h4 class="font-semibold text-sm mb-2">Existing Locations</h4>
            <div id="locations-list" class="max-h-60 overflow-y-auto border p-2 rounded-lg space-y-1 text-xs">
                <!-- Location list will be populated by JS -->
            </div>

            <button onclick="closeModal('location-modal')" class="compact-btn mt-4 bg-gray-200 hover:bg-gray-300 rounded-lg">Close</button>
        </div>
    </div>

    <!-- Project Management Modal -->
    <div id="project-modal" class="popup-overlay fixed inset-0 z-[90] hidden flex items-center justify-center p-4" onclick="if(event.target.id==='project-modal') closeModal('project-modal')">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-sm p-6">
            <h3 class="text-xl font-bold mb-4 border-b pb-2">Manage Projects</h3>
            <div id="project-message" class="text-xs text-red-500 mb-2"></div>

            <div class="mb-4 p-3 border rounded-lg bg-gray-50 space-y-2">
                <h4 class="font-semibold text-sm">Add New Project</h4>
                <input type="text" id="add-proj-name" placeholder="Project Name" class="compact-field w-full border rounded">
                <button onclick="manageProject('add')" class="compact-btn bg-green-500 hover:bg-green-600 text-white rounded-lg w-full">Add Project</button>
            </div>

            <h4 class="font-semibold text-sm mb-2">Existing Projects</h4>
            <div id="projects-list" class="max-h-60 overflow-y-auto border p-2 rounded-lg space-y-1 text-xs">
                <!-- Project list will be populated by JS -->
            </div>

            <button onclick="closeModal('project-modal')" class="compact-btn mt-4 bg-gray-200 hover:bg-gray-300 rounded-lg">Close</button>
        </div>
    </div>

    <!-- Live Trips Archive Confirmation Modal -->
    <div id="archive-modal" class="popup-overlay fixed inset-0 z-[90] hidden flex items-center justify-center p-4" onclick="if(event.target.id==='archive-modal') closeModal('archive-modal')">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-xs p-6 text-center">
            <h3 class="text-lg font-bold mb-4">Confirm Archive</h3>
            <p class="mb-6 text-gray-600">Are you sure you want to move all current trips to the archive?</p>
            <div class="flex justify-between gap-3">
                <button onclick="closeModal('archive-modal')" class="compact-btn flex-1 bg-gray-300 hover:bg-gray-400 rounded-lg">Cancel</button>
                <button onclick="handleAction(event, 'archive_trips')" class="compact-btn flex-1 bg-red-600 hover:bg-red-700 text-white rounded-lg">Archive</button>
            </div>
        </div>
    </div>
    
    <!-- Archive Management Modal (New) -->
    <div id="archive-management-modal" class="popup-overlay fixed inset-0 z-[90] hidden flex items-center justify-center p-4" onclick="if(event.target.id==='archive-management-modal') closeModal('archive-management-modal')">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-sm p-6">
            <h3 class="text-xl font-bold mb-4 border-b pb-2">Archive Management</h3>
            <p class="mb-4 text-gray-700 text-sm">Manage the permanent trip archive.</p>

            <div class="space-y-4">
                <button onclick="downloadCSV()" class="compact-btn w-full bg-green-600 hover:bg-green-700 text-white font-semibold rounded-lg shadow-md transition duration-150">
                    &#x1F4BE; Download Archive (CSV)
                </button>
                
                <div class="border p-3 rounded-lg bg-red-50">
                    <p class="text-sm font-semibold mb-2 text-red-700">Danger Zone</p>
                    <p class="text-xs mb-3 text-red-600">Clearing the archive permanently deletes all archived trip data. Export first!</p>
                    <button onclick="handleAction(event, 'clear_archive')" class="compact-btn w-full bg-red-600 hover:bg-red-700 text-white rounded-lg">
                        Permanently Clear Archive
                    </button>
                </div>
            </div>

            <button onclick="closeModal('archive-management-modal')" class="compact-btn mt-4 bg-gray-200 hover:bg-gray-300 rounded-lg">Close</button>
        </div>
    </div>

    <!-- Custom Confirmation Modal (Yes/No) - NEW -->
    <div id="custom-confirm-modal" class="popup-overlay fixed inset-0 z-[90] hidden flex items-center justify-center p-4" onclick="if(event.target.id==='custom-confirm-modal') closeModal('custom-confirm-modal')">
        <div class="bg-white rounded-xl shadow-2xl w-full max-w-xs p-6 text-center">
            <h3 id="confirm-title" class="text-lg font-bold mb-4">Confirm Action</h3>
            <p id="confirm-message" class="mb-6 text-gray-600">Are you sure?</p>
            <div class="flex justify-between gap-3">
                <button id="confirm-cancel-btn" class="compact-btn flex-1 bg-gray-300 hover:bg-gray-400 rounded-lg">No</button>
                <button id="confirm-yes-btn" class="compact-btn flex-1 bg-red-600 hover:bg-red-700 text-white font-semibold rounded-lg shadow-md transition duration-150">Yes</button>
            </div>
        </div>
    </div>


    <!-- JAVASCRIPT LOGIC -->
    <script>
        // Global Data from PHP
        let allLocations = <?= $js_locations ?>;
        let allProjects = <?= $js_projects ?>;
        const lastEndLocationPostcode = <?= $js_last_end_loc ?>;
        const HOME_POSTCODE = '<?= HOME_POSTCODE ?>';
        
        // Stores the function to call after confirmation from the custom modal
        let confirmCallback = null; 
        
        // --- UTILITY FUNCTIONS ---

        function closeModal(id) {
            document.getElementById(id).classList.add('hidden');
            // When closing the confirm modal, remove the global listener
            if (id === 'custom-confirm-modal') {
                document.removeEventListener('keydown', handleEnterKey);
            }
        }

        /**
         * Function to open the Location Management modal and render the list.
         */
        function openLocationModal() {
            renderLocationsList();
            document.getElementById('location-modal').classList.remove('hidden');
        }

        /**
         * Function to open the Project Management modal and render the list.
         */
        function openProjectModal() {
            renderProjectsList();
            document.getElementById('project-modal').classList.remove('hidden');
        }
        
        /**
         * Global handler for the Enter key when the custom confirmation modal is open.
         * This makes 'Yes' the default action.
         */
        function handleEnterKey(event) {
            if (document.getElementById('custom-confirm-modal').classList.contains('hidden')) {
                document.removeEventListener('keydown', handleEnterKey);
                return;
            }

            if (event.key === 'Enter') {
                event.preventDefault(); 
                const yesBtn = document.getElementById('confirm-yes-btn');
                yesBtn.click(); // Programmatically click the Yes button
            }
        }
        
        /**
         * Opens the custom Yes/No confirmation modal.
         * @param {string} message The message to display.
         * @param {function(boolean)} callback Function to call: true for Yes, false for No.
         * @param {string} title The title of the modal.
         */
        function showCustomConfirm(message, callback, title = 'Confirm Action') {
            const modal = document.getElementById('custom-confirm-modal');
            document.getElementById('confirm-title').textContent = title;
            document.getElementById('confirm-message').textContent = message;
            
            confirmCallback = callback;

            const yesBtn = document.getElementById('confirm-yes-btn');
            const cancelBtn = document.getElementById('confirm-cancel-btn');

            // Reset event listeners
            yesBtn.onclick = () => {
                closeModal('custom-confirm-modal');
                if (confirmCallback) confirmCallback(true);
            };

            cancelBtn.onclick = () => {
                closeModal('custom-confirm-modal');
                if (confirmCallback) confirmCallback(false);
            };

            modal.classList.remove('hidden');
            
            // Set the focus on the YES button for "Enter Key" default action
            setTimeout(() => yesBtn.focus(), 50);

            // Add global listener to handle Enter key press
            document.addEventListener('keydown', handleEnterKey);
        }
        
        /**
         * Creates and displays a toast notification in the top-right corner.
         * @param {string} message The message to display.
         * @param {string} bgColor Tailwind background color class.
         */
        function showToast(message, bgColor = 'bg-sky-600') {
            const container = document.getElementById('toast-container');
            const toast = document.createElement('div');
            toast.className = `toast ${bgColor}`;
            toast.textContent = message;

            container.prepend(toast); // Prepend to show the newest toast at the top of the stack

            // Show and hide
            setTimeout(() => toast.classList.add('show'), 10);
            setTimeout(() => {
                toast.classList.remove('show');
                // Remove element after transition finishes
                setTimeout(() => {
                    if (container.contains(toast)) {
                        container.removeChild(toast);
                    }
                }, 300); 
            }, 3000); // Display for 3 seconds
        }

        // --- CORE APPLICATION LOGIC ---

        /**
         * Generic AJAX/Fetch handler.
         * @param {string} action The action to execute on the PHP backend.
         * @param {Object} data Additional data to send.
         * @returns {Promise<Object>} JSON response from the server.
         */
        async function postData(action, data = {}) {
            const formData = new FormData();
            formData.append('action', action);
            for (const key in data) {
                formData.append(key, data[key]);
            }

            try {
                const response = await fetch('<?= $_SERVER['PHP_SELF'] ?>', {
                    method: 'POST',
                    body: formData,
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });
                
                // If 500 or other non-OK status, log it and return a failure object
                if (!response.ok) {
                    console.error(`HTTP error! status: ${response.status} for action: ${action}`);
                    return { success: false, message: `Server error: HTTP ${response.status}. Check server logs.` };
                }
                
                return await response.json();
            } catch (error) {
                console.error('Fetch error:', error);
                showToast('Error processing request.', 'bg-red-500');
                return { success: false, message: 'Network request failed.' };
            }
        }

        /**
         * Handles primary form submissions and general actions.
         */
        document.getElementById('trip-entry-form')?.addEventListener('submit', async function(e) {
            e.preventDefault();
            const form = e.target;
            const date = form.elements.date.value;
            const start = form.elements.start.value;
            const end = form.elements.end.value;
            const project = form.elements.project.value;

            if (start === end) {
                showToast('Start and End locations must be different.', 'bg-red-500');
                return;
            }

            const response = await postData('add_trip', { date, start, end, project });

            if (response.success) {
                showToast('Trip added successfully!', 'bg-green-500');

                // Update form state logic
                form.elements.project.value = project; // Project stays same
                form.elements.date.value = date; // Date stays same
                form.elements.start.value = end; // Start defaults to previous end

                // End location defaults to HOME
                form.elements.end.value = HOME_POSTCODE;

                // Reload the page to reflect new data
                setTimeout(() => window.location.reload(), 500);
            } else {
                showToast(response.message || 'Failed to add trip.', 'bg-red-500');
            }
        });

        /**
         * Handles quick entry buttons (ASC.PeopleCare, Back Home).
         */
        async function handleQuickEntry(event, action) {
            const button = event.currentTarget;
            button.disabled = true;
            button.textContent = 'Processing...';
            
            const form = document.getElementById('trip-entry-form');
            const date = form.elements.date.value;
            const project = form.elements.project.value;
            const lastEnd = form.elements.start.value; // Current start loc is the last end loc

            const response = await postData(action, { date, project, last_end: lastEnd });

            button.disabled = false;
            // Reset button text
            if (action === 'quick_asc_trip') {
                button.textContent = 'ASC.PeopleCare (Return Trip)';
            } else if (action === 'quick_back_home') {
                const lastEndNameEl = button.querySelector('span'); // Assuming the name is in a span, though it's not.
                button.textContent = `Back Home (${lastEndNameEl ? lastEndNameEl.textContent : '...'})`; 
            }
            
            if (response.success) {
                showToast(response.message, 'bg-green-500');
                // Reload the page to reflect new data
                setTimeout(() => window.location.reload(), 500);
            } else {
                showToast(response.message || 'Quick entry failed.', 'bg-red-500');
            }
        }

        /**
         * Handles general actions like Calculate Distances, Archive, and Clear Archive.
         * @param {Event} event The DOM event from the button click.
         * @param {string} action The action to execute on the PHP backend.
         */
        async function handleAction(event, action) {
            // CRITICAL FIX: event.currentTarget reliably refers to the element the listener was attached to.
            const button = event.currentTarget; 
            const originalText = button.textContent;
            
            // Handle modal closing immediately if this button was triggered inside a modal
            if (action === 'archive_trips') {
                closeModal('archive-modal');
            } else if (action === 'clear_archive') {
                closeModal('archive-management-modal');
            }

            // Disable button and show loading text
            button.disabled = true;
            button.textContent = action.includes('calculate') ? 'Calculating...' : 'Processing...';
            
            const response = await postData(action);

            // Re-enable and reset text
            button.disabled = false;
            button.textContent = originalText;
            
            if (response.success) {
                showToast(response.message, 'bg-green-500');
                setTimeout(() => window.location.reload(), 500);
            } else {
                showToast(response.message || 'Action failed.', 'bg-red-500');
            }
        }

        /**
         * Triggers the CSV download action via direct GET request.
         */
        function downloadCSV() {
            // Use window.location.href to trigger a full page GET request for file download
            window.location.href = '<?= $_SERVER['PHP_SELF'] ?>?action=download_archive_csv';

            // Close the modal immediately for better UX
            closeModal('archive-management-modal');
        }


        /**
         * Toggles the scored state of a trip.
         */
        async function toggleScored(checkbox) {
            const id = checkbox.dataset.id;
            const response = await postData('toggle_scored', { id });
            if (response.success) {
                const row = checkbox.closest('.list-row');
                if (checkbox.checked) {
                    row.classList.add('strike-through');
                } else {
                    row.classList.remove('strike-through');
                }
            } else {
                showToast('Failed to update scored state.', 'bg-red-500');
                checkbox.checked = !checkbox.checked; // Revert change on failure
            }
        }

        /**
         * Deletes a trip entry using a custom confirmation modal.
         */
        function deleteTrip(id) {
            const message = "Are you sure you want to permanently delete this trip entry?";
            
            showCustomConfirm(message, (confirmed) => {
                if (confirmed) {
                    // User clicked 'Yes' or pressed Enter
                     postData('delete_trip', { id }).then(response => {
                        if (response.success) {
                            showToast('Trip deleted.', 'bg-green-500');
                            setTimeout(() => window.location.reload(), 300);
                        } else {
                            showToast('Failed to delete trip.', 'bg-red-500');
                        }
                    });
                } else {
                    // User clicked 'No'
                    showToast('Deletion cancelled.', 'bg-gray-500');
                }
            }, 'Confirm Deletion');
        }

        /**
         * Copies text to clipboard and shows a toast notification near the element.
         */
        function copyToClipboard(element, text) {
            if (!text || text === 'N/A') return; // Do not copy if value is N/A or null

            // Use execCommand for broader compatibility in iFrames
            const textarea = document.createElement('textarea');
            textarea.value = text;
            document.body.appendChild(textarea);
            textarea.select();
            document.execCommand('copy');
            document.body.removeChild(textarea);

            showToast(`Copied: ${text}`);
        }

        // --- MANAGEMENT POPUP LOGIC ---

        /**
         * Renders the location list in the management modal.
         */
        function renderLocationsList() {
            const list = document.getElementById('locations-list');
            list.innerHTML = '';
            // Ensure allLocations is up-to-date by using array
            const locationsArray = Array.isArray(allLocations) ? allLocations : [];
            
            locationsArray.forEach(loc => {
                const div = document.createElement('div');
                div.className = 'flex justify-between items-center bg-white p-2 rounded-lg shadow-sm';
                div.innerHTML = `
                    <span class="font-medium">${loc.name}</span>
                    <span class="text-gray-500">${loc.postcode}</span>
                    <button onclick="manageLocation('remove', '${loc.postcode}')" class="text-red-500 hover:text-red-700">&#x2715;</button>
                `;
                list.appendChild(div);
            });
        }

        /**
         * Renders the project list in the management modal.
         */
        function renderProjectsList() {
            const list = document.getElementById('projects-list');
            list.innerHTML = '';
            const projectsArray = Array.isArray(allProjects) ? allProjects : [];

            projectsArray.forEach(proj => {
                const div = document.createElement('div');
                div.className = 'flex justify-between items-center bg-white p-2 rounded-lg shadow-sm';
                div.innerHTML = `
                    <span class="font-medium">${proj}</span>
                    <button onclick="manageProject('remove', '${proj}')" class="text-red-500 hover:text-red-700">&#x2715;</button>
                `;
                list.appendChild(div);
            });
        }

        /**
         * Handles adding/removing locations via the management modal.
         */
        async function manageLocation(type, postcode = null) {
            const messageEl = document.getElementById('location-message');
            messageEl.textContent = '';
            let response;

            if (type === 'add') {
                const name = document.getElementById('add-loc-name').value.trim();
                const pc = document.getElementById('add-loc-postcode').value.trim().toUpperCase();
                response = await postData('add_location', { name, postcode: pc });
                if (response.success) {
                    document.getElementById('add-loc-name').value = '';
                    document.getElementById('add-loc-postcode').value = '';
                }
            } else if (type === 'remove') {
                response = await postData('remove_location', { postcode });
            }

            if (response.success) {
                allLocations = response.locations;
                renderLocationsList();
                showToast(response.message, 'bg-green-500');
                // Simple reload of the page will update the main form dropdowns
                setTimeout(() => window.location.reload(), 300);
            } else {
                messageEl.textContent = response.message || 'Operation failed.';
            }
        }

        /**
         * Handles adding/removing projects via the management modal.
         */
        async function manageProject(type, name = null) {
            const messageEl = document.getElementById('project-message');
            messageEl.textContent = '';
            let response;

            if (type === 'add') {
                const newName = document.getElementById('add-proj-name').value.trim();
                response = await postData('add_project', { name: newName });
                if (response.success) {
                    document.getElementById('add-proj-name').value = '';
                }
            } else if (type === 'remove') {
                response = await postData('remove_project', { name });
            }

            if (response.success) {
                allProjects = response.projects;
                renderProjectsList();
                showToast(response.message, 'bg-green-500');
                // Simple reload of the page will update the main form dropdowns
                setTimeout(() => window.location.reload(), 300);
            } else {
                messageEl.textContent = response.message || 'Operation failed.';
            }
        }

    </script>
</body>
</html>
<?php
} // <-- ADDED MISSING CLOSING BRACE FOR render_main_app FUNCTION

// Function calls must be outside the function body
if (isset($is_archive_view)) {
    render_main_app($trips_grouped, $locations, $projects, $locations_map, $is_archive_view, $form_project, $form_start_loc, $form_date, $last_end_name, $archive_is_empty);
}
?>
