package postgres

import (
	"context"

	"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/redis/go-redis/v9"
	"gorm.io/gorm"
)

// PersonalCustomerStore 个人客户数据访问层
type PersonalCustomerStore struct {
	db    *gorm.DB
	redis *redis.Client
}

// NewPersonalCustomerStore 创建个人客户 Store
func NewPersonalCustomerStore(db *gorm.DB, redis *redis.Client) *PersonalCustomerStore {
	return &PersonalCustomerStore{
		db:    db,
		redis: redis,
	}
}

// Create 创建个人客户
func (s *PersonalCustomerStore) Create(ctx context.Context, customer *model.PersonalCustomer) error {
	return s.db.WithContext(ctx).Create(customer).Error
}

// GetByID 根据 ID 获取个人客户
func (s *PersonalCustomerStore) GetByID(ctx context.Context, id uint) (*model.PersonalCustomer, error) {
	var customer model.PersonalCustomer
	if err := s.db.WithContext(ctx).First(&customer, id).Error; err != nil {
		return nil, err
	}
	return &customer, nil
}

// GetByPhone 根据手机号获取个人客户
// 注意：由于 PersonalCustomer 不再直接存储手机号，此方法需要通过 PersonalCustomerPhone 关联表查询
func (s *PersonalCustomerStore) GetByPhone(ctx context.Context, phone string) (*model.PersonalCustomer, error) {
	var customerPhone model.PersonalCustomerPhone
	if err := s.db.WithContext(ctx).Where("phone = ?", phone).First(&customerPhone).Error; err != nil {
		return nil, err
	}

	// 查询关联的个人客户
	var customer model.PersonalCustomer
	if err := s.db.WithContext(ctx).First(&customer, customerPhone.CustomerID).Error; err != nil {
		return nil, err
	}
	return &customer, nil
}

// GetByWxOpenID 根据微信 OpenID 获取个人客户
func (s *PersonalCustomerStore) GetByWxOpenID(ctx context.Context, wxOpenID string) (*model.PersonalCustomer, error) {
	var customer model.PersonalCustomer
	if err := s.db.WithContext(ctx).Where("wx_open_id = ?", wxOpenID).First(&customer).Error; err != nil {
		return nil, err
	}
	return &customer, nil
}

// GetByWxUnionID 根据微信 UnionID 获取个人客户
func (s *PersonalCustomerStore) GetByWxUnionID(ctx context.Context, wxUnionID string) (*model.PersonalCustomer, error) {
	var customer model.PersonalCustomer
	if err := s.db.WithContext(ctx).Where("wx_union_id = ?", wxUnionID).First(&customer).Error; err != nil {
		return nil, err
	}
	return &customer, nil
}

// Update 更新个人客户
func (s *PersonalCustomerStore) Update(ctx context.Context, customer *model.PersonalCustomer) error {
	return s.db.WithContext(ctx).Save(customer).Error
}

// Delete 软删除个人客户
func (s *PersonalCustomerStore) Delete(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.PersonalCustomer{}, id).Error
}

// List 查询个人客户列表
func (s *PersonalCustomerStore) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.PersonalCustomer, int64, error) {
	var customers []*model.PersonalCustomer
	var total int64

	query := s.db.WithContext(ctx).Model(&model.PersonalCustomer{})

	// 应用过滤条件
	// 注意：phone 过滤需要通过关联表查询，这里先移除该过滤条件
	// TODO: 如果需要按手机号过滤，需要通过 JOIN PersonalCustomerPhone 表实现
	if nickname, ok := filters["nickname"].(string); ok && nickname != "" {
		query = query.Where("nickname LIKE ?", "%"+nickname+"%")
	}
	if status, ok := filters["status"].(int); ok {
		query = query.Where("status = ?", status)
	}

	// 计算总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页
	if opts == nil {
		opts = &store.QueryOptions{
			Page:     1,
			PageSize: constants.DefaultPageSize,
		}
	}
	offset := (opts.Page - 1) * opts.PageSize
	query = query.Offset(offset).Limit(opts.PageSize)

	// 排序
	if opts.OrderBy != "" {
		query = query.Order(opts.OrderBy)
	} else {
		query = query.Order("created_at DESC")
	}

	// 查询
	if err := query.Find(&customers).Error; err != nil {
		return nil, 0, err
	}

	return customers, total, nil
}
