package copy_mission

import (
	copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase"
	missionentity "haixun-backend/internal/model/copy_mission/domain/entity"
	missiondomain "haixun-backend/internal/model/copy_mission/domain/usecase"
	personadomain "haixun-backend/internal/model/persona/domain/usecase"
	scanpostdomain "haixun-backend/internal/model/scan_post/domain/usecase"
	"haixun-backend/internal/types"
)

func seedMissionResearchFromPersona(persona personadomain.PersonaSummary) (*missionentity.ResearchMap, []string) {
	src := persona.CopyResearchMap
	if src.AudienceSummary == "" && src.ContentGoal == "" && len(src.SuggestedTags) == 0 {
		return nil, nil
	}
	tags := make([]missionentity.SuggestedTag, 0, len(src.SuggestedTags))
	for _, tag := range src.SuggestedTags {
		if tag == "" {
			continue
		}
		tags = append(tags, missionentity.SuggestedTag{Tag: tag})
	}
	selected := append([]string(nil), src.SuggestedTags...)
	if len(selected) > 6 {
		selected = selected[:6]
	}
	rm := &missionentity.ResearchMap{
		AudienceSummary: src.AudienceSummary,
		ContentGoal:     src.ContentGoal,
		Questions:       append([]string(nil), src.Questions...),
		Pillars:         append([]string(nil), src.Pillars...),
		Exclusions:      append([]string(nil), src.Exclusions...),
		SuggestedTags:   tags,
		BenchmarkNotes:  src.BenchmarkNotes,
	}
	return rm, selected
}

func toMissionPatch(req *types.UpdateCopyMissionReq) missiondomain.MissionPatch {
	if req == nil {
		return missiondomain.MissionPatch{}
	}
	patch := missiondomain.MissionPatch{
		Label:     req.Label,
		SeedQuery: req.SeedQuery,
		Brief:     req.Brief,
	}
	if req.AudienceSummary != nil {
		patch.AudienceSummary = req.AudienceSummary
	}
	if req.ContentGoal != nil {
		patch.ContentGoal = req.ContentGoal
	}
	if req.Questions != nil {
		patch.QuestionsSet = true
		patch.Questions = append([]string(nil), req.Questions...)
	}
	if req.Pillars != nil {
		patch.PillarsSet = true
		patch.Pillars = append([]string(nil), req.Pillars...)
	}
	if req.Exclusions != nil {
		patch.ExclusionsSet = true
		patch.Exclusions = append([]string(nil), req.Exclusions...)
	}
	if req.BenchmarkNotes != nil {
		patch.BenchmarkNotes = req.BenchmarkNotes
	}
	if req.SelectedTags != nil {
		patch.SelectedTagsSet = true
		patch.SelectedTags = append([]string(nil), req.SelectedTags...)
	}
	return patch
}

func toCopyMissionData(item missiondomain.MissionSummary) types.CopyMissionData {
	tags := make([]types.CopySuggestedTagData, 0, len(item.ResearchMap.SuggestedTags))
	for _, tag := range item.ResearchMap.SuggestedTags {
		tags = append(tags, types.CopySuggestedTagData{
			Tag:          tag.Tag,
			Reason:       tag.Reason,
			SearchIntent: tag.SearchIntent,
			SearchType:   tag.SearchType,
		})
	}
	accounts := make([]types.CopySimilarAccountData, 0, len(item.ResearchMap.SimilarAccounts))
	for _, acc := range item.ResearchMap.SimilarAccounts {
		accounts = append(accounts, types.CopySimilarAccountData{
			Username:        acc.Username,
			Reason:          acc.Reason,
			Source:          acc.Source,
			Confidence:      acc.Confidence,
			ProfileUrl:      acc.ProfileURL,
			AuthorVerified:  acc.AuthorVerified,
			FollowerCount:   acc.FollowerCount,
			EngagementScore: acc.EngagementScore,
			LikeCount:       acc.LikeCount,
			ReplyCount:      acc.ReplyCount,
			PostCount:       acc.PostCount,
		})
	}
	return types.CopyMissionData{
		ID:        item.ID,
		PersonaID: item.PersonaID,
		Label:     item.Label,
		SeedQuery: item.SeedQuery,
		Brief:     item.Brief,
		ResearchMap: types.CopyMissionResearchMapData{
			AudienceSummary: item.ResearchMap.AudienceSummary,
			ContentGoal:     item.ResearchMap.ContentGoal,
			Questions:       append([]string(nil), item.ResearchMap.Questions...),
			Pillars:         append([]string(nil), item.ResearchMap.Pillars...),
			Exclusions:      append([]string(nil), item.ResearchMap.Exclusions...),
			SuggestedTags:   tags,
			SimilarAccounts: accounts,
			BenchmarkNotes:  item.ResearchMap.BenchmarkNotes,
		},
		SelectedTags:  append([]string(nil), item.SelectedTags...),
		LastScanJobID: item.LastScanJobID,
		Status:        item.Status,
		CreateAt:      item.CreateAt,
		UpdateAt:      item.UpdateAt,
	}
}

