<?php

namespace Tests\Feature;

use App\Models\Merchant;
use App\Models\Product;
use App\Models\ProductCategory;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use function PHPUnit\Framework\assertStringContainsString;

class AdminBusinessPagesTest extends TestCase
{
    use RefreshDatabase;

    protected function loginAsPlatformAdmin(): void
    {
        $this->seed();

        $this->post('/admin/login', [
            'email' => 'platform.admin@demo.local',
            'password' => 'Platform@123456',
        ])->assertRedirect('/admin');
    }

    public function test_admin_merchants_page_displays_site_management_content(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/merchants')
            ->assertOk()
            ->assertSee('站点管理')
            ->assertSee('新增站点')
            ->assertSee('站点列表')
            ->assertSee('创建站点');
    }

    public function test_admin_orders_page_displays_filters_and_export_entry(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/orders?status=shipped&payment_status=paid&platform=wechat_mini&device_type=mini-program&payment_channel=wechat_pay&min_pay_amount=180&max_pay_amount=190&sort=pay_amount_desc')
            ->assertOk()
            ->assertSee('订单监控')
            ->assertSee('筛选条件')
            ->assertSee('导出 CSV')
            ->assertSee('当前筛选摘要')
            ->assertSee('运营关注项')
            ->assertSee('当前信号')
            ->assertSee('工作台导航')
            ->assertSee('已发货')
            ->assertSee('已支付')
            ->assertSee('微信小程序')
            ->assertSee('小程序环境')
            ->assertSee('微信支付')
            ->assertSee('订单汇总');
    }

    public function test_admin_order_operations_focus_can_follow_current_filters(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/orders?platform=wechat_mini&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦微信小程序订单，建议优先关注下单到支付转化是否顺畅，并同步排查小程序端支付回流体验。')
            ->assertSee('继续查看微信小程序订单');

        $this->get('/admin/orders?payment_channel=wechat_pay&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦微信支付订单，建议优先核对支付成功率、回调稳定性与失败重试转化。')
            ->assertSee('继续查看微信支付订单');

        $this->get('/admin/orders?device_type=mini-program&payment_status=failed&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦小程序环境订单，建议优先核对授权链路、支付唤起表现与下单回流是否顺畅。')
            ->assertSee('继续查看小程序环境订单');

        $this->get('/admin/orders?device_type=mobile-webview&payment_status=failed&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦微信内网页订单，建议优先关注授权静默登录、页面跳转稳定性与支付拉起后的回流体验。')
            ->assertSee('继续查看微信内网页订单');

        $this->get('/admin/orders?device_type=mobile&payment_status=failed&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦移动浏览器订单，建议优先关注 H5 下单链路、页面加载稳定性与支付转化流失点。')
            ->assertSee('继续查看移动浏览器订单');

        $this->get('/admin/orders?device_type=desktop&payment_status=failed&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦桌面浏览器订单，建议优先关注 PC 端下单流程、页面首屏稳定性与高客单转化表现。')
            ->assertSee('继续查看桌面浏览器订单');

        $this->get('/admin/orders?payment_status=failed&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦支付失败订单，建议优先排查支付渠道、回调结果与用户重试情况。')
            ->assertSee('继续查看支付失败订单');

        $this->get('/admin/orders?status=completed&sort=latest')
            ->assertOk()
            ->assertSee('当前正在查看已完成订单，建议复盘高客单成交与复购来源，沉淀更稳定的转化路径。')
            ->assertSee('继续查看已完成订单');
    }

    public function test_admin_products_page_displays_import_and_history_entries(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/products?status=published&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('商品巡检')
            ->assertSee('批量导入商品')
            ->assertSee('下载导入模板')
            ->assertSee('导出 CSV')
            ->assertSee('导入历史')
            ->assertSee('导入历史摘要')
            ->assertSee('当前筛选摘要')
            ->assertSee('运营关注项')
            ->assertSee('当前信号')
            ->assertSee('工作台导航')
            ->assertSee('已上架')
            ->assertSee('价格从高到低');
    }

