<?php

namespace Tests\Tenant;

use App\Exports\InventoryExport;
use App\Facades\Settings;
use App\Jobs\InventoryExportJob;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\SalesChannelHistory;
use Mtc\MercuryDataModels\SalesChannelRule;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleSpecType;
use Tests\TenantTestCase;

class InventoryExportTest extends TenantTestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExportJob()
    {
        Storage::fake('inventory-export');
        Vehicle::factory(10)->create();
        Settings::update('sales-channels-inventory-file-name', 'foo.csv');

        new InventoryExportJob()->handle();

        Storage::disk('inventory-export')->assertExists('foo.csv');
        $logged = SalesChannelHistory::query()
            ->where('channel', 'inventory')
            ->where('was_successful', true)
            ->exists();
        $this->assertTrue($logged);
    }

    public function testNewVehicleYearFallsBackToZeroOnlyWhenMissing()
    {
        // New with a real year keeps it; a new vehicle missing the year sends 0;
        // used vehicles are unaffected.
        Vehicle::factory()->create([
            'is_published' => true,
            'is_new' => true,
            'manufacture_year' => 2025,
            'uuid' => 'stock-new-year',
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'is_new' => true,
            'manufacture_year' => null,
            'uuid' => 'stock-new-noyear',
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'is_new' => false,
            'manufacture_year' => 2019,
            'uuid' => 'stock-used',
        ]);

        $rows = new InventoryExport()->collection()->keyBy('Stock #');

        $this->assertEquals(2025, $rows['stock-new-year']['Year']);
        $this->assertSame(0, $rows['stock-new-noyear']['Year']);
        $this->assertEquals(2019, $rows['stock-used']['Year']);
    }

    public function testNewVehicleZeroYearRendersAsZeroNotBlankInCsv()
    {
        // Guards WithStrictNullComparison: without it, Laravel Excel's loose null
        // comparison (0 == null) writes integer 0 as a blank cell in the output.
        Vehicle::factory()->create([
            'is_published' => true,
            'is_new' => true,
            'manufacture_year' => null,
            'uuid' => 'stock-new-noyear',
        ]);

        $csv = Excel::raw(new InventoryExport(), \Maatwebsite\Excel\Excel::CSV);

        $row = collect(preg_split('/\R/', $csv))
            ->first(fn ($line) => str_contains($line, 'stock-new-noyear'));
        $this->assertNotNull($row, 'Expected the new vehicle row in the rendered CSV.');

        // Column order: Dealer ID, Dealer Name, Is New, Status, Note, VIN, Stock #, Year (index 7).
        $cells = str_getcsv($row);
        $this->assertSame('0', $cells[7]);
    }

    public function testVrmMapsToExtraFieldOne()
    {
        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
            'uuid' => 'stock-vrm',
            'registration_number' => 'AY26 NBL',
            'vrm_condensed' => 'AY26NBL',
        ]);

        $rows = new InventoryExport()->collection()->keyBy('Stock #');

        $this->assertNotEmpty($rows['stock-vrm']['Extra Field 1']);
        $this->assertSame($vehicle->fresh()->vrm_condensed, $rows['stock-vrm']['Extra Field 1']);
    }

    public function testOptionDescriptionUsesEquipmentPipeDelimited()
    {
        // "Match the website": Option Description mirrors the vehicle's Equipment tab
        // (vehicle_standard_equipment), pipe-delimited so option text containing commas
        // survives as a single item.
        $vehicle = Vehicle::factory()->create([
            'is_published' => true,
            'uuid' => 'stock-equip',
        ]);
        $vehicle->equipment()->create([
            'type' => VehicleSpecType::STANDARD_EQUIPMENT->value,
            'category' => 'Driver Convenience',
            'description' => '360 degree parking sensors',
        ]);
        $vehicle->equipment()->create([
            'type' => VehicleSpecType::OPTIONAL_EQUIPMENT->value,
            'category' => 'Exterior',
            'description' => 'Metallic paint, premium',
            'price' => 650,
        ]);

        $row = new InventoryExport()->collection()->keyBy('Stock #')['stock-equip'];
        $items = explode('|', $row['Option Description']);

        $this->assertCount(2, $items);
        $this->assertContains('360 degree parking sensors', $items);
        // comma inside an item is preserved (not treated as a delimiter)
        $this->assertContains('Metallic paint, premium', $items);
    }

    public function testFiltersByDealershipIdInList()
    {
        $included = Dealership::factory()->create();
        $excluded = Dealership::factory()->create();

        Vehicle::factory()->create([
            'is_published' => true,
            'dealership_id' => $included->id,
            'uuid' => 'stock-in',
        ]);
        Vehicle::factory()->create([
            'is_published' => true,
            'dealership_id' => $excluded->id,
            'uuid' => 'stock-out',
        ]);

        SalesChannelRule::query()->create([
            'channel' => 'inventory',
            'conditions' => [[
                'value' => [
                    'type' => 'and',
                    'column' => 'dealership_id',
                    'operator' => 'in',
                    'value' => [$included->id],
                ],
            ]],
        ]);

        $stockNumbers = new InventoryExport()->collection()->pluck('Stock #');

        $this->assertTrue($stockNumbers->contains('stock-in'));
        $this->assertFalse($stockNumbers->contains('stock-out'));
    }
}
