package postgres

import (
	"context"
	"time"

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

// PersonalCustomerICCIDStore 个人客户 ICCID 绑定数据访问层
type PersonalCustomerICCIDStore struct {
	db *gorm.DB
}

// NewPersonalCustomerICCIDStore 创建个人客户 ICCID Store
func NewPersonalCustomerICCIDStore(db *gorm.DB) *PersonalCustomerICCIDStore {
	return &PersonalCustomerICCIDStore{
		db: db,
	}
}

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

// GetByCustomerID 根据客户 ID 获取所有 ICCID 绑定记录
func (s *PersonalCustomerICCIDStore) GetByCustomerID(ctx context.Context, customerID uint) ([]*model.PersonalCustomerICCID, error) {
	var records []*model.PersonalCustomerICCID
	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
}

// GetByICCID 根据 ICCID 获取所有绑定记录（查询哪些用户使用过这个 ICCID）
func (s *PersonalCustomerICCIDStore) GetByICCID(ctx context.Context, iccid string) ([]*model.PersonalCustomerICCID, error) {
	var column string
	switch len(iccid) {
	case 19:
		column = "iccid_19"
	default:
		column = "iccid"
	}
	var records []*model.PersonalCustomerICCID
	if err := s.db.WithContext(ctx).
		Where(column+" = ?", iccid).
		Order("last_used_at DESC").
		Find(&records).Error; err != nil {
		return nil, err
	}
	return records, nil
}

// GetByCustomerAndICCID 根据客户 ID 和 ICCID 获取绑定记录
func (s *PersonalCustomerICCIDStore) GetByCustomerAndICCID(ctx context.Context, customerID uint, iccid string) (*model.PersonalCustomerICCID, error) {
	var column string
	switch len(iccid) {
	case 19:
		column = "iccid_19"
	default:
		column = "iccid"
	}
	var record model.PersonalCustomerICCID
	if err := s.db.WithContext(ctx).
		Where("customer_id = ? AND "+column+" = ?", customerID, iccid).
		First(&record).Error; err != nil {
		return nil, err
	}
	return &record, nil
}

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

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

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

// ExistsByCustomerAndICCID 检查客户是否已绑定该 ICCID
func (s *PersonalCustomerICCIDStore) ExistsByCustomerAndICCID(ctx context.Context, customerID uint, iccid string) (bool, error) {
	var column string
	switch len(iccid) {
	case 19:
		column = "iccid_19"
	default:
		column = "iccid"
	}
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.PersonalCustomerICCID{}).
		Where("customer_id = ? AND "+column+" = ? AND status = ?", customerID, iccid, 1).
		Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

// CountByICCID 统计指定 ICCID 的绑定记录数量（不过滤 status）
func (s *PersonalCustomerICCIDStore) CountByICCID(ctx context.Context, iccid string) (int64, error) {
	var column string
	switch len(iccid) {
	case 19:
		column = "iccid_19"
	default:
		column = "iccid"
	}
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.PersonalCustomerICCID{}).
		Where(column+" = ?", iccid).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

// CreateOrUpdateLastUsed 创建或更新绑定记录的最后使用时间
// 如果绑定记录存在，更新最后使用时间；如果不存在，创建新记录
func (s *PersonalCustomerICCIDStore) CreateOrUpdateLastUsed(ctx context.Context, customerID uint, iccid string) error {
	record, err := s.GetByCustomerAndICCID(ctx, customerID, iccid)
	if err == gorm.ErrRecordNotFound {
		iccid19 := iccid
		if len(iccid) == 20 {
			iccid19 = iccid[:19]
		}
		newRecord := &model.PersonalCustomerICCID{
			CustomerID: customerID,
			ICCID:      iccid,
			ICCID19:    iccid19,
			Status:     1,
		}
		return s.Create(ctx, newRecord)
	} else if err != nil {
		return err
	}

	return s.UpdateLastUsedAt(ctx, record.ID)
}
