package server

import (
	"ai_scheduler/internal/entitys"
	"ai_scheduler/internal/services"
	"context"
	"fmt"
	"sync"

	"gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/card"
	"gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/chatbot"
	"gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/client"
	"github.com/go-kratos/kratos/v2/log"
)

type DingBotServiceInterface interface {
	GetServiceCfg() ([]entitys.DingTalkBot, error)
	OnChatBotMessageReceived(ctx context.Context, data *chatbot.BotCallbackDataModel) (content []byte, err error)
	OnCardMessageReceived(ctx context.Context, data *card.CardRequest) (resp *card.CardResponse, err error)
}

type DingTalkBotServer struct {
	Clients map[string]*client.StreamClient
}

// NewDingTalkBotServer 批量注册钉钉客户端cli
// 这里支持两种方式，一种是完全独立service,一种是直接用现成的service
// 独立的service,在本页的ProvideAllDingBotServices方法进行注册
// 现成的service参考services->dtalk_bot.go
// 具体使用请根据实际业务需求
func NewDingTalkBotServer(
	services []DingBotServiceInterface,
) *DingTalkBotServer {
	clients := make(map[string]*client.StreamClient)
	for _, service := range services {
		serviceConfigs, err := service.GetServiceCfg()
		for _, serviceConf := range serviceConfigs {
			if serviceConf.ClientId == "" || serviceConf.ClientSecret == "" {
				continue
			}
			cli := DingBotServerInit(serviceConf.ClientId, serviceConf.ClientSecret, service)
			if cli == nil {
				log.Infof("%s客户端初始失败:%s", serviceConf.BotIndex, err.Error())
				continue
			}
			clients[serviceConf.BotIndex] = cli
		}
	}
	return &DingTalkBotServer{
		Clients: clients,
	}
}

func ProvideAllDingBotServices(
	dingBotSvc *services.DingBotService,
) []DingBotServiceInterface {
	return []DingBotServiceInterface{
		dingBotSvc,
	}
}

func (d *DingTalkBotServer) Run(ctx context.Context, botIndex string) {
	if botIndex == "" {
		log.Info("未指定机器人索引，跳过启动")
		return
	}

	var targets []string
	switch {
	case botIndex == "All":
		targets = make([]string, 0, len(d.Clients))
		for name := range d.Clients {
			targets = append(targets, name)
		}
	default:
		if _, exists := d.Clients[botIndex]; exists {
			targets = []string{botIndex}
		} else {
			log.Infof("未找到索引为 %s 的机器人", botIndex)
			return
		}
	}

	var wg sync.WaitGroup
	errors := make([]error, 0, len(targets))

	for _, name := range targets {
		wg.Add(1)
		go func(name string) {
			defer wg.Done()
			err := d.Clients[name].Start(ctx)
			if err != nil {
				log.Errorf("%s 启动失败: %v", name, err)
				errors = append(errors, fmt.Errorf("%s: %w", name, err))
			} else {
				log.Infof("%s 启动成功", name)
			}
		}(name)
	}

	wg.Wait()
	if len(errors) > 0 {
		log.Errorf("部分机器人启动失败，总数: %d, 成功: %d, 失败: %d",
			len(targets), len(targets)-len(errors), len(errors))
	}
}
func DingBotServerInit(clientId string, clientSecret string, service DingBotServiceInterface) (cli *client.StreamClient) {
	cli = client.NewStreamClient(client.WithAppCredential(client.NewAppCredentialConfig(clientId, clientSecret)))
	cli.RegisterChatBotCallbackRouter(service.OnChatBotMessageReceived)
	cli.RegisterCardCallbackRouter(service.OnCardMessageReceived)
	return
}