func toListData(result *missiondomain.ListResult) *types.ListCopyMissionsData {
	if result == nil {
		return &types.ListCopyMissionsData{List: []types.CopyMissionData{}}
	}
	list := make([]types.CopyMissionData, 0, len(result.List))
	for _, item := range result.List {
		list = append(list, toCopyMissionData(item))
	}
	return &types.ListCopyMissionsData{List: list}
}

func toEntityResearchMap(data types.CopyMissionResearchMapData) missionentity.ResearchMap {
	tags := make([]missionentity.SuggestedTag, 0, len(data.SuggestedTags))
	for _, tag := range data.SuggestedTags {
		tags = append(tags, missionentity.SuggestedTag{
			Tag:          tag.Tag,
			Reason:       tag.Reason,
			SearchIntent: tag.SearchIntent,
			SearchType:   tag.SearchType,
		})
	}
	accounts := make([]missionentity.SimilarAccount, 0, len(data.SimilarAccounts))
	for _, acc := range data.SimilarAccounts {
		accounts = append(accounts, missionentity.SimilarAccount{
			Username:        acc.Username,
			Reason:          acc.Reason,
			Source:          acc.Source,
			Confidence:      acc.Confidence,
			ProfileURL:      acc.ProfileUrl,
			AuthorVerified:  acc.AuthorVerified,
			FollowerCount:   acc.FollowerCount,
			EngagementScore: acc.EngagementScore,
			LikeCount:       acc.LikeCount,
			ReplyCount:      acc.ReplyCount,
			PostCount:       acc.PostCount,
		})
	}
	return missionentity.ResearchMap{
		AudienceSummary: data.AudienceSummary,
		ContentGoal:     data.ContentGoal,
		Questions:       append([]string(nil), data.Questions...),
		Pillars:         append([]string(nil), data.Pillars...),
		Exclusions:      append([]string(nil), data.Exclusions...),
		SuggestedTags:   tags,
		SimilarAccounts: accounts,
		BenchmarkNotes:  data.BenchmarkNotes,
	}
}

func toViralScanPostsData(posts []scanpostdomain.ScanPostSummary) *types.ListPersonaViralScanPostsData {
	list := make([]types.ViralScanPostData, 0, len(posts))
	for _, post := range posts {
		list = append(list, types.ViralScanPostData{
			ID:              post.ID,
			SearchTag:       post.SearchTag,
			Permalink:       post.Permalink,
			Author:          post.Author,
			AuthorVerified:  post.AuthorVerified,
			FollowerCount:   post.FollowerCount,
			Text:            post.Text,
			LikeCount:       post.LikeCount,
			ReplyCount:      post.ReplyCount,
			EngagementScore: post.EngagementScore,
			Source:          post.Source,
			ScanJobID:       post.ScanJobID,
			Replies:         toScanReplyData(post.Replies),
			CreateAt:        post.CreateAt,
		})
	}
	return &types.ListPersonaViralScanPostsData{List: list, Total: len(list)}
}

func toScanReplyData(replies []scanpostdomain.ScanReplySummary) []types.ScanReplyData {
	if len(replies) == 0 {
		return nil
	}
	out := make([]types.ScanReplyData, 0, len(replies))
	for _, reply := range replies {
		out = append(out, types.ScanReplyData{
			ExternalID: reply.ExternalID,
			Author:     reply.Author,
			Text:       reply.Text,
			Permalink:  reply.Permalink,
			LikeCount:  reply.LikeCount,
			PostedAt:   reply.PostedAt,
		})
	}
	return out
}

func toCopyDraftData(item copydraftdomain.CopyDraftSummary) types.CopyDraftData {
	return types.CopyDraftData{
		ID:                 item.ID,
		PersonaID:          item.PersonaID,
		CopyMissionID:      item.CopyMissionID,
		ScanPostID:         item.ScanPostID,
		DraftType:          item.DraftType,
		SortOrder:          item.SortOrder,
		Text:               item.Text,
		Angle:              item.Angle,
		Hook:               item.Hook,
		Rationale:          item.Rationale,
		ReferenceNotes:     item.ReferenceNotes,
		Sources:            item.Sources,
		Status:             item.Status,
		PublishedMediaID:   item.PublishedMediaID,
		PublishedPermalink: item.PublishedPermalink,
		PublishedAt:        item.PublishedAt,
		CreateAt:           item.CreateAt,
	}
}
