<?php

namespace Tests\Feature;

use App\Models\Brand;
use App\Models\SocialAccount;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class BrandSocialConditionalTest extends TestCase
{
    use RefreshDatabase;
    
    protected function setUp(): void
    {
        parent::setUp();
        
        // Disable role middleware for testing
        $this->withoutMiddleware();
    }

    /**
     * Test connecting a brand social account with missing token.
     *
     * @return void
     */
    public function test_connect_brand_account_with_missing_token()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Try to add manual token with missing data
        $response = $this->post(route('brand.connections.manual'), [
            'provider' => 'youtube',
            // Missing provider_user_id and access_token
        ]);

        // Should get validation errors
        $response->assertSessionHasErrors(['provider_user_id', 'access_token']);
    }

    /**
     * Test connecting a brand social account with expired token.
     *
     * @return void
     */
    public function test_connect_brand_account_with_expired_token()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Create a social account with expired token
        $account = SocialAccount::factory()->forBrand($brand->id, $brand->tenant_id)->create([
            'provider' => 'youtube',
            'token_expires_at' => now()->subDay(), // Expired yesterday
        ]);

        // Visit connections page
        $response = $this->get(route('brand.connections.index'));

        // Should see expired token status
        $response->assertSee('Token Expired');
    }

    /**
     * Test connecting a brand social account with invalid provider.
     *
     * @return void
     */
    public function test_connect_brand_account_with_invalid_provider()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Try to connect with invalid provider
        $response = $this->get(route('brand.connections.connect', ['provider' => 'invalid_provider']));

        // Should get error message
        $response->assertSessionHas('error');
        $response->assertRedirect(route('brand.connections.index'));
    }

    /**
     * Test unauthorized access to brand social account.
     *
     * @return void
     */
    public function test_unauthorized_access_to_brand_social_account()
    {
        // Create two brands
        $brand1 = Brand::factory()->create();
        $brand2 = Brand::factory()->create();

        // Create users for each brand
        $user1 = User::factory()->create([
            'brand_id' => $brand1->id,
        ]);
        $user1->assignRole('brand_admin');

        $user2 = User::factory()->create([
            'brand_id' => $brand2->id,
        ]);
        $user2->assignRole('brand_admin');

        // Create a social account for brand1
        $account = SocialAccount::factory()->forBrand($brand1->id, $brand1->tenant_id)->create([
            'provider' => 'youtube',
        ]);

        // Acting as user2 (brand2 admin)
        $this->actingAs($user2);

        // Try to access brand1's account
        $response = $this->get(route('brand.provider.show', ['provider' => 'youtube']));

        // Should get error or not find the account
        $response->assertSessionHas('error')
                 ->assertRedirect(route('brand.dashboard'));
    }

    /**
     * Test successful connection of brand social account.
     *
     * @return void
     */
    public function test_successful_brand_social_account_connection()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Add manual token
        $response = $this->post(route('brand.connections.manual'), [
            'provider' => 'youtube',
            'provider_user_id' => 'test_youtube_channel',
            'access_token' => 'test_access_token',
        ]);

        // Should be redirected with success message
        $response->assertSessionHas('success');
        $response->assertRedirect(route('brand.connections.index'));

        // Check that account was created
        $this->assertDatabaseHas('social_accounts', [
            'brand_id' => $brand->id,
            'provider' => 'youtube',
            'provider_user_id' => 'test_youtube_channel',
        ]);
    }

    /**
     * Test disconnecting a brand social account.
     *
     * @return void
     */
    public function test_disconnect_brand_social_account()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Create a social account
        $account = SocialAccount::factory()->forBrand($brand->id, $brand->tenant_id)->create([
            'provider' => 'youtube',
        ]);

        // Disconnect the account
        $response = $this->delete(route('brand.connections.destroy', $account->id));

        // Should be redirected with success message
        $response->assertSessionHas('success');
        $response->assertRedirect(route('brand.connections.index'));

        // Check that account was deleted
        $this->assertDatabaseMissing('social_accounts', [
            'id' => $account->id,
        ]);
    }

    /**
     * Test brand admin dashboard with no social accounts.
     *
     * @return void
     */
    public function test_brand_dashboard_with_no_social_accounts()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Visit dashboard
        $response = $this->get(route('brand.dashboard'));

        // Should see dashboard with no social accounts message
        $response->assertStatus(200);
        $response->assertSee('No connections found.');
    }

    /**
     * Test brand admin dashboard with social accounts.
     *
     * @return void
     */
    public function test_brand_dashboard_with_social_accounts()
    {
        // Create a brand and brand admin user
        $brand = Brand::factory()->create();
        $user = User::factory()->create([
            'brand_id' => $brand->id,
        ]);
        $user->assignRole('brand_admin');

        // Acting as brand admin
        $this->actingAs($user);

        // Create social accounts
        SocialAccount::factory()->forBrand($brand->id, $brand->tenant_id)->create([
            'provider' => 'youtube',
            'meta' => ['followers' => 1000],
        ]);

        SocialAccount::factory()->forBrand($brand->id, $brand->tenant_id)->create([
            'provider' => 'instagram',
            'meta' => ['followers' => 500],
        ]);
        
        // Create aggregate data for total followers
        \App\Models\SocialAggregate::factory()->forBrand($brand->id, $brand->tenant_id)->create([
            'key' => 'total_followers',
            'value' => 1500,
            'computed_at' => now(),
        ]);

        // Visit dashboard
        $response = $this->get(route('brand.dashboard'));

        // Should see dashboard with social account information
        $response->assertStatus(200);
        $response->assertSee('Connection Status');
        $response->assertSee('1,500'); // Total followers (1000 + 500) - formatted with commas
    }
}