package meta_test

import (
	"context"
	"database/sql"
	"os"
	"testing"
	"time"

	"aijianzhan/platform/internal/blueprint"
	"aijianzhan/platform/internal/meta"

	_ "github.com/lib/pq"
)

func testDSN(t *testing.T) string {
	t.Helper()
	dsn := os.Getenv("PLATFORM_TEST_DSN")
	if dsn == "" {
		dsn = "postgres://platform:platform@127.0.0.1:5432/platform?sslmode=disable"
	}
	return dsn
}

func TestPostgresMetaPersist(t *testing.T) {
	db, err := sql.Open("postgres", testDSN(t))
	if err != nil {
		t.Skip(err)
	}
	if err := db.Ping(); err != nil {
		t.Skip(err)
	}
	defer db.Close()

	ctx := context.Background()
	if err := meta.EnsureSchema(ctx, db); err != nil {
		t.Fatal(err)
	}

	store := meta.NewPostgresStore(db)
	slug := "meta_persist_demo"
	tenantID := int64(99001)
	_, _ = db.ExecContext(ctx, `DELETE FROM platform_meta.tenant_apps WHERE tenant_id=$1 AND slug=$2`, tenantID, slug)

	n := false
	bp := &blueprint.Blueprint{
		Version: "1.0",
		Meta:    blueprint.Meta{Name: "持久化测试", Slug: slug, Locale: "zh-CN"},
		Storage: blueprint.Storage{Mode: "schema_per_app", Engine: "postgres", SchemaName: "app_t99001_meta_persist_demo"},
		Entities: []blueprint.Entity{{
			Name: "item", Table: "item", Label: "Item", PrimaryKey: "id",
			Fields: []blueprint.Field{
				{Name: "id", Type: "bigint", Label: "ID", Nullable: &n},
				{Name: "title", Type: "string", Label: "标题", Nullable: &n, MaxLength: 64},
			},
		}},
		Apis: blueprint.Apis{
			BasePath: "/api/v1/apps/" + slug,
			Resources: []blueprint.APIResource{{
				Entity: "item", Path: "/items",
				Operations: []string{"list", "get", "create"},
			}},
		},
		Pages: []blueprint.Page{{
			ID: "list", Title: "列表", Route: "/items", Type: "list", Entity: "item",
		}},
		Security: blueprint.Security{
			Visibility: "private",
			Roles: []blueprint.Role{{
				Name: "管理员", Permissions: []string{"读取模块", "写入模块", "发布模块", "新增数据", "查询数据"},
			}},
			RowPolicies: []blueprint.RowPolicy{{Entity: "item", Rule: "tenant_isolated"}},
		},
	}

	rec := &meta.AppRecord{
		AppID:      "11111111-1111-1111-1111-111111111111",
		TenantID:   tenantID,
		Slug:       slug,
		Name:       bp.Meta.Name,
		SchemaName: bp.Storage.SchemaName,
		Engine:     "postgres",
		Status:     meta.StatusPublished,
		Blueprint:  bp,
		DDL:        []string{"SELECT 1"},
		Endpoints:  []string{"GET /api/v1/apps/" + slug + "/items"},
		CreatedAt:  time.Now().UTC(),
		UpdatedAt:  time.Now().UTC(),
	}
	if err := store.Save(ctx, rec); err != nil {
		t.Fatal(err)
	}

	got, err := store.GetBySlug(ctx, tenantID, slug)
	if err != nil {
		t.Fatal(err)
	}
	if got.Status != meta.StatusPublished || got.Blueprint == nil || got.Blueprint.Meta.Name != "持久化测试" {
		t.Fatalf("unexpected record: %+v", got)
	}

	ref, err := store.ResolveResource(ctx, tenantID, slug, "items")
	if err != nil {
		t.Fatal(err)
	}
	if ref.Entity.Name != "item" {
		t.Fatalf("entity=%s", ref.Entity.Name)
	}

	// 二次 Save 应保留 app_id
	rec.Name = "持久化测试-更新"
	rec.AppID = "22222222-2222-2222-2222-222222222222"
	if err := store.Save(ctx, rec); err != nil {
		t.Fatal(err)
	}
	got2, err := store.GetBySlug(ctx, tenantID, slug)
	if err != nil {
		t.Fatal(err)
	}
	if got2.AppID != "11111111-1111-1111-1111-111111111111" {
		t.Fatalf("app_id should be preserved, got %s", got2.AppID)
	}
	if got2.Name != "持久化测试-更新" {
		t.Fatalf("name not updated: %s", got2.Name)
	}
}
