package postgres

import (
	"context"
	"time"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"gorm.io/gorm"
)

// PersonalCustomerDeviceStore 个人客户设备号绑定数据访问层
type PersonalCustomerDeviceStore struct {
	db *gorm.DB
}

// NewPersonalCustomerDeviceStore 创建个人客户设备号 Store
func NewPersonalCustomerDeviceStore(db *gorm.DB) *PersonalCustomerDeviceStore {
	return &PersonalCustomerDeviceStore{
		db: db,
	}
}

// Create 创建设备号绑定记录
func (s *PersonalCustomerDeviceStore) Create(ctx context.Context, record *model.PersonalCustomerDevice) error {
	record.BindAt = time.Now()
	// LastUsedAt 在首次使用时更新，创建时保持 nil
	return s.db.WithContext(ctx).Create(record).Error
}

// GetByCustomerID 根据客户 ID 获取所有设备号绑定记录
func (s *PersonalCustomerDeviceStore) GetByCustomerID(ctx context.Context, customerID uint) ([]*model.PersonalCustomerDevice, error) {
	var records []*model.PersonalCustomerDevice
	if err := s.db.WithContext(ctx).
		Where("customer_id = ?", customerID).
		Order("last_used_at DESC").
		Find(&records).Error; err != nil {
		return nil, err
	}
	return records, nil
}

// GetByDeviceNo 根据设备号获取所有绑定记录（查询哪些用户使用过这个设备）
func (s *PersonalCustomerDeviceStore) GetByDeviceNo(ctx context.Context, deviceNo string) ([]*model.PersonalCustomerDevice, error) {
	var records []*model.PersonalCustomerDevice
	if err := s.db.WithContext(ctx).
		Where("virtual_no = ?", deviceNo).
		Order("last_used_at DESC").
		Find(&records).Error; err != nil {
		return nil, err
	}
	return records, nil
}

// GetByCustomerAndDevice 根据客户 ID 和设备号获取绑定记录
func (s *PersonalCustomerDeviceStore) GetByCustomerAndDevice(ctx context.Context, customerID uint, deviceNo string) (*model.PersonalCustomerDevice, error) {
	var record model.PersonalCustomerDevice
	if err := s.db.WithContext(ctx).
		Where("customer_id = ? AND virtual_no = ?", customerID, deviceNo).
		First(&record).Error; err != nil {
		return nil, err
	}
	return &record, nil
}

// UpdateLastUsedAt 更新最后使用时间
func (s *PersonalCustomerDeviceStore) UpdateLastUsedAt(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).
		Model(&model.PersonalCustomerDevice{}).
		Where("id = ?", id).
		Update("last_used_at", time.Now()).Error
}

// UpdateStatus 更新状态
func (s *PersonalCustomerDeviceStore) UpdateStatus(ctx context.Context, id uint, status int) error {
	return s.db.WithContext(ctx).
		Model(&model.PersonalCustomerDevice{}).
		Where("id = ?", id).
		Update("status", status).Error
}

// UpdateVirtualNo 更新指定记录的虚拟号（换货迁移专用）
func (s *PersonalCustomerDeviceStore) UpdateVirtualNo(ctx context.Context, id uint, newVirtualNo string) error {
	return s.db.WithContext(ctx).
		Model(&model.PersonalCustomerDevice{}).
		Where("id = ?", id).
		Update("virtual_no", newVirtualNo).Error
}

// Delete 软删除绑定记录
func (s *PersonalCustomerDeviceStore) Delete(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.PersonalCustomerDevice{}, id).Error
}

// ExistsByCustomerAndDevice 检查客户是否已绑定该设备
func (s *PersonalCustomerDeviceStore) ExistsByCustomerAndDevice(ctx context.Context, customerID uint, deviceNo string) (bool, error) {
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.PersonalCustomerDevice{}).
		Where("customer_id = ? AND virtual_no = ? AND status = ?", customerID, deviceNo, 1).
		Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CountByVirtualNo 统计指定虚拟号的绑定记录数量（不过滤 status）
func (s *PersonalCustomerDeviceStore) CountByVirtualNo(ctx context.Context, virtualNo string) (int64, error) {
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.PersonalCustomerDevice{}).
		Where("virtual_no = ?", virtualNo).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

// CreateOrUpdateLastUsed 创建或更新绑定记录的最后使用时间
// 如果绑定记录存在，更新最后使用时间；如果不存在，创建新记录
func (s *PersonalCustomerDeviceStore) CreateOrUpdateLastUsed(ctx context.Context, customerID uint, deviceNo string) error {
	record, err := s.GetByCustomerAndDevice(ctx, customerID, deviceNo)
	if err == gorm.ErrRecordNotFound {
		// 不存在，创建新记录
		newRecord := &model.PersonalCustomerDevice{
			CustomerID: customerID,
			VirtualNo:  deviceNo,
			Status:     1, // 启用
		}
		return s.Create(ctx, newRecord)
	} else if err != nil {
		return err
	}

	// 存在，更新最后使用时间
	return s.UpdateLastUsedAt(ctx, record.ID)
}