    public function test_admin_product_operations_focus_can_follow_current_filters(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/products?status=draft&sort=latest')
            ->assertOk()
            ->assertSee('当前正在查看草稿商品，建议优先补齐标题、分类、价格与库存后再安排上架。')
            ->assertSee('继续查看当前草稿');

        $this->get('/admin/products?status=published&min_stock=0&max_stock=20&sort=stock_asc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架库存视角，建议优先确认低库存补货节奏，并同步观察高库存结构是否健康。')
            ->assertSee('继续查看当前库存视角');

        $this->get('/admin/products?status=published&category_id=1&keyword=%E6%BC%94%E7%A4%BA&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架的“演示店铺 / 默认分类”分类下关键词“演示”命中的价格带 ¥150.00 ~ ¥220.00 商品，建议优先核对在售商品命名、分类承接、价格梯度与站点承接是否一致，并同步观察库存结构与站点覆盖是否健康。')
            ->assertSee('继续查看当前已上架分类关键词价格带商品')
            ->assertSee('去看当前已上架分类关键词商品');

        $this->get('/admin/products?status=published&category_id=1&keyword=%E6%BC%94%E7%A4%BA&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架的“演示店铺 / 默认分类”分类下关键词“演示”命中的商品，建议优先核对在售商品命名、分类承接与站点承接是否一致，并同步观察价格带、库存结构与站点覆盖是否健康。')
            ->assertSee('继续查看当前已上架分类关键词商品');

        $this->get('/admin/products?status=published&category_id=1&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架的“演示店铺 / 默认分类”分类下价格带 ¥150.00 ~ ¥220.00 商品，建议优先核对该分类在售商品的价格结构、库存分布与站点覆盖是否协调。')
            ->assertSee('继续查看当前已上架分类价格带商品');

        $this->get('/admin/products?status=published&keyword=%E6%BC%94%E7%A4%BA&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架商品中关键词“演示”命中的价格带 ¥150.00 ~ ¥220.00 结果，建议优先核对在售商品命名、卖点表达与价格梯度是否一致，并同步观察库存结构、站点承接与站点覆盖是否健康。')
            ->assertSee('继续查看当前已上架关键词价格带商品')
            ->assertSee('去看当前已上架关键词商品');

        $this->get('/admin/products?status=published&keyword=%E6%BC%94%E7%A4%BA&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架商品中关键词“演示”命中的结果，建议优先核对在售商品命名、卖点表达与站点承接是否一致，并同步观察价格带、库存结构与站点覆盖是否健康。')
            ->assertSee('继续查看当前已上架关键词商品');

        $this->get('/admin/products?category_id=1&keyword=%E6%BC%94%E7%A4%BA&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦“演示店铺 / 默认分类”分类下关键词“演示”命中的价格带 ¥150.00 ~ ¥220.00 商品，建议优先核对分类承接、命名卖点与价格梯度是否一致，并同步观察库存结构、站点承接与站点覆盖是否健康。')
            ->assertSee('继续查看当前分类关键词价格带商品')
            ->assertSee('去看当前分类关键词商品');

        $this->get('/admin/products?category_id=1&keyword=%E6%BC%94%E7%A4%BA&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦“演示店铺 / 默认分类”分类下关键词“演示”命中的商品，建议优先核对分类承接、命名卖点与站点承接是否一致，并同步观察相关商品的价格带、库存结构与站点覆盖。')
            ->assertSee('继续查看当前分类关键词商品');

        $this->get('/admin/products?status=published&category_id=1&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦已上架的“演示店铺 / 默认分类”分类商品，建议优先核对该分类在售商品的价格带、库存结构与站点覆盖是否均衡。')
            ->assertSee('继续查看当前已上架分类商品');

        $this->get('/admin/products?category_id=1&min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦“演示店铺 / 默认分类”分类下价格带 ¥150.00 ~ ¥220.00 商品，建议优先核对该分类价格结构是否连贯，并同步观察库存分布、转化表现与站点覆盖是否健康。')
            ->assertSee('继续查看当前分类价格带商品');

        $this->get('/admin/products?category_id=1&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦“演示店铺 / 默认分类”分类商品，建议优先核对分类承接是否准确，并同步观察价格带、库存结构与站点覆盖是否均衡。')
            ->assertSee('继续查看当前分类商品');

        $this->get('/admin/products?keyword=%E6%BC%94%E7%A4%BA&sort=latest')
            ->assertOk()
            ->assertSee('当前筛选已聚焦关键词“演示”命中的商品，建议优先核对命名、卖点与站点承接是否一致，并同步观察相关商品的价格带与库存结构。')
            ->assertSee('继续查看当前关键词商品');

        $this->get('/admin/products?min_price=150&max_price=220&sort=price_desc')
            ->assertOk()
            ->assertSee('当前筛选已聚焦价格带 ¥150.00 ~ ¥220.00 商品，建议优先核对定价梯度是否连贯，并同步观察库存结构、转化表现与站点覆盖是否匹配。')
            ->assertSee('继续查看当前价格带商品');
    }

