package seed

import (
	"context"
	"fmt"
	"math/rand"
	"time"

	"quyun/v2/app/commands"
	"quyun/v2/database"
	"quyun/v2/database/fields"
	"quyun/v2/database/models"
	"quyun/v2/pkg/consts"
	"quyun/v2/providers/postgres"

	"github.com/google/uuid"
	"github.com/spf13/cast"
	"github.com/spf13/cobra"
	"go.ipao.vip/atom"
	"go.ipao.vip/atom/container"
	"go.ipao.vip/gen/types"
	"go.uber.org/dig"
	"gorm.io/gorm"
)

func defaultProviders() container.Providers {
	return commands.Default(container.Providers{
		postgres.DefaultProvider(),
		database.DefaultProvider(),
	}...)
}

func Command() atom.Option {
	return atom.Command(
		atom.Name("seed"),
		atom.Short("seed initial data"),
		atom.RunE(Serve),
		atom.Providers(defaultProviders()),
	)
}

type Service struct {
	dig.In

	DB *gorm.DB
}

func Serve(cmd *cobra.Command, args []string) error {
	return container.Container.Invoke(func(ctx context.Context, svc Service) error {
		models.SetDefault(svc.DB)
		fmt.Println("Seeding data...")

		// 1. Users
		// Creator
		creator := &models.User{
			Username: "creator",
			Phone:    "13800000001",
			Nickname: "梅派传人小林",
			Avatar:   "https://api.dicebear.com/7.x/avataaars/svg?seed=Master1",
			Balance:  10000,
			Status:   consts.UserStatusVerified,
			Roles:    types.Array[consts.Role]{consts.RoleCreator},
		}
		if err := models.UserQuery.WithContext(ctx).Create(creator); err != nil {
			fmt.Printf("Create creator failed (maybe exists): %v\n", err)
			creator, _ = models.UserQuery.WithContext(ctx).Where(models.UserQuery.Phone.Eq("13800000001")).First()
		}

		// Buyer

		buyer := &models.User{
			Username: "test",
			Phone:    "13800138000",
			Nickname: "戏迷小张",
			Avatar:   "https://api.dicebear.com/7.x/avataaars/svg?seed=Zhang",
			Balance:  5000,
			Status:   consts.UserStatusVerified,
			Roles:    types.Array[consts.Role]{consts.RoleUser},
		}
		if err := models.UserQuery.WithContext(ctx).Create(buyer); err != nil {
			fmt.Printf("Create buyer failed: %v\n", err)
			buyer, _ = models.UserQuery.WithContext(ctx).Where(models.UserQuery.Phone.Eq("13800138000")).First()
		}

		// 2. Tenant

		tenant := &models.Tenant{
			UserID: creator.ID,
			Name:   "梅派艺术工作室",
			Code:   "meipai_" + cast.ToString(rand.Intn(1000)),
			UUID:   types.UUID(uuid.New()),
			Status: consts.TenantStatusVerified,
		}
		if err := models.TenantQuery.WithContext(ctx).Create(tenant); err != nil {
			fmt.Printf("Create tenant failed: %v\n", err)
			tenant, _ = models.TenantQuery.WithContext(ctx).Where(models.TenantQuery.UserID.Eq(creator.ID)).First()
		}

		// 3. Contents
		titles := []string{
			"《锁麟囊》春秋亭 (程砚秋)", "昆曲《牡丹亭》游园惊梦", "越剧《红楼梦》葬花",
			"京剧《霸王别姬》全本实录", "京剧打击乐基础教程", "豫剧唱腔发音技巧",
			"黄梅戏《女驸马》选段", "评剧《花为媒》报花名", "秦腔《三滴血》",
			"河北梆子《大登殿》",
		}
		covers := []string{
			"https://images.unsplash.com/photo-1514306191717-452ec28c7f31?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=60",
			"https://images.unsplash.com/photo-1557683316-973673baf926?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=60",
			"https://images.unsplash.com/photo-1469571486292-0ba58a3f068b?ixlib=rb-1.2.1&auto=format&fit=crop&w=400&q=60",
		}

		for i, title := range titles {
			price := int64((i % 3) * 1000) // 0, 10.00, 20.00
			if i == 3 {
				price = 990
			} // 9.90

			c := &models.Content{
				TenantID:    tenant.ID,
				UserID:      creator.ID,
				Title:       title,
				Description: fmt.Sprintf("这是关于 %s 的详细介绍...", title),
				Genre:       "京剧",
				Status:      consts.ContentStatusPublished,
				Visibility:  consts.ContentVisibilityPublic,
				Views:       int32(rand.Intn(10000)),
				Likes:       int32(rand.Intn(1000)),
			}
			models.ContentQuery.WithContext(ctx).Create(c)
			// Price
			models.ContentPriceQuery.WithContext(ctx).Create(&models.ContentPrice{
				TenantID:    tenant.ID,
				UserID:      creator.ID,
				ContentID:   c.ID,
				PriceAmount: price,
				Currency:    "CNY",
			})

			// Asset (Cover)
			ma := &models.MediaAsset{
				TenantID:  tenant.ID,
				UserID:    creator.ID,
				Type:      consts.MediaAssetTypeImage,
				Status:    consts.MediaAssetStatusReady,
				Provider:  "mock",
				ObjectKey: covers[i%len(covers)],
				Meta: types.NewJSONType(fields.MediaAssetMeta{
					Size: 1024,
				}),
			}
			models.MediaAssetQuery.WithContext(ctx).Create(ma)

			models.ContentAssetQuery.WithContext(ctx).Create(&models.ContentAsset{
				TenantID:  tenant.ID,
				UserID:    creator.ID,
				ContentID: c.ID,
				AssetID:   ma.ID,
				Role:      consts.ContentAssetRoleCover,
			})
		}

		// 4. Coupons
		cp1 := &models.Coupon{
			TenantID:       tenant.ID,
			Title:          "新人立减券",
			Type:           "fix_amount",
			Value:          500, // 5.00
			MinOrderAmount: 1000,
			TotalQuantity:  100,
			StartAt:        time.Now().Add(-24 * time.Hour),
			EndAt:          time.Now().Add(30 * 24 * time.Hour),
		}
		models.CouponQuery.WithContext(ctx).Create(cp1)

		// Give to buyer
		models.UserCouponQuery.WithContext(ctx).Create(&models.UserCoupon{
			UserID:   buyer.ID,
			CouponID: cp1.ID,
			Status:   "unused",
		})

		// 5. Notifications
		models.NotificationQuery.WithContext(ctx).Create(&models.Notification{
			UserID:  buyer.ID,
			Type:    "system",
			Title:   "欢迎注册",
			Content: "欢迎来到曲韵平台！",
			IsRead:  false,
		})

		fmt.Println("Seed done.")
		return nil
	})
}
