package repository

import (
	"context"
	"errors"
	"fmt"
	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
	"github.com/go-nunu/nunu-layout-advanced/internal/model"
	"gorm.io/gorm"
	"math"
	"strings"
)

type GatewayGroupRepository interface {
	GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error)
	AddGatewayGroup(ctx context.Context, req *model.GatewayGroup) error
	EditGatewayGroup(ctx context.Context, req *model.GatewayGroup) error
	DeleteGatewayGroup(ctx context.Context, id int) error
	GetGatewayGroupWhereHostIdNull(ctx context.Context, req v1.GlobalLimitRequireResponse) (int, error)
	GetGatewayGroupByHostId(ctx context.Context, hostId int64) (*model.GatewayGroup, error)
	GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup], error)
	EditGatewayGroupById(ctx context.Context, req *model.GatewayGroup) error
}

func NewGatewayGroupRepository(
	repository *Repository,
) GatewayGroupRepository {
	return &gatewayGroupRepository{
		Repository: repository,
	}
}

type gatewayGroupRepository struct {
	*Repository
}

func (r *gatewayGroupRepository) GetGatewayGroup(ctx context.Context, id int64) (*model.GatewayGroup, error) {
	var gatewayGroup model.GatewayGroup

	return &gatewayGroup, nil
}

func (r *gatewayGroupRepository) AddGatewayGroup(ctx context.Context, req *model.GatewayGroup) error {
	if err := r.DB(ctx).Create(req).Error; err != nil {
		return err
	}
	return nil
}

func (r *gatewayGroupRepository) EditGatewayGroup(ctx context.Context, req *model.GatewayGroup) error {
	if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", req.Id).Updates(req).Error; err != nil {
		return err
	}
	return nil
}

func (r *gatewayGroupRepository) DeleteGatewayGroup(ctx context.Context, id int) error {
	if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", id).Delete(&model.GatewayGroup{}).Error; err != nil {
		return err
	}
	return nil
}

func (r *gatewayGroupRepository) GetGatewayGroupWhereHostIdNull(ctx context.Context,req v1.GlobalLimitRequireResponse) (int, error) {
	var id int
	subQuery := r.DB(ctx).Model(&model.GateWayGroupIp{}).
		Select("gateway_group_id").
		Group("gateway_group_id").
		Having("COUNT(*) = ?", req.IpCount)

	err := r.DB(ctx).Model(&model.GatewayGroup{}).
		Where("operator = ?", req.Operator).
		Where("ban_udp", req.IsBanUdp).
		Where("ban_overseas", req.IsBanOverseas).
		Where("id IN (?)", subQuery).
		Where("host_id = ?", 0).
		Select("id").First(&id).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound){
			return 0, fmt.Errorf("库存不足,请联系客服补充网关组库存")
		}
		return 0, err
	}
	return id, nil
}

func (r *gatewayGroupRepository) GetGatewayGroupByHostId(ctx context.Context, hostId int64) (*model.GatewayGroup, error) {
	res := model.GatewayGroup{}
	if err := r.DB(ctx).Where("host_id = ?", hostId).Find(&res).Error; err != nil {
		return nil, err
	}
	return &res, nil
}


func (r *gatewayGroupRepository) GetGatewayGroupList(ctx context.Context,req v1.SearchGatewayGroupParams) (*v1.PaginatedResponse[model.GatewayGroup], error) {
	var res []model.GatewayGroup
	var total int64

	query := r.Db.WithContext(ctx).Model(&model.GatewayGroup{})

	if  req.Name != "" {
		// 去除后所有的空白字符（包括空格、制表符\t、换行符等）
		trimmedName := strings.TrimSpace(req.Name)
		// 使用 LIKE 进行模糊匹配
		query = query.Where("name LIKE CONCAT('%', ?, '%')", trimmedName)
	}
	// 如果 HostId 被提供了，添加一个精确匹配条件
	if req.HostId != 0 {
		query = query.Where("host_id = ?", req.HostId)
	}

	// 如果 RuleId 被提供了
	if req.RuleId != 0 {
		query = query.Where("rule_id = ?", req.RuleId)
	}

	// 如果 Operator 被提供了
	if req.Operator != 0 {
		query = query.Where("operator = ?", req.Operator)
	}

	if req.Column != "" {
		if req.Column == "createTime" {
			query = query.Order("created_at" + " " + req.Order)
		}
	}

	if err := query.Count(&total).Error; err != nil {
		// 如果连计数都失败了，直接返回错误
		return nil, err
	}


	page := req.Current
	pageSize := req.PageSize

	if page <= 0 {
		page = 1
	}

	if pageSize <= 0 {
		pageSize = 10 // 默认每页 10 条
	} else if pageSize > 100 {
		pageSize = 100 // 每页最多 100 条
	}

	// 计算 offset (偏移量)
	// 例如，第 1 页，offset = (1-1)*10 = 0 (从第0条开始)
	// 第 2 页，offset = (2-1)*10 = 10 (从第10条开始)
	offset := (page - 1) * pageSize
	// 3. 执行最终的查询
	// 在所有条件都添加完毕后，再执行 .Find()
	result := query.Offset(offset).Limit(pageSize).Find(&res)
	if result.Error != nil {
		// 这里的错误可能是数据库连接问题等，而不是“未找到记录”
		return nil, result.Error
	}
	return &v1.PaginatedResponse[model.GatewayGroup]{
		Records: res,
		Page: page,
		PageSize: pageSize,
		Total: total,
		TotalPages: int(math.Ceil(float64(total) / float64(pageSize))),

	}, nil
}

func (r *gatewayGroupRepository) EditGatewayGroupById(ctx context.Context, req *model.GatewayGroup) error {

	if err := r.DB(ctx).Model(&model.GatewayGroup{}).Where("id = ?", req.Id).Updates(req).Error; err != nil {
		return err
	}
	return nil

}