package postgres

import (
	"context"

	"gorm.io/gorm"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/store"
)

type CarrierStore struct {
	db *gorm.DB
}

func NewCarrierStore(db *gorm.DB) *CarrierStore {
	return &CarrierStore{db: db}
}

func (s *CarrierStore) Create(ctx context.Context, carrier *model.Carrier) error {
	return s.db.WithContext(ctx).Create(carrier).Error
}

func (s *CarrierStore) GetByID(ctx context.Context, id uint) (*model.Carrier, error) {
	var carrier model.Carrier
	if err := s.db.WithContext(ctx).First(&carrier, id).Error; err != nil {
		return nil, err
	}
	return &carrier, nil
}

func (s *CarrierStore) GetByCode(ctx context.Context, code string) (*model.Carrier, error) {
	var carrier model.Carrier
	if err := s.db.WithContext(ctx).Where("carrier_code = ?", code).First(&carrier).Error; err != nil {
		return nil, err
	}
	return &carrier, nil
}

func (s *CarrierStore) Update(ctx context.Context, carrier *model.Carrier) error {
	return s.db.WithContext(ctx).Save(carrier).Error
}

func (s *CarrierStore) Delete(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.Carrier{}, id).Error
}

func (s *CarrierStore) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.Carrier, int64, error) {
	var carriers []*model.Carrier
	var total int64

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

	if carrierType, ok := filters["carrier_type"].(string); ok && carrierType != "" {
		query = query.Where("carrier_type = ?", carrierType)
	}
	if carrierName, ok := filters["carrier_name"].(string); ok && carrierName != "" {
		query = query.Where("carrier_name LIKE ?", "%"+carrierName+"%")
	}
	if status, ok := filters["status"]; ok {
		query = query.Where("status = ?", status)
	}

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

	if opts == nil {
		opts = store.DefaultQueryOptions()
	}
	offset := (opts.Page - 1) * opts.PageSize
	query = query.Offset(offset).Limit(opts.PageSize)

	if opts.OrderBy != "" {
		query = query.Order(opts.OrderBy)
	}

	if err := query.Find(&carriers).Error; err != nil {
		return nil, 0, err
	}

	return carriers, total, nil
}

// GetDataResetDay 获取运营商上游流量重置日（1-28），查询失败默认返回 1
func (s *CarrierStore) GetDataResetDay(ctx context.Context, carrierID uint) int {
	var day int
	err := s.db.WithContext(ctx).
		Model(&model.Carrier{}).
		Select("data_reset_day").
		Where("id = ?", carrierID).
		Scan(&day).Error
	if err != nil || day == 0 {
		return 1
	}
	return day
}
