<?php

namespace Tests\Feature;

use App\Models\AdminPermission;
use App\Models\AdminUser;
use App\Models\Announcement;
use App\Models\Category;
use App\Models\HomeSlider;
use App\Models\NewsletterSubscriber;
use App\Models\Product;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class MarketingFeatureTest extends TestCase
{
    use RefreshDatabase;

    public function test_customer_can_subscribe_to_newsletter(): void
    {
        $this->post('/newsletter', ['email' => 'SHOPPER@EXAMPLE.COM'])
            ->assertSessionHas('newsletter_status');

        $this->assertDatabaseHas('newsletter_subscribers', [
            'email' => 'shopper@example.com',
            'is_active' => true,
        ]);
    }

    public function test_homepage_shows_active_announcement_and_newsletter_form(): void
    {
        $category = Category::query()->create([
            'name' => 'Deals',
            'slug' => 'deals',
            'is_active' => true,
        ]);

        Product::query()->create([
            'category_id' => $category->id,
            'name' => 'Deal Product',
            'slug' => 'deal-product',
            'price' => 50,
            'stock' => 5,
            'is_active' => true,
        ]);

        Announcement::query()->create([
            'title' => 'Flash Sale Live',
            'body' => 'Limited stock available today.',
            'button_text' => 'Shop now',
            'button_url' => 'https://example.com/deals',
            'is_active' => true,
        ]);

        $this->get('/')
            ->assertOk()
            ->assertSee('Flash Sale Live')
            ->assertSee('Limited stock available today.')
            ->assertSee('name="email"', false)
            ->assertSee(route('newsletter.store'), false);
    }

    public function test_admin_can_manage_announcements_email_templates_and_subscribers(): void
    {
        $admin = $this->marketingAdmin();

        $this->actingAs($admin, 'admin')
            ->post('/admin/announcements', [
                'title' => 'Delivery Update',
                'body' => 'Orders ship within 24 hours.',
                'button_text' => 'View products',
                'button_url' => 'https://example.com/products',
                'is_active' => '1',
            ])
            ->assertRedirect(route('admin.announcements.index'));

        $this->assertDatabaseHas('announcements', [
            'title' => 'Delivery Update',
            'is_active' => true,
        ]);

        $this->actingAs($admin, 'admin')
            ->post('/admin/email-templates', [
                'name' => 'Promo Email',
                'subject' => 'New offers at 8Stores',
                'preheader' => 'Fresh deals are available.',
                'body_html' => '<h2>Shop new deals</h2><p>Limited time.</p>',
                'is_active' => '1',
            ])
            ->assertRedirect(route('admin.email-templates.index'));

        $this->assertDatabaseHas('email_templates', [
            'slug' => 'promo-email',
            'subject' => 'New offers at 8Stores',
        ]);

        $subscriber = NewsletterSubscriber::query()->create([
            'email' => 'subscriber@example.com',
            'is_active' => true,
            'subscribed_at' => now(),
        ]);

        $this->actingAs($admin, 'admin')
            ->get('/admin/newsletter-subscribers')
            ->assertOk()
            ->assertSee('subscriber@example.com');

        $this->actingAs($admin, 'admin')
            ->patch("/admin/newsletter-subscribers/{$subscriber->id}/toggle")
            ->assertSessionHas('status');

        $this->assertFalse($subscriber->fresh()->is_active);
    }

    public function test_admin_can_manage_home_sliders_and_homepage_uses_dynamic_slider(): void
    {
        Storage::fake('public');

        $admin = $this->marketingAdmin();

        $this->actingAs($admin, 'admin')
            ->post('/admin/home-sliders', [
                'title' => 'New Season Deals',
                'subtitle' => 'Fresh products are live.',
                'button_text' => 'Explore',
                'button_url' => 'https://example.com/new',
                'image' => UploadedFile::fake()->image('slider.jpg', 1400, 700),
                'sort_order' => 1,
                'is_active' => '1',
            ])
            ->assertRedirect(route('admin.home-sliders.index'));

        $slider = HomeSlider::query()->firstOrFail();

        Storage::disk('public')->assertExists($slider->image_path);

        $this->get('/')
            ->assertOk()
            ->assertSee('New Season Deals')
            ->assertSee('Fresh products are live.')
            ->assertSee('Explore')
            ->assertSee("/storage/{$slider->image_path}", false);

        $this->actingAs($admin, 'admin')
            ->patch("/admin/home-sliders/{$slider->id}/toggle")
            ->assertSessionHas('status');

        $this->assertFalse($slider->fresh()->is_active);
    }

    public function test_homepage_shows_featured_products_section(): void
    {
        $category = Category::query()->create([
            'name' => 'Featured',
            'slug' => 'featured',
            'is_active' => true,
        ]);

        Product::query()->create([
            'category_id' => $category->id,
            'name' => 'Featured Product',
            'slug' => 'featured-product',
            'price' => 120,
            'stock' => 8,
            'is_active' => true,
            'is_featured' => true,
        ]);

        Product::query()->create([
            'category_id' => $category->id,
            'name' => 'Normal Product',
            'slug' => 'normal-product',
            'price' => 90,
            'stock' => 5,
            'is_active' => true,
            'is_featured' => false,
        ]);

        $this->get('/')
            ->assertOk()
            ->assertSee('Featured products')
            ->assertSee('Featured Product');
    }

    private function marketingAdmin(): AdminUser
    {
        $admin = AdminUser::query()->create([
            'name' => 'Marketing Admin',
            'email' => 'marketing.admin@example.com',
            'password' => Hash::make('secret-password'),
            'is_active' => true,
        ]);

        $permission = AdminPermission::query()->create(['name' => 'Manage Products', 'slug' => 'products.manage']);
        $admin->permissions()->attach($permission);

        return $admin;
    }
}
