<?php

namespace Tests\Feature;

use App\Models\Conversation;
use App\Models\Review;
use App\Models\User;
use App\Models\Worker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ReportApiTest extends TestCase
{
    use RefreshDatabase;

    protected $worker;
    protected $employer;
    protected $workerToken;
    protected $employerToken;
    protected $category;

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

        // Create category
        $this->category = \App\Models\WorkerCategory::create([
            'name' => 'Housemaid',
        ]);

        // Create worker
        $this->workerToken = 'worker-token-xyz';
        $this->worker = Worker::create([
            'name' => 'Jane Worker',
            'email' => 'jane.worker@example.com',
            'phone' => '+971500000001',
            'password' => bcrypt('password'),
            'api_token' => $this->workerToken,
            'status' => 'Available',
            'nationality' => 'Ethiopian',
            'age' => 28,
            'salary' => 1500.00,
            'availability' => 'Immediate',
            'experience' => '2 Years',
            'religion' => 'Christian',
            'bio' => 'Experienced housemaid seeking employment.',
            'category_id' => $this->category->id,
        ]);

        // Create employer user
        $this->employerToken = 'employer-token-abc';
        $this->employer = User::create([
            'name' => 'John Employer',
            'email' => 'john.employer@example.com',
            'password' => bcrypt('password'),
            'role' => 'employer',
            'api_token' => $this->employerToken,
        ]);
    }

    /**
     * Test worker can report a chat conversation.
     */
    public function test_worker_can_report_chat()
    {
        $conversation = Conversation::create([
            'employer_id' => $this->employer->id,
            'worker_id' => $this->worker->id,
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->postJson('/api/workers/report', [
            'type' => 'Chat',
            'item_id' => $conversation->id,
            'reason' => 'Inappropriate messages',
            'description' => 'The employer sent abusive messages.',
        ]);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
                'message' => 'Report submitted successfully. Our safety team will review it shortly.',
            ]);

        $this->assertDatabaseHas('moderation_reports', [
            'type' => 'Chat',
            'reported_user_name' => $this->employer->name,
            'reported_user_role' => 'Sponsor',
            'reported_by_name' => $this->worker->name,
            'reported_by_role' => 'Worker',
            'reason' => 'Inappropriate messages',
            'description' => 'The employer sent abusive messages.',
            'status' => 'Pending',
        ]);

        $this->assertDatabaseHas('audit_logs', [
            'category' => 'user_activity',
            'user' => 'Jane Worker (Worker)',
        ]);
    }

    /**
     * Test worker can report a review.
     */
    public function test_worker_can_report_review()
    {
        $review = Review::create([
            'employer_id' => $this->employer->id,
            'worker_id' => $this->worker->id,
            'rating' => 1,
            'comment' => 'Very bad attitude.',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->postJson('/api/workers/report', [
            'type' => 'Review',
            'item_id' => $review->id,
            'reason' => 'False accusation',
            'description' => 'The review contains false claims.',
        ]);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
            ]);

        $this->assertDatabaseHas('moderation_reports', [
            'type' => 'Review',
            'reported_user_name' => $this->employer->name,
            'reported_user_role' => 'Sponsor',
            'reported_by_name' => $this->worker->name,
            'reported_by_role' => 'Worker',
            'reason' => 'False accusation',
            'status' => 'Pending',
        ]);
    }

    /**
     * Test worker reporting non-existent/unauthorized review.
     */
    public function test_worker_report_invalid_review_returns_404()
    {
        // Review for a different worker
        $otherWorker = Worker::create([
            'name' => 'Other Worker',
            'email' => 'other@example.com',
            'phone' => '+971500000009',
            'password' => bcrypt('password'),
            'category_id' => $this->category->id,
            'nationality' => 'Indian',
            'age' => 30,
            'salary' => 1800.00,
            'availability' => 'Immediate',
            'experience' => '3 Years',
            'religion' => 'Hindu',
            'bio' => 'Experienced helper.',
        ]);

        $review = Review::create([
            'employer_id' => $this->employer->id,
            'worker_id' => $otherWorker->id,
            'rating' => 2,
            'comment' => 'Okay review.',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->postJson('/api/workers/report', [
            'type' => 'Review',
            'item_id' => $review->id,
            'reason' => 'Spam',
        ]);

        $response->assertStatus(404);
    }

    /**
     * Test employer can report a chat conversation.
     */
    public function test_employer_can_report_chat()
    {
        $conversation = Conversation::create([
            'employer_id' => $this->employer->id,
            'worker_id' => $this->worker->id,
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->employerToken,
        ])->postJson('/api/employers/report', [
            'type' => 'Chat',
            'item_id' => $conversation->id,
            'reason' => 'Abusive worker',
            'description' => 'Worker requested payment outside platform.',
        ]);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
            ]);

        $this->assertDatabaseHas('moderation_reports', [
            'type' => 'Chat',
            'reported_user_name' => $this->worker->name,
            'reported_user_role' => 'Worker',
            'reported_by_name' => $this->employer->name,
            'reported_by_role' => 'Sponsor',
            'reason' => 'Abusive worker',
            'status' => 'Pending',
        ]);

        $this->assertDatabaseHas('audit_logs', [
            'category' => 'user_activity',
            'user' => 'John Employer (Sponsor)',
        ]);
    }

    /**
     * Test employer can report a review.
     */
    public function test_employer_can_report_review()
    {
        $review = Review::create([
            'employer_id' => $this->employer->id,
            'worker_id' => $this->worker->id,
            'rating' => 5,
            'comment' => 'Great helper.',
        ]);

        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->employerToken,
        ])->postJson('/api/employers/report', [
            'type' => 'Review',
            'item_id' => $review->id,
            'reason' => 'Report my own review mistake',
            'description' => 'I selected wrong worker.',
        ]);

        $response->assertStatus(201);
    }

    /**
     * Test validation error on invalid input.
     */
    public function test_report_validation_errors()
    {
        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->postJson('/api/workers/report', [
            'type' => 'InvalidType',
            'item_id' => '',
            'reason' => '',
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['type', 'item_id', 'reason']);
    }

    /**
     * Test unauthenticated access.
     */
    public function test_report_endpoints_require_auth()
    {
        $response = $this->postJson('/api/workers/report', [
            'type' => 'Chat',
            'item_id' => 1,
            'reason' => 'Abuse',
        ]);

        $response->assertStatus(401);
    }

    /**
     * Test retrieving report reasons.
     */
    public function test_get_report_reasons_filtering()
    {
        // Clear reasons table and seed specific reasons for testing
        \DB::table('report_reasons')->truncate();
        \DB::table('report_reasons')->insert([
            ['reason' => 'Chat Spam', 'status' => 'Active', 'type' => 'Chat'],
            ['reason' => 'Review Abuse', 'status' => 'Active', 'type' => 'Review'],
            ['reason' => 'General Impersonation', 'status' => 'Active', 'type' => 'Both'],
            ['reason' => 'Inactive Reason', 'status' => 'Inactive', 'type' => 'Both'],
        ]);

        // 1. Worker retrieves all Active reasons
        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->getJson('/api/workers/report-reasons');

        $response->assertStatus(200)
            ->assertJsonCount(3, 'reasons')
            ->assertJsonFragment(['reason' => 'Chat Spam'])
            ->assertJsonFragment(['reason' => 'Review Abuse'])
            ->assertJsonFragment(['reason' => 'General Impersonation'])
            ->assertJsonMissing(['reason' => 'Inactive Reason']);

        // 2. Worker retrieves Chat reasons only
        $responseChat = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->getJson('/api/workers/report-reasons?type=Chat');

        $responseChat->assertStatus(200)
            ->assertJsonCount(2, 'reasons')
            ->assertJsonFragment(['reason' => 'Chat Spam'])
            ->assertJsonFragment(['reason' => 'General Impersonation'])
            ->assertJsonMissing(['reason' => 'Review Abuse']);

        // 3. Worker retrieves Review reasons only
        $responseReview = $this->withHeaders([
            'Authorization' => 'Bearer ' . $this->workerToken,
        ])->getJson('/api/workers/report-reasons?type=Review');

        $responseReview->assertStatus(200)
            ->assertJsonCount(2, 'reasons')
            ->assertJsonFragment(['reason' => 'Review Abuse'])
            ->assertJsonFragment(['reason' => 'General Impersonation'])
            ->assertJsonMissing(['reason' => 'Chat Spam']);
    }
}

