package usecase

import (
	"log"
	"sync"

	"haixun-backend/internal/library/clock"
	domusecase "haixun-backend/internal/model/threads_account/domain/usecase"
)

const oauthDebugLogCap = 80

// OAuthDebugEntry is a recent OAuth event for Dev Console debugging.
type OAuthDebugEntry struct {
	At        int64  `json:"at"`
	Level     string `json:"level"`
	Stage     string `json:"stage"`
	AccountID string `json:"account_id,omitempty"`
	Message   string `json:"message"`
}

var (
	oauthDebugMu   sync.Mutex
	oauthDebugRing []OAuthDebugEntry
	oauthDebugSeq  int
)

func recordOAuthDebug(level, stage, accountID, message string) {
	at := clock.NowUnixNano()
	entry := OAuthDebugEntry{
		At:        at,
		Level:     level,
		Stage:     stage,
		AccountID: accountID,
		Message:   message,
	}
	log.Printf("threads oauth [%s] %s account=%s %s", stage, level, accountID, message)

	oauthDebugMu.Lock()
	defer oauthDebugMu.Unlock()
	if len(oauthDebugRing) < oauthDebugLogCap {
		oauthDebugRing = append(oauthDebugRing, entry)
	} else {
		oauthDebugRing[oauthDebugSeq%oauthDebugLogCap] = entry
	}
	oauthDebugSeq++
}

func (u *threadsAccountUseCase) RecordOAuthDebug(level, stage, accountID, message string) {
	recordOAuthDebug(level, stage, accountID, message)
}

func (u *threadsAccountUseCase) ListOAuthDebugLogs(limit int) []domusecase.OAuthDebugLogEntry {
	raw := listOAuthDebugLogs(limit)
	out := make([]domusecase.OAuthDebugLogEntry, 0, len(raw))
	for _, item := range raw {
		out = append(out, domusecase.OAuthDebugLogEntry{
			At:        item.At,
			Level:     item.Level,
			Stage:     item.Stage,
			AccountID: item.AccountID,
			Message:   item.Message,
		})
	}
	return out
}

func listOAuthDebugLogs(limit int) []OAuthDebugEntry {
	if limit <= 0 || limit > oauthDebugLogCap {
		limit = oauthDebugLogCap
	}
	oauthDebugMu.Lock()
	defer oauthDebugMu.Unlock()
	n := len(oauthDebugRing)
	if n == 0 {
		return nil
	}
	out := make([]OAuthDebugEntry, 0, min(n, limit))
	if n < oauthDebugLogCap {
		start := n - min(n, limit)
		if start < 0 {
			start = 0
		}
		out = append(out, oauthDebugRing[start:n]...)
		return out
	}
	start := oauthDebugSeq - min(oauthDebugSeq, limit)
	if start < 0 {
		start = 0
	}
	for i := start; i < oauthDebugSeq; i++ {
		out = append(out, oauthDebugRing[i%oauthDebugLogCap])
	}
	return out
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
