package usecase

import (
	"context"
	"strings"

	"haixun-backend/internal/library/clock"
	app "haixun-backend/internal/library/errors"
	"haixun-backend/internal/library/errors/code"
	jobdom "haixun-backend/internal/model/job/domain/usecase"
	"haixun-backend/internal/model/publish_analytics/domain/entity"
	domrepo "haixun-backend/internal/model/publish_analytics/domain/repository"
	domusecase "haixun-backend/internal/model/publish_analytics/domain/usecase"

	"github.com/google/uuid"
)

type publishAnalyticsUseCase struct {
	repo domrepo.Repository
	jobs jobdom.UseCase
}

func NewUseCase(repo domrepo.Repository, jobs jobdom.UseCase) domusecase.UseCase {
	return &publishAnalyticsUseCase{repo: repo, jobs: jobs}
}

func (u *publishAnalyticsUseCase) RecordCheckpoint(ctx context.Context, tenantID, ownerUID string, summary domusecase.PublishAnalyticsSummary) (*domusecase.PublishAnalyticsSummary, error) {
	tenantID = strings.TrimSpace(tenantID)
	ownerUID = strings.TrimSpace(ownerUID)
	if tenantID == "" || ownerUID == "" {
		return nil, app.For(code.AI).AuthUnauthorized("missing actor")
	}
	mediaID := strings.TrimSpace(summary.MediaID)
	if mediaID == "" {
		return nil, app.For(code.AI).InputMissingRequired("media_id is required")
	}
	checkpoint := strings.TrimSpace(summary.Checkpoint)
	if checkpoint == "" {
		return nil, app.For(code.AI).InputMissingRequired("checkpoint is required")
	}

	now := clock.NowUnixNano()
	analytics := &entity.PublishAnalytics{
		ID:              uuid.NewString(),
		TenantID:        tenantID,
		OwnerUID:        ownerUID,
		MediaID:         mediaID,
		Permalink:       strings.TrimSpace(summary.Permalink),
		PublishedAt:     summary.PublishedAt,
		Checkpoint:      checkpoint,
		LikeCount:       summary.LikeCount,
		ReplyCount:      summary.ReplyCount,
		RepostCount:     summary.RepostCount,
		QuoteCount:      summary.QuoteCount,
		ViewCount:       summary.ViewCount,
		ShareCount:      summary.ShareCount,
		ImpressionCount: summary.ImpressionCount,
		ReachCount:      summary.ReachCount,
		CheckedAt:       now,
		CreateAt:        now,
	}

	created, err := u.repo.Upsert(ctx, analytics)
	if err != nil {
		return nil, err
	}
	out := toSummary(*created)
	return &out, nil
}

func (u *publishAnalyticsUseCase) ListByMedia(ctx context.Context, tenantID, ownerUID, mediaID string) ([]domusecase.PublishAnalyticsSummary, error) {
	tenantID = strings.TrimSpace(tenantID)
	ownerUID = strings.TrimSpace(ownerUID)
	mediaID = strings.TrimSpace(mediaID)
	if tenantID == "" || ownerUID == "" {
		return nil, app.For(code.AI).AuthUnauthorized("missing actor")
	}
	if mediaID == "" {
		return nil, app.For(code.AI).InputMissingRequired("media_id is required")
	}

	items, err := u.repo.ListByMedia(ctx, tenantID, ownerUID, mediaID)
	if err != nil {
		return nil, err
	}
	out := make([]domusecase.PublishAnalyticsSummary, 0, len(items))
	for _, item := range items {
		out = append(out, toSummary(item))
	}
	return out, nil
}

func toSummary(item entity.PublishAnalytics) domusecase.PublishAnalyticsSummary {
	return domusecase.PublishAnalyticsSummary{
		ID:              item.ID,
		MediaID:         item.MediaID,
		Permalink:       item.Permalink,
		PublishedAt:     item.PublishedAt,
		Checkpoint:      item.Checkpoint,
		LikeCount:       item.LikeCount,
		ReplyCount:      item.ReplyCount,
		RepostCount:     item.RepostCount,
		QuoteCount:      item.QuoteCount,
		ViewCount:       item.ViewCount,
		ShareCount:      item.ShareCount,
		ImpressionCount: item.ImpressionCount,
		ReachCount:      item.ReachCount,
		CheckedAt:       item.CheckedAt,
		CreateAt:        item.CreateAt,
	}
}
