package postgres

import (
	"context"
	"testing"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/tests/testutils"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestOrderItemStore_BatchCreate(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)
	orderStore := NewOrderStore(tx, rdb)
	itemStore := NewOrderItemStore(tx, rdb)
	ctx := context.Background()

	order := &model.Order{
		OrderNo:       orderStore.GenerateOrderNo(),
		OrderType:     model.OrderTypeSingleCard,
		BuyerType:     model.BuyerTypePersonal,
		BuyerID:       100,
		TotalAmount:   15000,
		PaymentStatus: model.PaymentStatusPending,
	}
	require.NoError(t, orderStore.Create(ctx, order, nil))

	items := []*model.OrderItem{
		{OrderID: order.ID, PackageID: 1, PackageName: "套餐A", Quantity: 1, UnitPrice: 5000, Amount: 5000},
		{OrderID: order.ID, PackageID: 2, PackageName: "套餐B", Quantity: 2, UnitPrice: 5000, Amount: 10000},
	}

	err := itemStore.BatchCreate(ctx, items)
	require.NoError(t, err)

	for _, item := range items {
		assert.NotZero(t, item.ID)
		assert.Equal(t, order.ID, item.OrderID)
	}
}

func TestOrderItemStore_BatchCreate_Empty(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)
	itemStore := NewOrderItemStore(tx, rdb)
	ctx := context.Background()

	err := itemStore.BatchCreate(ctx, nil)
	require.NoError(t, err)

	err = itemStore.BatchCreate(ctx, []*model.OrderItem{})
	require.NoError(t, err)
}

func TestOrderItemStore_ListByOrderID(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)
	orderStore := NewOrderStore(tx, rdb)
	itemStore := NewOrderItemStore(tx, rdb)
	ctx := context.Background()

	order := &model.Order{
		OrderNo:       orderStore.GenerateOrderNo(),
		OrderType:     model.OrderTypeDevice,
		BuyerType:     model.BuyerTypeAgent,
		BuyerID:       200,
		TotalAmount:   20000,
		PaymentStatus: model.PaymentStatusPending,
	}
	items := []*model.OrderItem{
		{PackageID: 10, PackageName: "设备套餐1", Quantity: 1, UnitPrice: 10000, Amount: 10000},
		{PackageID: 11, PackageName: "设备套餐2", Quantity: 1, UnitPrice: 10000, Amount: 10000},
	}
	require.NoError(t, orderStore.Create(ctx, order, items))

	result, err := itemStore.ListByOrderID(ctx, order.ID)
	require.NoError(t, err)
	assert.Len(t, result, 2)

	for _, item := range result {
		assert.Equal(t, order.ID, item.OrderID)
	}
}

func TestOrderItemStore_ListByOrderIDs(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	rdb := testutils.GetTestRedis(t)
	testutils.CleanTestRedisKeys(t, rdb)
	orderStore := NewOrderStore(tx, rdb)
	itemStore := NewOrderItemStore(tx, rdb)
	ctx := context.Background()

	order1 := &model.Order{
		OrderNo:       orderStore.GenerateOrderNo(),
		OrderType:     model.OrderTypeSingleCard,
		BuyerType:     model.BuyerTypePersonal,
		BuyerID:       300,
		TotalAmount:   5000,
		PaymentStatus: model.PaymentStatusPending,
	}
	items1 := []*model.OrderItem{
		{PackageID: 20, PackageName: "套餐X", Quantity: 1, UnitPrice: 5000, Amount: 5000},
	}
	require.NoError(t, orderStore.Create(ctx, order1, items1))

	order2 := &model.Order{
		OrderNo:       orderStore.GenerateOrderNo(),
		OrderType:     model.OrderTypeSingleCard,
		BuyerType:     model.BuyerTypePersonal,
		BuyerID:       300,
		TotalAmount:   8000,
		PaymentStatus: model.PaymentStatusPending,
	}
	items2 := []*model.OrderItem{
		{PackageID: 21, PackageName: "套餐Y", Quantity: 1, UnitPrice: 3000, Amount: 3000},
		{PackageID: 22, PackageName: "套餐Z", Quantity: 1, UnitPrice: 5000, Amount: 5000},
	}
	require.NoError(t, orderStore.Create(ctx, order2, items2))

	t.Run("查询多个订单的明细", func(t *testing.T) {
		result, err := itemStore.ListByOrderIDs(ctx, []uint{order1.ID, order2.ID})
		require.NoError(t, err)
		assert.Len(t, result, 3)
	})

	t.Run("空订单ID列表", func(t *testing.T) {
		result, err := itemStore.ListByOrderIDs(ctx, []uint{})
		require.NoError(t, err)
		assert.Nil(t, result)
	})

	t.Run("不存在的订单ID", func(t *testing.T) {
		result, err := itemStore.ListByOrderIDs(ctx, []uint{99999})
		require.NoError(t, err)
		assert.Len(t, result, 0)
	})
}