    public function test_admin_import_histories_page_displays_filter_and_export_entries(): void
    {
        $this->loginAsPlatformAdmin();

        $this->get('/admin/products/import-histories')
            ->assertOk()
            ->assertSee('商品导入历史')
            ->assertSee('筛选导入历史')
            ->assertSee('导出 CSV');
    }

    public function test_admin_product_summary_stats_match_export_summary_for_same_filters(): void
    {
        $this->loginAsPlatformAdmin();

        $page = $this->get('/admin/products?merchant_id=1&keyword=%E6%BC%94%E7%A4%BA%E5%95%86%E5%93%81&status=published&min_price=150&max_price=220');
        $page->assertOk()->assertViewHas('summaryStats', function (array $summaryStats) {
            return ($summaryStats['total_products'] ?? null) === 1
                && ($summaryStats['total_stock'] ?? null) === 100
                && (float) ($summaryStats['total_stock_value'] ?? 0) === 19900.0
                && (float) ($summaryStats['average_price'] ?? 0) === 199.0;
        });

        $export = $this->get('/admin/products/export?merchant_id=1&keyword=%E6%BC%94%E7%A4%BA%E5%95%86%E5%93%81&status=published&min_price=150&max_price=220');
        $export->assertOk();
        $content = $export->streamedContent();

        assertStringContainsString('导出信息,总台商品导出', $content);
        assertStringContainsString('站点,"1 / 演示店铺"', $content);
        assertStringContainsString('状态,已上架', $content);
        assertStringContainsString('最低价格,¥150.00', $content);
        assertStringContainsString('最高价格,¥220.00', $content);
        assertStringContainsString('导出商品数,1', $content);
        assertStringContainsString('导出总库存,100', $content);
        assertStringContainsString('导出总货值,19900.00', $content);
        assertStringContainsString('导出平均售价,199.00', $content);
        assertStringContainsString('演示商品', $content);
    }

