<?php
session_start();

require_once __DIR__ . '/../../includes/auth.php';
require_once __DIR__ . '/../../classes/Database.php';

$conn = (new Database())->getConnection();
$auth = new Auth($conn);

if (!isset($_SESSION['user_id'])) {
    header('Location: ../../login.php');
    exit;
}
$auth->enforceSuperAdminPrivileges($_SESSION['user_id']);

function exportError($message, $status = 400)
{
    http_response_code($status);
    $safeMessage = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
    echo '<!doctype html><html><head><meta charset="utf-8"><title>Expense export</title></head><body>';
    echo '<p>' . $safeMessage . '</p><p><a href="manage_expenses.php">Back to expenses</a></p>';
    echo '</body></html>';
    exit;
}

function validExportDate($value)
{
    $date = DateTime::createFromFormat('!Y-m-d', (string)$value);
    return $date && $date->format('Y-m-d') === $value;
}

function safeCsvText($value)
{
    $value = (string)$value;
    if (preg_match('/^[=+\-@\t\r]/u', $value)) {
        return "'" . $value;
    }
    return $value;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    exportError('Use the expense selection form to start an export.', 405);
}

$submittedToken = (string)($_POST['csrf_token'] ?? '');
$sessionToken = (string)($_SESSION['expense_export_csrf'] ?? '');
if ($sessionToken === '' || !hash_equals($sessionToken, $submittedToken)) {
    exportError('Your export session expired. Return to the expenses page and try again.', 403);
}

$startDate = (string)($_POST['start_date'] ?? '');
$endDate = (string)($_POST['end_date'] ?? '');
if (!validExportDate($startDate) || !validExportDate($endDate) || $startDate > $endDate) {
    exportError('Select a valid export date range.');
}

$expenseIds = array_values(array_unique(array_filter(
    array_map('intval', (array)($_POST['expense_ids'] ?? [])),
    static function ($id) {
        return $id > 0;
    }
)));

if (!$expenseIds) {
    exportError('Select at least one expense to export.');
}
if (count($expenseIds) > 5000) {
    exportError('A maximum of 5,000 expenses can be exported at once.');
}

$endExclusive = (new DateTime($endDate))->modify('+1 day')->format('Y-m-d');
$params = [
    ':start_date' => $startDate,
    ':end_date' => $endExclusive,
];
$placeholders = [];
foreach ($expenseIds as $index => $expenseId) {
    $placeholder = ':expense_' . $index;
    $placeholders[] = $placeholder;
    $params[$placeholder] = $expenseId;
}

$sql = "SELECT e.expense_id, e.expense_date, e.description, e.amount,
        COALESCE(c.category_name, 'Uncategorised') AS category_name,
        COALESCE(b.branch_name, 'Unassigned') AS branch_name,
        COALESCE(u.username, 'Unknown') AS recorded_by
    FROM operational_expenses e
    LEFT JOIN expense_categories c ON c.category_id = e.expense_category_id
    LEFT JOIN branches b ON b.branch_id = e.branch_id
    LEFT JOIN users u ON u.user_id = e.user_id
    WHERE e.expense_id IN (" . implode(',', $placeholders) . ")
      AND e.expense_date >= :start_date
      AND e.expense_date < :end_date
    ORDER BY e.expense_date, e.expense_id";

$stmt = $conn->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

if (!$rows) {
    exportError('None of the selected expenses fall within the confirmed date range.');
}

$filename = 'expenses_' . $startDate . '_to_' . $endDate . '.csv';
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');

session_write_close();

$output = fopen('php://output', 'wb');
if ($output === false) {
    exportError('The export file could not be created.', 500);
}

fwrite($output, "\xEF\xBB\xBF");
fputcsv($output, ['Expense ID', 'Date', 'Category', 'Description', 'Amount (MWK)', 'Branch', 'Recorded By']);

$total = 0.0;
foreach ($rows as $row) {
    $amount = (float)$row['amount'];
    $total += $amount;
    fputcsv($output, [
        (int)$row['expense_id'],
        date('Y-m-d', strtotime($row['expense_date'])),
        safeCsvText($row['category_name']),
        safeCsvText($row['description']),
        number_format($amount, 2, '.', ''),
        safeCsvText($row['branch_name']),
        safeCsvText($row['recorded_by']),
    ]);
}

fputcsv($output, []);
fputcsv($output, ['', '', '', 'Total', number_format($total, 2, '.', ''), '', '']);
fclose($output);
exit;
