<?php

declare(strict_types=1);

namespace App\Exports;

use App\Support\ImportRow;
use App\Support\Imports\ImportModule;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;

/**
 * The rows that failed, in the template's own column order, with one
 * appended column explaining why. Deliberately still shaped like the
 * template rather than a bare error list: fix the flagged cells in this same
 * file and upload it again — the extra "Import Errors" column is simply
 * ignored on the way back in, since column matching only requires the
 * template's own required columns to be present.
 */
class ImportErrorReportExport implements FromCollection, ShouldAutoSize, WithHeadings
{
    /**
     * @param  class-string<ImportModule>  $module
     * @param  Collection<int, ImportRow>  $rows
     */
    public function __construct(
        private readonly string $module,
        private readonly Collection $rows,
    ) {}

    /**
     * @return list<string>
     */
    public function headings(): array
    {
        return [...$this->module::headings(), 'Import Errors'];
    }

    /**
     * Built by appending in a loop over the same slugged keys
     * `WithHeadingRow` produced when the row was read, rather than as one
     * array literal, so a column can never silently end up in the wrong
     * position if a module's headings() ever changes order.
     *
     * @return Collection<int, non-empty-list<mixed>>
     */
    public function collection(): Collection
    {
        $keys = collect($this->module::headings())->map(fn (string $heading): string => Str::slug($heading, '_'));

        return $this->rows->map(function (ImportRow $row) use ($keys): array {
            $line = [];

            foreach ($keys as $key) {
                $line[] = $row->raw[$key] ?? null;
            }

            $line[] = implode(' ', $row->errors);

            return $line;
        });
    }
}
