package job

import (
	"context"
	"fmt"
	"strings"

	libthreads "haixun-backend/internal/library/threadsapi"
	jobdom "haixun-backend/internal/model/job/domain/usecase"
	publishanalyticsdomain "haixun-backend/internal/model/publish_analytics/domain/usecase"
	threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase"
)

type PublishAnalyticsDeps struct {
	Jobs             jobdom.UseCase
	ThreadsAccount   threadsaccountdomain.UseCase
	PublishAnalytics publishanalyticsdomain.UseCase
}

func RegisterPublishAnalyticsHandler(runner *Runner, deps PublishAnalyticsDeps) {
	if runner == nil {
		return
	}
	runner.RegisterStepHandler("check", func(ctx context.Context, step StepContext) error {
		return runPublishAnalyticsCheck(ctx, step, deps)
	})
}

func runPublishAnalyticsCheck(ctx context.Context, step StepContext, deps PublishAnalyticsDeps) error {
	payload := step.Run.Payload
	tenantID, ownerUID := runActorFromPayload(payload, step.Run)
	mediaID := strings.TrimSpace(stringField(payload, "media_id"))
	checkpoint := strings.TrimSpace(stringField(payload, "checkpoint"))
	permalink := strings.TrimSpace(stringField(payload, "permalink"))
	publishedAt := int64Field(payload, "published_at")
	if mediaID == "" || checkpoint == "" {
		return fmt.Errorf("publish-analytics payload missing media_id or checkpoint")
	}

	accountID := strings.TrimSpace(stringField(payload, "account_id"))
	if accountID == "" {
		accountID = strings.TrimSpace(step.Run.ScopeID)
	}
	token, err := deps.ThreadsAccount.ResolveAccountAPIAccessToken(ctx, tenantID, ownerUID, accountID)
	if err != nil {
		return fmt.Errorf("resolve api token: %w", err)
	}
	if token == "" {
		return fmt.Errorf("no access token found")
	}

	stats, err := libthreads.GetMediaStats(ctx, token, mediaID)
	if err != nil {
		return fmt.Errorf("get media stats: %w", err)
	}

	saved, err := deps.PublishAnalytics.RecordCheckpoint(ctx, tenantID, ownerUID, publishanalyticsdomain.PublishAnalyticsSummary{
		MediaID:     mediaID,
		Permalink:   permalink,
		PublishedAt: publishedAt,
		Checkpoint:  checkpoint,
		LikeCount:   stats.LikeCount,
		ReplyCount:  stats.ReplyCount,
		RepostCount: stats.RepostCount,
		QuoteCount:  stats.QuoteCount,
		ViewCount:   stats.Views,
		ShareCount:  stats.Shares,
	})
	if err != nil {
		return fmt.Errorf("record checkpoint: %w", err)
	}

	_, err = deps.Jobs.CompleteRun(ctx, jobdom.CompleteRunRequest{
		JobID:    step.JobID,
		WorkerID: step.WorkerID,
		Result: map[string]any{
			"media_id":     mediaID,
			"checkpoint":   checkpoint,
			"like_count":   saved.LikeCount,
			"reply_count":  saved.ReplyCount,
			"repost_count": saved.RepostCount,
			"quote_count":  saved.QuoteCount,
			"view_count":   saved.ViewCount,
			"share_count":  saved.ShareCount,
			"analytics_id": saved.ID,
		},
	})
	return err
}
