<?php

declare(strict_types=1);

namespace App\Exports;

use App\Models\Asset;
use Illuminate\Database\Eloquent\Builder;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

/**
 * The asset register as a spreadsheet.
 *
 * Honours the same `Asset::filter()` scope the listing uses, so "export"
 * always means "export what I am currently looking at" — never a silent
 * full-table dump that disagrees with the screen it was requested from.
 *
 * When `$onlyIds` is given (the "Export Selected" bulk action) it takes over
 * entirely: a deliberate row selection is never narrowed further by whatever
 * filters happen to still be in the address bar.
 */
class AssetsExport implements FromQuery, ShouldAutoSize, WithHeadings, WithMapping
{
    /**
     * @param  array<string, mixed>  $filters
     * @param  array<int, int>|null  $onlyIds
     */
    public function __construct(
        private readonly array $filters = [],
        private readonly ?array $onlyIds = null,
    ) {}

    public function query(): Builder
    {
        return Asset::query()
            ->with(['category', 'location', 'team'])
            ->when(
                $this->onlyIds !== null,
                fn (Builder $query) => $query->whereIn('id', $this->onlyIds ?? []),
                fn (Builder $query) => $query->filter($this->filters),
            )
            ->orderBy('asset_tag');
    }

    /**
     * @return array<int, string>
     */
    public function headings(): array
    {
        return [
            'Asset Tag',
            'Name',
            'Category',
            'Manufacturer',
            'Model',
            'Serial Number',
            'MAC Address',
            'Status',
            'Condition',
            'Location',
            'Team',
            'Purchase Date',
            'Purchase Cost',
            'Currency',
            'Vendor',
            'Invoice Number',
            'PO Number',
        ];
    }

    /**
     * @param  Asset  $asset
     * @return array<int, mixed>
     */
    public function map($asset): array
    {
        return [
            $asset->asset_tag,
            $asset->name,
            $asset->category?->name,
            $asset->manufacturer,
            $asset->model,
            $asset->serial_number,
            $asset->mac_address,
            $asset->status->label(),
            $asset->condition->label(),
            $asset->location?->name,
            $asset->team?->name,
            $asset->purchase_date?->format('Y-m-d'),
            $asset->purchase_cost,
            $asset->currency,
            $asset->vendor,
            $asset->invoice_number,
            $asset->po_number,
        ];
    }
}
