<?php

namespace App\Support;

use Symfony\Component\HttpFoundation\StreamedResponse;

class CsvExport
{
    /**
     * Stream a CSV download. $rows is any iterable of associative or ordered
     * arrays; $headers are the column titles written as the first line.
     *
     * @param  array<int,string>  $headers
     * @param  iterable<int,array>  $rows
     */
    public static function stream(string $filename, array $headers, iterable $rows): StreamedResponse
    {
        $filename = preg_replace('/[^A-Za-z0-9._-]/', '_', $filename) ?: 'export.csv';

        return response()->streamDownload(function () use ($headers, $rows) {
            $handle = fopen('php://output', 'w');

            // UTF-8 BOM so Excel renders accented characters correctly.
            fwrite($handle, "\xEF\xBB\xBF");

            if ($headers) {
                fputcsv($handle, $headers);
            }

            foreach ($rows as $row) {
                fputcsv($handle, array_map(static function ($value) {
                    if (is_array($value)) {
                        return json_encode($value);
                    }

                    if ($value instanceof \DateTimeInterface) {
                        return $value->format('Y-m-d H:i:s');
                    }

                    return $value;
                }, (array) $row));
            }

            fclose($handle);
        }, $filename, [
            'Content-Type' => 'text/csv; charset=UTF-8',
        ]);
    }
}
