<?php

declare(strict_types=1);

namespace Tests\Feature;

use App\Filament\Resources\Posts\Pages\EditPost;
use App\Filament\Resources\Posts\PostResource;
use App\Models\Post;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
use ReflectionClass;
use Tests\TestCase;

class PostFormInjectionTest extends TestCase
{
    use RefreshDatabase;

    public function test_post_form_includes_paid_section_from_membership_plugin(): void
    {
        $schema = Schema::make();
        PostResource::form($schema);

        // Section 的标题在 heading 而非 label
        $headings = collect($schema->getComponents())
            ->map(fn ($component) => method_exists($component, 'getHeading') ? $component->getHeading() : $component->getLabel())
            ->all();

        $this->assertContains('付费设置', $headings);

        // 找到付费设置 Section；无 Livewire 环境下用反射读取默认内容槽（childComponents 按 schema key 分组）
        $section = collect($schema->getComponents())
            ->first(fn ($component) => $component->getHeading() === '付费设置');

        $property = (new ReflectionClass($section))->getProperty('childComponents');
        $fieldNames = collect($property->getValue($section)['default'] ?? [])
            ->map(fn ($field) => $field->getName())
            ->all();

        $this->assertContains('meta.price', $fieldNames);
        $this->assertContains('meta.members_only', $fieldNames);
    }

    public function test_post_table_includes_paid_badge_column(): void
    {
        // Table 构造器要求 HasTable Livewire 组件，测试中绕过构造器
        $table = (new ReflectionClass(Table::class))->newInstanceWithoutConstructor();
        PostResource::table($table);

        $names = array_keys($table->getColumns());

        // 会员插件注入的付费徽章列（meta.members_only 承载价格/会员判定）
        $this->assertContains('meta.members_only', $names);
        $this->assertContains('title', $names);
    }

    public function test_meta_price_maps_to_post_meta_json(): void
    {
        $post = Post::create([
            'title' => '付费文章',
            'content' => '内容',
            'content_format' => 'markdown',
            'status' => 'published',
            'published_at' => now(),
            'meta' => ['price' => 9900, 'members_only' => true],
        ]);

        $this->assertSame(9900, $post->meta['price']);
        $this->assertTrue($post->meta['members_only']);
    }

    public function test_edit_post_save_preserves_other_meta_keys(): void
    {
        $post = Post::create([
            'title' => '已解锁文章',
            'slug' => 'unlocked-post',
            'content' => '内容',
            'content_format' => 'markdown',
            'status' => 'published',
            'published_at' => now(),
            'meta' => ['price' => 9900, 'members_only' => true, 'unlocked_user_ids' => [1, 2]],
        ]);

        Livewire::test(EditPost::class, ['record' => $post->getRouteKey()])
            ->call('save')
            ->assertHasNoFormErrors();

        $post->refresh();
        // 表单只含 price/members_only，保存时不得覆盖解锁用户等其他 meta 键
        $this->assertSame([1, 2], $post->meta['unlocked_user_ids']);
        $this->assertSame(9900, $post->meta['price']);
        $this->assertTrue($post->meta['members_only']);
    }
}
