package robot

import (
	"context"
	"strings"
	"time"

	"cyberstrike-ai/internal/config"
	"cyberstrike-ai/internal/robot/ilink"

	"go.uber.org/zap"
)

const (
	wechatReconnectInitial = 5 * time.Second
	wechatReconnectMax     = 60 * time.Second
	wechatPlatform         = "wechat"
)

// StartWechat 启动微信 iLink 长轮询（无需公网回调），收到消息后调用 handler 并回复。
func StartWechat(ctx context.Context, robotsCfg config.RobotsConfig, h MessageHandler, appVersion string, logger *zap.Logger) {
	cfg := robotsCfg.Wechat
	if !cfg.Enabled || cfg.BotToken == "" {
		return
	}
	go runWechatLoop(ctx, cfg, h, appVersion, logger)
}

func runWechatLoop(ctx context.Context, cfg config.RobotWechatConfig, h MessageHandler, appVersion string, logger *zap.Logger) {
	backoff := wechatReconnectInitial
	for {
		err := runWechatPoll(ctx, cfg, h, appVersion, logger)
		if ctx.Err() != nil {
			logger.Info("微信 iLink 长轮询已按配置关闭")
			return
		}
		if err != nil {
			logger.Warn("微信 iLink 长轮询异常，将自动重连", zap.Error(err), zap.Duration("retry_after", backoff))
		}
		select {
		case <-ctx.Done():
			return
		case <-time.After(backoff):
			if backoff < wechatReconnectMax {
				backoff *= 2
				if backoff > wechatReconnectMax {
					backoff = wechatReconnectMax
				}
			}
		}
	}
}

func runWechatPoll(ctx context.Context, cfg config.RobotWechatConfig, h MessageHandler, appVersion string, logger *zap.Logger) error {
	client := ilink.NewClient(cfg.BaseURL, cfg.BotToken, cfg.BotAgent, ilink.BuildClientVersion(appVersion))
	buf := cfg.GetUpdatesBuf
	logger.Info("微信 iLink 长轮询已启动", zap.String("ilink_bot_id", cfg.ILinkBotID))
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		default:
		}
		resp, err := client.GetUpdates(ctx, buf)
		if err != nil {
			return err
		}
		if resp.ErrCode != 0 && resp.Ret != 0 {
			logger.Warn("微信 getUpdates 返回错误", zap.Int("errcode", resp.ErrCode), zap.String("errmsg", resp.ErrMsg))
		}
		if resp.GetUpdatesBuf != "" {
			buf = resp.GetUpdatesBuf
		}
		for _, msg := range resp.Msgs {
			if msg.MessageType != 1 {
				continue
			}
			text := ilink.ExtractText(msg)
			if text == "" {
				continue
			}
			userID := strings.TrimSpace(msg.FromUserID)
			if userID == "" {
				continue
			}
			logger.Info("微信收到消息", zap.String("from", userID), zap.String("content", text))
			reply := h.HandleMessage(wechatPlatform, userID, text)
			if strings.TrimSpace(reply) == "" {
				continue
			}
			if err := client.SendTextMessage(ctx, userID, msg.ContextToken, reply, ""); err != nil {
				logger.Warn("微信发送回复失败", zap.String("to", userID), zap.Error(err))
			}
		}
	}
}
