package persona

import (
	"context"
	"math"

	copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
	pqdomain "haixun-backend/internal/model/publish_queue/domain/usecase"
	"haixun-backend/internal/svc"
	"haixun-backend/internal/types"
)

type ListPersonaContentInboxLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewListPersonaContentInboxLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListPersonaContentInboxLogic {
	return &ListPersonaContentInboxLogic{ctx: ctx, svcCtx: svcCtx}
}

func (l *ListPersonaContentInboxLogic) ListPersonaContentInbox(req *types.ListPersonaContentInboxHandlerReq) (*types.ListPersonaContentInboxData, error) {
	tenantID, uid, err := actorFrom(l.ctx)
	if err != nil {
		return nil, err
	}
	personaID := req.ID
	if _, err := l.svcCtx.Persona.Get(l.ctx, tenantID, uid, personaID); err != nil {
		return nil, err
	}
	page := int(req.Page)
	if page <= 0 {
		page = 1
	}
	pageSize := int(req.PageSize)
	if pageSize <= 0 {
		pageSize = 12
	}
	result, err := l.svcCtx.CopyDraft.ListInbox(l.ctx, copydraftdomain.InboxListRequest{
		TenantID:   tenantID,
		OwnerUID:   uid,
		PersonaID:  personaID,
		Status:     req.Status,
		RangeStart: req.RangeStart,
		RangeEnd:   req.RangeEnd,
		Page:       page,
		PageSize:   pageSize,
	})
	if err != nil {
		return nil, err
	}

	queueIDs := make([]string, 0)
	for _, item := range result.Items {
		if item.PublishQueueID != "" {
			queueIDs = append(queueIDs, item.PublishQueueID)
		}
	}
	queueByID := map[string]pqdomain.QueueItemSummary{}
	if len(queueIDs) > 0 {
		queueItems, qerr := l.svcCtx.PublishQueue.ListByIDs(l.ctx, tenantID, uid, queueIDs)
		if qerr == nil {
			for _, q := range queueItems {
				queueByID[q.ID] = q
			}
		}
	}

	list := make([]types.ContentInboxItemData, 0, len(result.Items))
	for _, item := range result.Items {
		queueItem := queueByID[item.PublishQueueID]
		scheduledAt := queueItem.ScheduledAt
		lifecycle, groupDate := inboxLifecycle(item, scheduledAt)
		draftData := toCopyDraftData(item)
		if queueItem.TopicTag != "" {
			draftData.TopicTag = queueItem.TopicTag
		}
		list = append(list, types.ContentInboxItemData{
			CopyDraftData: draftData,
			ScheduledAt:   scheduledAt,
			Lifecycle:     lifecycle,
			GroupDate:     groupDate,
		})
	}

	totalPages := int64(0)
	if pageSize > 0 {
		totalPages = int64(math.Ceil(float64(result.Total) / float64(pageSize)))
	}
	return &types.ListPersonaContentInboxData{
		Pagination: types.PaginationData{
			Total:      result.Total,
			Page:       int64(page),
			PageSize:   int64(pageSize),
			TotalPages: totalPages,
		},
		List: list,
	}, nil
}

func inboxLifecycle(item copydraftdomain.CopyDraftSummary, scheduledAt int64) (lifecycle string, groupDate int64) {
	if item.PublishedAt > 0 {
		return "published", item.PublishedAt
	}
	if item.PublishQueueID != "" || scheduledAt > 0 {
		if scheduledAt > 0 {
			return "scheduled", scheduledAt
		}
		return "scheduled", item.CreateAt
	}
	return "draft", item.CreateAt
}
