package postgres

import (
	"context"
	"testing"

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

func TestPackageSeriesStore_Create(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode:  "SERIES_TEST_001",
		SeriesName:  "测试系列",
		Description: "测试描述",
		Status:      constants.StatusEnabled,
	}

	err := s.Create(ctx, series)
	require.NoError(t, err)
	assert.NotZero(t, series.ID)
}

func TestPackageSeriesStore_GetByID(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode: "SERIES_TEST_002",
		SeriesName: "测试系列2",
		Status:     constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, series))

	t.Run("查询存在的系列", func(t *testing.T) {
		result, err := s.GetByID(ctx, series.ID)
		require.NoError(t, err)
		assert.Equal(t, series.SeriesCode, result.SeriesCode)
	})

	t.Run("查询不存在的系列", func(t *testing.T) {
		_, err := s.GetByID(ctx, 99999)
		require.Error(t, err)
	})
}

func TestPackageSeriesStore_GetByCode(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode: "SERIES_TEST_003",
		SeriesName: "测试系列3",
		Status:     constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, series))

	t.Run("查询存在的编码", func(t *testing.T) {
		result, err := s.GetByCode(ctx, "SERIES_TEST_003")
		require.NoError(t, err)
		assert.Equal(t, series.ID, result.ID)
	})

	t.Run("查询不存在的编码", func(t *testing.T) {
		_, err := s.GetByCode(ctx, "NOT_EXISTS")
		require.Error(t, err)
	})
}

func TestPackageSeriesStore_Update(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode: "SERIES_TEST_004",
		SeriesName: "测试系列4",
		Status:     constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, series))

	series.SeriesName = "测试系列4-更新"
	series.Description = "更新后的描述"
	err := s.Update(ctx, series)
	require.NoError(t, err)

	updated, err := s.GetByID(ctx, series.ID)
	require.NoError(t, err)
	assert.Equal(t, "测试系列4-更新", updated.SeriesName)
	assert.Equal(t, "更新后的描述", updated.Description)
}

func TestPackageSeriesStore_Delete(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode: "SERIES_DEL_001",
		SeriesName: "待删除系列",
		Status:     constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, series))

	err := s.Delete(ctx, series.ID)
	require.NoError(t, err)

	_, err = s.GetByID(ctx, series.ID)
	require.Error(t, err)
}

func TestPackageSeriesStore_List(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	seriesList := []*model.PackageSeries{
		{SeriesCode: "LIST_S_001", SeriesName: "基础套餐", Status: constants.StatusEnabled},
		{SeriesCode: "LIST_S_002", SeriesName: "高级套餐", Status: constants.StatusEnabled},
		{SeriesCode: "LIST_S_003", SeriesName: "企业套餐", Status: constants.StatusEnabled},
	}
	for _, series := range seriesList {
		require.NoError(t, s.Create(ctx, series))
	}
	seriesList[2].Status = constants.StatusDisabled
	require.NoError(t, s.Update(ctx, seriesList[2]))

	t.Run("查询所有系列", func(t *testing.T) {
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 20}, nil)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(3))
		assert.GreaterOrEqual(t, len(result), 3)
	})

	t.Run("按名称模糊搜索", func(t *testing.T) {
		filters := map[string]interface{}{"series_name": "高级"}
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 20}, filters)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(1))
		for _, series := range result {
			assert.Contains(t, series.SeriesName, "高级")
		}
	})

	t.Run("按状态过滤", func(t *testing.T) {
		filters := map[string]interface{}{"status": constants.StatusDisabled}
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 20}, filters)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(1))
		for _, series := range result {
			assert.Equal(t, constants.StatusDisabled, series.Status)
		}
	})

	t.Run("分页查询", func(t *testing.T) {
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 2}, nil)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(3))
		assert.LessOrEqual(t, len(result), 2)
	})
}

func TestPackageSeriesStore_UpdateStatus(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewPackageSeriesStore(tx)
	ctx := context.Background()

	series := &model.PackageSeries{
		SeriesCode: "STATUS_TEST_001",
		SeriesName: "状态测试系列",
		Status:     constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, series))

	err := s.UpdateStatus(ctx, series.ID, constants.StatusDisabled)
	require.NoError(t, err)

	updated, err := s.GetByID(ctx, series.ID)
	require.NoError(t, err)
	assert.Equal(t, constants.StatusDisabled, updated.Status)
}
