package camel_oil

import (
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/gtrace"
	"github.com/gogf/gf/v2/os/glog"
	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model/do"
	"kami/utility/config"
	"kami/utility/integration/camel_oil_api"
	"kami/utility/integration/pig"
	"sync"
	"sync/atomic"
)

// LoginAccount 执行账号登录流程
// 注意：当前使用假数据，实际应对接骆驼加油平台和接码平台
func (s *sCamelOil) LoginAccount(ctx context.Context) (err error) {
	ctx, span := gtrace.NewSpan(ctx, "sCamelOil.LoginAccount")
	defer span.End()

	// 对接接码平台，获取手机号并检查是否已存在
	phoneNumber, err := pig.NewClient().GetAccountInfo(ctx)
	if err != nil {
		return gerror.Wrap(err, "从豪猪平台获取手机号失败")
	}

	// 检查手机号是否已存在
	existingAccount, checkErr := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Phone, phoneNumber).
		One()
	if checkErr != nil {
		return gerror.Wrap(checkErr, "检查手机号是否存在失败")
	}

	// 如果手机号已存在，继续获取新的手机号
	if existingAccount != nil {
		// 手机号不存在，可以使用
		return errors.New("手机号已存在，重新获取")
	}

	isOk, err := camel_oil_api.NewClient(ctx).SendCaptcha(ctx, phoneNumber)
	if err != nil {
		return gerror.Wrap(err, "发送验证码失败")
	}
	if !isOk {
		return gerror.New("获取验证码失败")
	}

	accountId, err := s.CreateAccount(ctx, phoneNumber, "创建账号")
	if err != nil {
		return gerror.Wrap(err, "创建账号失败")
	}
	// 更新状态为登录中
	_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusSendCode, consts.CamelOilAccountChangeTypeLogin, "获取验证码成功")
	return nil
}

// BatchLoginAccounts 批量登录账号
func (s *sCamelOil) BatchLoginAccounts(ctx context.Context, count int64) (successCount int64, err error) {
	ctx, span := gtrace.NewSpan(ctx, "sCamelOil.BatchLoginAccounts")
	defer span.End()

	if count <= 0 {
		return 0, gerror.New("登录数量必须大于0")
	}

	// 使用设置中的并发数量控制登录
	semaphore := make(chan struct{}, 1)
	var wg sync.WaitGroup
	var successCounter int64

	for i := 0; i < int(count); i++ {
		wg.Go(func() {
			semaphore <- struct{}{}        // 获取信号量
			defer func() { <-semaphore }() // 释放信号量

			loginErr := s.LoginAccount(ctx)
			if loginErr != nil {
				glog.Errorf(ctx, "账号登录失败，错误: %v", loginErr)
				return
			}
			atomic.AddInt64(&successCounter, 1)
		})
	}

	wg.Wait()
	successCount = successCounter
	glog.Infof(ctx, "批量登录完成，成功: %d", successCount)
	return successCount, nil
}

// markAccountInvalid 标记账号为已失效
func (s *sCamelOil) markAccountInvalid(ctx context.Context, accountId int64, reason string) error {
	_, err := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CamelOilAccount.Columns().Id, accountId).
		Update(do.V1CamelOilAccount{
			Status:        consts.CamelOilAccountStatusInvalid,
			FailureReason: reason,
		})
	if err != nil {
		return gerror.Wrap(err, "标记账号为已失效失败")
	}

	// 记录失效历史
	_ = s.RecordAccountHistory(ctx, accountId, consts.CamelOilAccountChangeTypeInvalidate,
		consts.CamelOilAccountStatusSendCode, consts.CamelOilAccountStatusInvalid,
		fmt.Sprintf("账号失效: %s", reason))

	glog.Warningf(ctx, "账号已标记为失效，ID: %d, 原因: %s", accountId, reason)
	return nil
}
