<?php

namespace Tests\Feature\Audit;

use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Client;
use App\Models\Tenant\Vehicle;
use App\Models\Tenant\WorkOrder;
use App\Models\Tenant\WorkOrderWork;
use App\Services\TenantBackupService;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use ZipArchive;

class TenantBackupServiceTest extends TestCase
{
    use RefreshDatabase;

    public function test_export_produces_valid_zip_with_manifest_and_tables(): void
    {
        $company = $this->bootTenant();

        // Populate one client + vehicle + WO so the export has data.
        $c = Client::create(['name' => 'BackupOwner', 'phone' => '+37377555111', 'type' => 'individual', 'status' => 'active']);
        $v = Vehicle::create(['client_id' => $c->id, 'make' => 'BMW', 'model' => 'X5', 'plate' => 'BK-001']);
        $wo = WorkOrder::create([
            'number' => WorkOrder::generateNumber($company->id),
            'client_id' => $c->id, 'vehicle_id' => $v->id,
            'opened_at' => today(), 'status' => 'in_work',
        ]);
        WorkOrderWork::create([
            'work_order_id' => $wo->id, 'name' => 'X',
            'hours' => 1, 'price_per_hour' => 100, 'status' => 'todo',
        ]);

        $path = app(TenantBackupService::class)->export($company);
        $this->assertFileExists($path);

        // Open the zip and read manifest + clients.json.
        $zip = new ZipArchive();
        $this->assertTrue($zip->open($path) === true);

        $manifestJson = $zip->getFromName('manifest.json');
        $this->assertNotEmpty($manifestJson, 'manifest.json present');
        $manifest = json_decode($manifestJson, true);
        $this->assertEquals($company->slug, $manifest['tenant']['slug']);
        $this->assertGreaterThanOrEqual(1, $manifest['counts']['clients']);
        $this->assertGreaterThanOrEqual(1, $manifest['counts']['vehicles']);
        $this->assertGreaterThanOrEqual(1, $manifest['counts']['work_orders']);

        $clientsJson = $zip->getFromName('data/clients.json');
        $this->assertNotEmpty($clientsJson);
        $clients = json_decode($clientsJson, true);
        $this->assertEquals('BackupOwner', $clients[0]['name']);

        // Embedded WO data must include works (with-eager-loaded).
        $woJson = $zip->getFromName('data/work_orders.json');
        $wos = json_decode($woJson, true);
        $this->assertNotEmpty($wos[0]['works']);

        $zip->close();
        @unlink($path);
    }

    public function test_filename_includes_slug_and_date(): void
    {
        $company = $this->bootTenant();
        $name = app(TenantBackupService::class)->filename($company);
        $this->assertStringStartsWith('tenant-' . $company->slug . '-', $name);
        $this->assertStringEndsWith('.zip', $name);
    }

    private function bootTenant(): Company
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => 'bkup-' . uniqid(),
            'name' => 'BK Co', 'status' => 'active',
        ]);
        app(TenantManager::class)->setCurrent($company);
        return $company;
    }
}
