package telegram

import (
	"context"
	"log/slog"
	"sync"
	"time"

	"proxyrotator/internal/config"
	"proxyrotator/internal/store"

	tele "gopkg.in/telebot.v3"
)

// Bot Telegram Bot 管理器
type Bot struct {
	mu    sync.RWMutex
	bot   *tele.Bot
	cfg   *config.Config
	store store.ProxyStore

	scheduler *Scheduler
	notifier  *Notifier

	running  bool
	stopChan chan struct{}
}

// Status Bot 状态
type Status struct {
	Running   bool   `json:"running"`
	Connected bool   `json:"connected"`
	Username  string `json:"username,omitempty"`
}

// NewBot 创建 Bot 实例
func NewBot(cfg *config.Config, proxyStore store.ProxyStore) *Bot {
	return &Bot{
		cfg:      cfg,
		store:    proxyStore,
		stopChan: make(chan struct{}),
	}
}

// Start 启动 Bot
func (b *Bot) Start(ctx context.Context) error {
	b.mu.Lock()
	defer b.mu.Unlock()

	if b.running {
		return nil
	}

	if b.cfg.TelegramBotToken == "" {
		slog.Info("telegram bot token not configured, skipping")
		return nil
	}

	return b.startInternal()
}

// startInternal 内部启动（需要持有锁）
func (b *Bot) startInternal() error {
	pref := tele.Settings{
		Token:  b.cfg.TelegramBotToken,
		Poller: &tele.LongPoller{Timeout: 10 * time.Second},
	}

	bot, err := tele.NewBot(pref)
	if err != nil {
		slog.Error("failed to create telegram bot", "error", err)
		return err
	}

	b.bot = bot
	b.notifier = NewNotifier(bot, b.cfg.TelegramNotifyChatID)
	b.scheduler = NewScheduler(b.store, b.notifier, b.cfg)

	// 注册命令处理器
	b.registerCommands(b.cfg.TelegramAdminIDs)

	// 启动调度器
	b.scheduler.Start()

	// 注册命令菜单
	commands := []tele.Command{
		{Text: "stats", Description: "查看代理池统计"},
		{Text: "groups", Description: "查看分组统计"},
		{Text: "get", Description: "获取可用代理 (默认1个，如 /get 5)"},
		{Text: "import", Description: "导入代理 (如 /import groupname)"},
		{Text: "test", Description: "触发测活 (如 /test groupname)"},
		{Text: "purge", Description: "清理死代理"},
		{Text: "help", Description: "显示帮助信息"},
	}
	if err := bot.SetCommands(commands); err != nil {
		slog.Warn("failed to set bot commands", "error", err)
	}

	// 启动 Bot
	b.stopChan = make(chan struct{})
	go func() {
		slog.Info("telegram bot started", "username", bot.Me.Username)
		bot.Start()
	}()

	b.running = true
	return nil
}

// Stop 停止 Bot
func (b *Bot) Stop() {
	b.mu.Lock()
	defer b.mu.Unlock()

	b.stopInternal()
}

// stopInternal 内部停止（需要持有锁）
func (b *Bot) stopInternal() {
	if !b.running {
		return
	}

	if b.scheduler != nil {
		b.scheduler.Stop()
	}

	if b.bot != nil {
		b.bot.Stop()
		slog.Info("telegram bot stopped")
	}

	close(b.stopChan)
	b.running = false
}

// Status 获取 Bot 状态
func (b *Bot) Status() Status {
	b.mu.RLock()
	defer b.mu.RUnlock()

	status := Status{
		Running: b.running,
	}

	if b.bot != nil && b.running {
		status.Connected = true
		status.Username = b.bot.Me.Username
	}

	return status
}

// TriggerTest 手动触发测活
func (b *Bot) TriggerTest(ctx context.Context) error {
	b.mu.RLock()
	defer b.mu.RUnlock()

	if b.scheduler == nil {
		return nil
	}

	return b.scheduler.RunTest(ctx)
}

// registerCommands 注册命令
func (b *Bot) registerCommands(adminIDs []int64) {
	// 管理员权限中间件
	adminOnly := func(next tele.HandlerFunc) tele.HandlerFunc {
		return func(c tele.Context) error {
			if len(adminIDs) == 0 {
				return next(c)
			}
			userID := c.Sender().ID
			for _, id := range adminIDs {
				if id == userID {
					return next(c)
				}
			}
			return c.Send("⛔ 无权限访问")
		}
	}

	// 创建命令处理器
	cmds := NewCommands(b.store, b.scheduler)

	b.bot.Handle("/start", adminOnly(cmds.HandleStart))
	b.bot.Handle("/help", adminOnly(cmds.HandleHelp))
	b.bot.Handle("/stats", adminOnly(cmds.HandleStats))
	b.bot.Handle("/groups", adminOnly(cmds.HandleGroups))
	b.bot.Handle("/get", adminOnly(cmds.HandleGet))
	b.bot.Handle("/test", adminOnly(cmds.HandleTest))
	b.bot.Handle("/purge", adminOnly(cmds.HandlePurge))
	b.bot.Handle("/import", adminOnly(cmds.HandleImport))
	b.bot.Handle(tele.OnDocument, adminOnly(cmds.HandleDocument))
	b.bot.Handle(tele.OnText, adminOnly(cmds.HandleText))
}
