<?php

namespace Tests\Feature;

use App\Models\Visitor;
use App\Http\Middleware\LogVisitor;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Livewire\Livewire;
use Tests\TestCase;

class WebAnalyticsTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function log_visitor_middleware_tracks_page_views_and_durations()
    {
        $middleware = new LogVisitor();
        
        // 1. First visit (creates new record)
        $request1 = Request::create('/', 'GET');
        $request1->server->set('REMOTE_ADDR', '192.168.1.100');
        
        $response = $middleware->handle($request1, function () {
            return new Response();
        });

        $this->assertEquals(1, Visitor::count());
        $visitor = Visitor::first();
        $this->assertEquals('192.168.1.100', $visitor->ip_address);
        $this->assertEquals(1, $visitor->page_views);
        $this->assertEquals(0, $visitor->session_duration);
        $this->assertEquals('direct', $visitor->source);

        // 2. Second visit (updates existing record)
        $request2 = Request::create('/about', 'GET');
        $request2->server->set('REMOTE_ADDR', '192.168.1.100');
        
        // Mock time passing by manual update in DB or just calling middleware again
        // Here we just verify page_views increment
        $middleware->handle($request2, function () {
            return new Response();
        });

        $this->assertEquals(1, Visitor::count());
        $visitor->refresh();
        $this->assertEquals(2, $visitor->page_views);
    }

    /** @test */
    public function web_analytics_component_calculates_metrics_correctly()
    {
        // Seed test visitor records
        Visitor::create([
            'ip_address' => '1.1.1.1',
            'source' => 'direct',
            'page_views' => 5,
            'session_duration' => 120,
            'created_at' => now(),
        ]);

        Visitor::create([
            'ip_address' => '2.2.2.2',
            'source' => 'searchengine',
            'page_views' => 1,
            'session_duration' => 0,
            'created_at' => now(),
        ]);

        Livewire::test(\App\Livewire\WebAnalytics::class)
            ->assertSet('metrics.visitors', 2)
            ->assertSet('metrics.pageViews', 6)
            ->assertSet('metrics.bounceRate', 50.0)
            ->assertSet('metrics.avgSessionDuration', '2m 0s');
    }

    /** @test */
    public function can_download_filtered_pdf_report()
    {
        $this->withoutMiddleware();

        Visitor::create([
            'ip_address' => '1.1.1.1',
            'source' => 'direct',
            'page_views' => 5,
            'session_duration' => 120,
            'created_at' => now(),
        ]);

        $response = $this->get(route('admin.analytics.download-pdf', [
            'start_date' => now()->subDays(1)->format('Y-m-d'),
            'end_date' => now()->addDays(1)->format('Y-m-d'),
            'filter' => 'daily'
        ]));

        $response->assertStatus(200);
        $this->assertEquals('application/pdf', $response->headers->get('content-type'));
    }

    /** @test */
    public function can_access_product_performance_report_with_filters()
    {
        $this->withoutMiddleware();

        $user = \App\Models\User::create([
            'name' => 'Test Admin',
            'email' => 'testadmin@example.com',
            'password' => bcrypt('password'),
            'status' => 1,
        ]);
        $this->actingAs($user);

        $category = \App\Models\Category::create([
            'category_name' => 'Test Category',
            'category_image' => 'test.jpg',
            'status' => 1,
        ]);

        $product = \App\Models\Product::create([
            'product_name' => 'Test Product',
            'product_tags' => 'test',
            'sku' => 'TEST-SKU',
            'product_image' => 'test.jpg',
            'product_price' => 100.00,
            'category_id' => $category->id,
            'weight' => 500,
            'status' => 1,
        ]);

        // Create some product views
        \App\Models\ProductView::create([
            'product_id' => $product->id,
            'ip_address' => '127.0.0.1',
            'created_at' => now(),
        ]);

        // Create an order
        \App\Models\Order::create([
            'order_id' => 'ORD-123',
            'userid' => 1,
            'zone_id' => 1,
            'product_id' => $product->id,
            'first_name' => 'Test',
            'last_name' => 'User',
            'email' => 'test@example.com',
            'telephone' => '1234567890',
            'address_1' => 'Test Address',
            'city' => 'Test City',
            'district' => 'Test District',
            'totalweight' => 500,
            'quantity' => 2,
            'service_fee' => 0.00,
            'total' => 200.00,
            'payment_method' => 'COD',
            'status' => 1,
            'created_at' => now(),
        ]);

        // 1. Test sales report
        $responseSales = $this->get(route('admin.analytics.products-report', [
            'type' => 'sales',
            'filter' => 'daily',
        ]));
        $responseSales->assertStatus(200);
        $responseSales->assertViewHas('products');
        $this->assertEquals(2, $responseSales->viewData('products')->first()->total_sold);

        // 2. Test views report
        $responseViews = $this->get(route('admin.analytics.products-report', [
            'type' => 'productview',
            'filter' => 'daily',
        ]));
        $responseViews->assertStatus(200);
        $responseViews->assertViewHas('products');
        $this->assertEquals(1, $responseViews->viewData('products')->first()->view_count);

        // 3. Test Excel export
        $responseExport = $this->get(route('admin.analytics.products-report.export', [
            'type' => 'sales',
            'filter' => 'daily',
        ]));
        $responseExport->assertStatus(200);
        $responseExport->assertHeader('content-disposition', 'attachment; filename=product_performance_report_sales_' . now()->subDays(30)->format('Ymd') . '_to_' . now()->format('Ymd') . '.xlsx');
    }

    /** @test */
    public function preset_filter_ignores_custom_dates_parameters()
    {
        $this->withoutMiddleware();

        $user = \App\Models\User::create([
            'name' => 'Test Admin',
            'email' => 'testadmin2@example.com',
            'password' => bcrypt('password'),
            'status' => 1,
        ]);
        $this->actingAs($user);

        // When requesting 'daily' preset but also passing unrelated custom dates:
        $response = $this->get(route('admin.analytics.products-report', [
            'type' => 'sales',
            'filter' => 'daily',
            'start_date' => '2000-01-01',
            'end_date' => '2000-01-31',
        ]));

        $response->assertStatus(200);
        $response->assertViewHas('filter', 'daily');
        $response->assertViewHas('start_date', now()->subDays(30)->format('Y-m-d'));
        $response->assertViewHas('end_date', now()->format('Y-m-d'));
    }

    /** @test */
    public function performance_report_can_be_filtered_by_product_name_search()
    {
        $this->withoutMiddleware();

        $user = \App\Models\User::create([
            'name' => 'Test Admin',
            'email' => 'testadmin3@example.com',
            'password' => bcrypt('password'),
            'status' => 1,
        ]);
        $this->actingAs($user);

        $category = \App\Models\Category::create([
            'category_name' => 'Test Category',
            'category_image' => 'test.jpg',
            'status' => 1,
        ]);

        $product1 = \App\Models\Product::create([
            'product_name' => 'Alpha Product',
            'product_tags' => 'test',
            'sku' => 'SKU-ALPHA',
            'product_image' => 'test.jpg',
            'product_price' => 100.00,
            'category_id' => $category->id,
            'weight' => 500,
            'status' => 1,
        ]);

        $product2 = \App\Models\Product::create([
            'product_name' => 'Beta Product',
            'product_tags' => 'test',
            'sku' => 'SKU-BETA',
            'product_image' => 'test.jpg',
            'product_price' => 150.00,
            'category_id' => $category->id,
            'weight' => 500,
            'status' => 1,
        ]);

        // Search for 'Alpha'
        $response = $this->get(route('admin.analytics.products-report', [
            'search' => 'Alpha',
        ]));

        $response->assertStatus(200);
        $products = $response->viewData('products');
        $this->assertEquals(1, $products->total());
        $this->assertEquals('Alpha Product', $products->first()->product_name);

        // Search by SKU 'BETA'
        $response2 = $this->get(route('admin.analytics.products-report', [
            'search' => 'BETA',
        ]));

        $response2->assertStatus(200);
        $products2 = $response2->viewData('products');
        $this->assertEquals(1, $products2->total());
        $this->assertEquals('Beta Product', $products2->first()->product_name);
    }
}