    public function test_admin_order_summary_stats_match_export_summary_for_same_filters(): void
    {
        $this->loginAsPlatformAdmin();

        $page = $this->get('/admin/orders?status=shipped&payment_status=paid&platform=wechat_mini&device_type=mini-program&payment_channel=wechat_pay&min_pay_amount=180&max_pay_amount=190');
        $page->assertOk()->assertViewHas('summaryStats', function (array $summaryStats) {
            return ($summaryStats['total_orders'] ?? null) === 1
                && (float) ($summaryStats['total_pay_amount'] ?? 0) === 189.0
                && (float) ($summaryStats['average_order_amount'] ?? 0) === 189.0
                && ($summaryStats['paid_orders'] ?? null) === 1
                && ($summaryStats['failed_payment_orders'] ?? null) === 0;
        });

        $export = $this->get('/admin/orders/export?status=shipped&payment_status=paid&platform=wechat_mini&device_type=mini-program&payment_channel=wechat_pay&min_pay_amount=180&max_pay_amount=190');
        $export->assertOk();
        $content = $export->streamedContent();

        assertStringContainsString('导出信息,总台订单导出', $content);
        assertStringContainsString('订单状态,已发货', $content);
        assertStringContainsString('支付状态,已支付', $content);
        assertStringContainsString('平台,微信小程序', $content);
        assertStringContainsString('设备类型,小程序环境', $content);
        assertStringContainsString('支付渠道,微信支付', $content);
        assertStringContainsString('最低实付金额,¥180.00', $content);
        assertStringContainsString('最高实付金额,¥190.00', $content);
        assertStringContainsString('导出订单数,1', $content);
        assertStringContainsString('导出实付总额,189.00', $content);
        assertStringContainsString('导出平均客单价,189.00', $content);
        assertStringContainsString('导出已支付订单数,1', $content);
        assertStringContainsString('导出支付失败订单,0', $content);
        assertStringContainsString('ORD202603080003', $content);
    }

    public function test_admin_products_batch_status_update_changes_selected_products(): void
    {
        $this->loginAsPlatformAdmin();

        $products = Product::query()->orderBy('id')->take(2)->get();

        $this->post('/admin/products/batch', [
            'product_ids' => $products->pluck('id')->all(),
            'action' => 'change_status',
            'status' => 'offline',
        ])->assertRedirect('/admin/products')
            ->assertSessionHas('success', '批量操作已完成，本次更新 2 条商品。');

        foreach ($products as $product) {
            $this->assertSame('offline', $product->fresh()->status);
        }
    }

    public function test_admin_products_batch_change_category_blocks_cross_merchant_operation(): void
    {
        $this->loginAsPlatformAdmin();

        $secondMerchant = Merchant::query()->create([
            'name' => '第二站点',
            'slug' => 'merchant-2-demo',
            'domain' => null,
            'contact_name' => '测试人',
            'contact_phone' => '13800000001',
            'contact_email' => 'merchant2@example.com',
            'plan' => 'basic',
            'status' => 'active',
            'activated_at' => now(),
            'settings' => ['currency' => 'CNY'],
        ]);

        $secondCategory = ProductCategory::query()->create([
            'merchant_id' => $secondMerchant->id,
            'name' => '第二站点分类',
            'slug' => 'merchant-2-default',
            'status' => 'active',
            'sort' => 10,
            'description' => '用于跨商家分类拦截测试',
        ]);

        $secondProduct = Product::query()->create([
            'merchant_id' => $secondMerchant->id,
            'category_id' => $secondCategory->id,
            'title' => '第二站点商品',
            'slug' => 'merchant-2-product',
            'sku' => 'SKU-MERCHANT-2-001',
            'summary' => '用于跨商家批量改分类测试',
            'content' => 'test',
            'price' => 88,
            'original_price' => 99,
            'stock' => 10,
            'status' => 'published',
            'images' => [],
        ]);

        $firstProduct = Product::query()->orderBy('id')->firstOrFail();
        $firstMerchantCategory = ProductCategory::query()->where('merchant_id', $firstProduct->merchant_id)->orderBy('id')->firstOrFail();

        $response = $this->from('/admin/products')->post('/admin/products/batch', [
            'product_ids' => [$firstProduct->id, $secondProduct->id],
            'action' => 'change_category',
            'category_id' => $firstMerchantCategory->id,
        ]);

        $response->assertRedirect('/admin/products');
        $response->assertSessionHasErrors(['category_id']);
        $this->assertStringContainsString('所选分类不属于商家 #', session('errors')->first('category_id'));

        $this->assertSame($secondCategory->id, $secondProduct->fresh()->category_id);
    }
}
