<?php

namespace Tests\Feature\SyncVehicles;

use App\Facades\Settings;
use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Setting;
use Mtc\MercuryDataModels\Vehicle;
use Tests\DatabaseTestCase;
use Tests\UserForTenant;


class CustomEndpointTest extends DatabaseTestCase
{
    use UserForTenant;

    private string $prefix;

    protected function setUp(): void
    {
        parent::setUp();

        Config::set('queue.default', 'sync');
        Settings::shouldReceive('get')->andReturn(null)->byDefault();

        Settings::shouldReceive('get')
            ->with('stock-sync-frequency')
            ->andReturn('every-hour');

        // ensures fullSync returns true
        $this->travelTo(now()->setHour(4));

        Http::preventStrayRequests();

        Setting::factory()->create([
            'config_key' => 'stock-endpoint-enabled',
            'value' => 1
        ]);

        $dealership = Dealership::factory()->create([
            'data' => ['auto-trader-location-id' => '1234'],
        ]);

        Vehicle::factory()->create([
            'dealership_id' => $dealership->id,
            'stock_provider' => 'emc-import',
            'was_recently_synced' => 0
        ]);

        Http::fake([
            'https://stockcentral.emcgroup.co.uk/stockfeed/gforces/*' => Http::response('<AddLeadResult>
                    <CustomerID>123456</CustomerID>
                    <ErrorCode>0</ErrorCode>
                    <ErrorMessage />
                </AddLeadResult>
                '),
        ]);
    }

    public function testPckLogsErrorWhenSettingConfigIsEmpty()
    {
        $this->travelTo(Carbon::create(2026, 2, 10, 10));
        Settings::shouldReceive('get')
            ->with('stock-endpoint-provider')
            ->andReturn('pck');

        Settings::shouldReceive('get')
            ->with('custom-data-feed-secrets')
            ->andReturn(json_encode([]));

        Log::shouldReceive('debug')->once();
        Log::shouldReceive('error')
            ->once();

        Artisan::call('sync:vehicles');
    }


    public function testPckReservedFeedImportMarksVehiclesReservedAndDeletesOthers()
    {
        $this->travelTo(Carbon::create(2026, 2, 10, 10));
        Settings::shouldReceive('get')
            ->with('stock-endpoint-provider')
            ->andReturn('pck');

        Settings::shouldReceive('get')
            ->with('custom-data-feed-secrets')
            ->andReturn(json_encode([
                'host' => 'sftp.example.com',
                'username' => 'user',
                'password' => 'pass',
                'homePath' => '/home/feed',
            ]));


        $reservedVin = fake()->text(16);
        $reservedVin = 'RESERVED-123';
        $notReservedVin = 'NOT-RESERVED-123';

        Vehicle::factory()->create(['vin' => $reservedVin, 'is_reserved' => 0, 'stock_provider' => 'pck']);
        Vehicle::factory()->create(['vin' => $notReservedVin, 'is_reserved' => 0, 'stock_provider' => 'pck']);

        // Mock SFTP Storage
        $csvSheet = $this->generateMockCsvContent($reservedVin, $notReservedVin);


        Settings::shouldReceive('get')
            ->with('site-logo')
            ->andReturn([
                'url' => 'https://example.com/logo.png',
            ]);

        Storage::shouldReceive('disk')->with('media')->andReturnSelf();

        Storage::shouldReceive('disk')->with('media')->andReturnSelf();
        Storage::shouldReceive('exists')->andReturn(true);
        Storage::shouldReceive('deleteDirectory')->andReturn(true);


        Storage::shouldReceive('disk')->with('sftp')->andReturnSelf();
        Storage::shouldReceive('build')->andReturnSelf();
        Storage::shouldReceive('files')->andReturn(['feed.csv']);
        Storage::shouldReceive('get')->with('feed.csv')->andReturn($csvSheet);


        Artisan::call('sync:vehicles');

        $this->assertDatabaseHas('vehicles', [
            'vin' => $reservedVin,
            'is_reserved' => 1,
        ]);

        $this->assertDatabaseHas('vehicles', [
            'vin' => $notReservedVin,
            'is_reserved' => 0,
        ]);
    }

    private function generateMockCsvContent(string $reservedVin, string $unreservedVin)
    {
        $headers = $reservedData = $unreservedData = [];

        for ($i = 1; $i <= 22; $i++) {
            $headers[] = 'col' . $i;

            if ($i == 3) {
                $reservedData[] = $reservedVin;
                $unreservedData[] = $unreservedVin;
            } else if ($i == 21) {
                $reservedData[] = 'Reserved';
                $unreservedData[] = 'Not Reserved';
            } else {
                $reservedData[] = '';
                $unreservedData[] = '';
            }
        }
        $sheet = [$headers, $reservedData, $unreservedData];

        $csv = '';
        $handle = fopen('php://temp', 'r+');
        foreach ($sheet as $row) {
            fputcsv($handle, $row);
        }
        rewind($handle);
        $csv = stream_get_contents($handle);
        fclose($handle);

        return $csv;
    }
}
