<?php

namespace Tests\Feature;

use App\Models\User;
use App\Models\Proposal;
use App\Models\Contract;
use App\Models\Payment;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use Spatie\Permission\Models\Role;

class BrandProposalFullLifecycleTest extends TestCase
{
    use RefreshDatabase;

    protected $brandAdmin;
    protected $creator;

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

        // Create roles if they don't exist
        if (!Role::where('name', 'brand_admin')->where('guard_name', 'web')->exists()) {
            Role::create(['name' => 'brand_admin', 'guard_name' => 'web']);
        }
        
        if (!Role::where('name', 'creator')->where('guard_name', 'web')->exists()) {
            Role::create(['name' => 'creator', 'guard_name' => 'web']);
        }

        // Create a brand admin user
        $this->brandAdmin = User::factory()->create([
            'name' => 'Test Brand Admin',
            'email' => 'brand@test.com',
        ]);
        $this->brandAdmin->assignRole('brand_admin');

        // Create a creator user
        $this->creator = User::factory()->create([
            'name' => 'Test Creator',
            'email' => 'creator@test.com',
        ]);
        $this->creator->assignRole('creator');
    }

    public function test_proposal_full_lifecycle()
    {
        // 1. Create a proposal
        $proposal = Proposal::factory()->create([
            'brand_id' => 1,
            'creator_id' => $this->creator->id,
            'title' => 'Test Proposal',
            'message' => 'This is a test proposal message',
            'type' => 'Collaboration',
            'status' => 'sent',
        ]);

        // 2. Brand admin views proposal
        $response = $this->actingAs($this->brandAdmin)
            ->get(route('brand.proposals.show', $proposal));
        $response->assertStatus(200);
        $response->assertSee('Test Proposal');

        // 3. Brand admin accepts proposal
        $response = $this->actingAs($this->brandAdmin)
            ->put(route('brand.proposals.accept', $proposal));
        $response->assertStatus(302);
        $proposal->refresh();
        $this->assertEquals('accepted', $proposal->status);

        // 4. Create a contract for the proposal
        $contract = Contract::factory()->create([
            'proposal_id' => $proposal->id,
            'brand_id' => $proposal->brand_id,
            'creator_id' => $proposal->creator_id,
            'title' => 'Contract for ' . $proposal->title,
            'status' => 'draft',
        ]);

        // Update proposal with contract
        $proposal->update(['contract_id' => $contract->id, 'status' => 'contract_sent']);

        // 5. Creator signs contract
        $contract->update([
            'creator_signature' => 'Creator Signature',
            'creator_signed_at' => now(),
            'status' => 'signed'
        ]);

        // Update proposal status
        $proposal->update(['status' => 'contract_signed']);

        // 6. Create a payment for the proposal
        $payment = Payment::factory()->create([
            'proposal_id' => $proposal->id,
            'contract_id' => $contract->id,
            'brand_id' => $proposal->brand_id,
            'creator_id' => $proposal->creator_id,
            'amount' => $proposal->budget ?? 1000,
            'status' => 'pending',
        ]);

        // Update proposal with payment
        $proposal->update(['payment_id' => $payment->id, 'status' => 'payment_pending']);

        // 7. Process payment
        $payment->update(['status' => 'completed', 'paid_at' => now()]);

        // Update proposal status
        $proposal->update(['status' => 'payment_made']);

        // 8. Creator delivers work
        $proposal->update([
            'status' => 'delivered',
            'delivered_at' => now(),
            'delivery_notes' => 'Work has been delivered as requested.',
        ]);

        // 9. Brand admin rates and reviews
        $proposal->update([
            'rating' => 4.5,
            'review' => 'Great work! Very satisfied with the deliverables.',
        ]);

        // 10. Verify final state
        $proposal->refresh();
        $this->assertEquals('delivered', $proposal->status);
        $this->assertEquals(4.5, $proposal->rating);
        $this->assertEquals('Great work! Very satisfied with the deliverables.', $proposal->review);
        $this->assertNotNull($proposal->delivered_at);
        $this->assertNotNull($proposal->delivery_notes);
    }
}