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 TestCarrierStore_Create(t *testing.T) {
	tx := testutils.NewTestTransaction(t)
	s := NewCarrierStore(tx)
	ctx := context.Background()

	carrier := &model.Carrier{
		CarrierCode: "CMCC_TEST_001",
		CarrierName: "中国移动测试",
		CarrierType: constants.CarrierTypeCMCC,
		Description: "测试运营商",
		Status:      constants.StatusEnabled,
	}

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

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

	carrier := &model.Carrier{
		CarrierCode: "CUCC_TEST_001",
		CarrierName: "中国联通测试",
		CarrierType: constants.CarrierTypeCUCC,
		Status:      constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, carrier))

	t.Run("查询存在的运营商", func(t *testing.T) {
		result, err := s.GetByID(ctx, carrier.ID)
		require.NoError(t, err)
		assert.Equal(t, carrier.CarrierCode, result.CarrierCode)
		assert.Equal(t, carrier.CarrierName, result.CarrierName)
	})

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

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

	carrier := &model.Carrier{
		CarrierCode: "CTCC_TEST_001",
		CarrierName: "中国电信测试",
		CarrierType: constants.CarrierTypeCTCC,
		Status:      constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, carrier))

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

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

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

	carrier := &model.Carrier{
		CarrierCode: "CBN_TEST_001",
		CarrierName: "中国广电测试",
		CarrierType: constants.CarrierTypeCBN,
		Status:      constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, carrier))

	carrier.CarrierName = "中国广电测试-更新"
	carrier.Description = "更新后的描述"
	err := s.Update(ctx, carrier)
	require.NoError(t, err)

	updated, err := s.GetByID(ctx, carrier.ID)
	require.NoError(t, err)
	assert.Equal(t, "中国广电测试-更新", updated.CarrierName)
	assert.Equal(t, "更新后的描述", updated.Description)
}

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

	carrier := &model.Carrier{
		CarrierCode: "DEL_TEST_001",
		CarrierName: "待删除运营商",
		CarrierType: constants.CarrierTypeCMCC,
		Status:      constants.StatusEnabled,
	}
	require.NoError(t, s.Create(ctx, carrier))

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

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

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

	carriers := []*model.Carrier{
		{CarrierCode: "LIST_001", CarrierName: "移动1", CarrierType: constants.CarrierTypeCMCC, Status: constants.StatusEnabled},
		{CarrierCode: "LIST_002", CarrierName: "联通1", CarrierType: constants.CarrierTypeCUCC, Status: constants.StatusEnabled},
		{CarrierCode: "LIST_003", CarrierName: "电信1", CarrierType: constants.CarrierTypeCTCC, Status: constants.StatusEnabled},
	}
	for _, c := range carriers {
		require.NoError(t, s.Create(ctx, c))
	}
	// 显式更新第三个 carrier 为禁用状态（GORM 不会写入零值）
	carriers[2].Status = constants.StatusDisabled
	require.NoError(t, s.Update(ctx, carriers[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{}{"carrier_type": constants.CarrierTypeCMCC}
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 20}, filters)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(1))
		for _, c := range result {
			assert.Equal(t, constants.CarrierTypeCMCC, c.CarrierType)
		}
	})

	t.Run("按名称模糊搜索", func(t *testing.T) {
		filters := map[string]interface{}{"carrier_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 _, c := range result {
			assert.Contains(t, c.CarrierName, "联通")
		}
	})

	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 _, c := range result {
			assert.Equal(t, constants.StatusDisabled, c.Status)
		}
	})

	t.Run("按状态过滤-启用", func(t *testing.T) {
		filters := map[string]interface{}{"status": constants.StatusEnabled}
		result, total, err := s.List(ctx, &store.QueryOptions{Page: 1, PageSize: 20}, filters)
		require.NoError(t, err)
		assert.GreaterOrEqual(t, total, int64(2))
		for _, c := range result {
			assert.Equal(t, constants.StatusEnabled, c.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)
	})

	t.Run("默认分页选项", func(t *testing.T) {
		result, _, err := s.List(ctx, nil, nil)
		require.NoError(t, err)
		assert.NotNil(t, result)
	})
}
