package persona

import (
	"context"
	"strings"

	app "haixun-backend/internal/library/errors"
	"haixun-backend/internal/library/errors/code"
	libthreads "haixun-backend/internal/library/threadsapi"
	"haixun-backend/internal/library/threadspost"
	copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
	"haixun-backend/internal/svc"
	"haixun-backend/internal/types"
)

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

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

func (l *PublishPersonaCopyDraftLogic) PublishPersonaCopyDraft(
	req *types.PublishCopyDraftHandlerReq,
) (*types.PublishCopyDraftData, error) {
	tenantID, uid, err := actorFrom(l.ctx)
	if err != nil {
		return nil, err
	}
	personaID := strings.TrimSpace(req.ID)
	draftID := strings.TrimSpace(req.DraftID)
	if !req.Confirm {
		return nil, app.For(code.Persona).InputMissingRequired("請確認 confirm=true 後再發布貼文")
	}
	if _, err := l.svcCtx.Persona.Get(l.ctx, tenantID, uid, personaID); err != nil {
		return nil, err
	}

	draftItem, err := l.svcCtx.CopyDraft.Get(l.ctx, tenantID, uid, personaID, draftID)
	if err != nil {
		return nil, err
	}
	draft := draftItem
	if draft.Status == "published" {
		return nil, app.For(code.Persona).ResInvalidState("此草稿已發布")
	}

	text := strings.TrimSpace(req.Text)
	if text == "" {
		text = strings.TrimSpace(draft.Text)
	}
	if text == "" {
		return nil, app.For(code.Persona).InputMissingRequired("text is required")
	}
	if err := threadspost.ValidatePublish(text); err != nil {
		return nil, app.For(code.Persona).InputInvalidFormat(err.Error())
	}
	if strings.TrimSpace(req.Text) != "" && req.Text != draft.Text {
		updatedText, err := l.svcCtx.CopyDraft.Update(l.ctx, copydraftdomain.UpdateRequest{
			TenantID:  tenantID,
			OwnerUID:  uid,
			PersonaID: personaID,
			DraftID:   draftID,
			Patch:     copydraftdomain.CopyDraftPatch{Text: &req.Text},
		})
		if err != nil {
			return nil, err
		}
		draft = updatedText
		text = strings.TrimSpace(updatedText.Text)
	}

	cred, err := l.svcCtx.ThreadsAccount.ResolveMemberThreadsPublishCredential(l.ctx, tenantID, uid)
	if err != nil {
		return nil, err
	}
	result, err := libthreads.PublishText(l.ctx, libthreads.PublishTextInput{
		ThreadsUserID: cred.ThreadsUserID,
		AccessToken:   cred.AccessToken,
		Text:          text,
	})
	if err != nil {
		return nil, app.For(code.ThreadsAccount).SvcThirdParty("Threads API 發布貼文失敗：" + err.Error())
	}

	updated, err := l.svcCtx.CopyDraft.MarkPublished(l.ctx, copydraftdomain.MarkPublishedRequest{
		TenantID:  tenantID,
		OwnerUID:  uid,
		PersonaID: personaID,
		DraftID:   draftID,
		MediaID:   result.MediaID,
		Permalink: result.Permalink,
	})
	if err != nil {
		return nil, err
	}

	return &types.PublishCopyDraftData{
		DraftID:   draftID,
		MediaID:   result.MediaID,
		Permalink: result.Permalink,
		Status:    updated.Status,
		Message:   "仿寫貼文已透過 Threads API 發布",
	}, nil
}
