package copy_mission

import (
	"context"
	"strings"

	app "haixun-backend/internal/library/errors"
	"haixun-backend/internal/library/errors/code"
	missionentity "haixun-backend/internal/model/copy_mission/domain/entity"
	jobdom "haixun-backend/internal/model/job/domain/usecase"
	"haixun-backend/internal/svc"
	"haixun-backend/internal/types"
)

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

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

func (l *UpsertCopyMissionScanScheduleLogic) UpsertCopyMissionScanSchedule(
	req *types.UpsertCopyMissionScanScheduleHandlerReq,
) (*types.CopyMissionScanScheduleData, error) {
	tenantID, uid, err := actorFrom(l.ctx)
	if err != nil {
		return nil, err
	}
	personaID := strings.TrimSpace(req.PersonaID)
	missionID := strings.TrimSpace(req.ID)
	if _, err := l.svcCtx.Persona.Get(l.ctx, tenantID, uid, personaID); err != nil {
		return nil, err
	}
	mission, err := l.svcCtx.CopyMission.Get(l.ctx, tenantID, uid, personaID, missionID)
	if err != nil {
		return nil, err
	}
	if mission.Status == string(missionentity.StatusArchived) {
		return nil, app.For(code.Persona).ResInvalidState("已封存的任務無法設定排程")
	}
	if req.Enabled && len(mission.SelectedTags) == 0 {
		return nil, app.For(code.Persona).InputMissingRequired("啟用排程前請先勾選並儲存搜尋標籤")
	}

	cronExpr := "0 9 * * *"
	timezone := "Asia/Taipei"
	if strings.TrimSpace(req.Cron) != "" {
		cronExpr = strings.TrimSpace(req.Cron)
	}
	if strings.TrimSpace(req.Timezone) != "" {
		timezone = strings.TrimSpace(req.Timezone)
	}

	research, err := l.svcCtx.Placement.ResearchSettings(l.ctx, tenantID, uid)
	if err != nil {
		return nil, err
	}
	memberCtx, err := l.svcCtx.ThreadsAccount.ResolveMemberPlacementContext(l.ctx, tenantID, uid, research)
	if err != nil {
		return nil, err
	}

	payload := map[string]any{
		"persona_id":      personaID,
		"copy_mission_id": missionID,
		"bootstrap":       false,
		"scheduled":       true,
	}
	for key, value := range memberCtx.PayloadFields() {
		payload[key] = value
	}

	existing, err := findCopyMissionScanSchedule(l.ctx, l.svcCtx, missionID)
	if err != nil {
		return nil, err
	}
	if existing != nil {
		updated, err := l.svcCtx.Job.UpdateSchedule(l.ctx, jobdom.UpdateScheduleRequest{
			ID:              existing.ID.Hex(),
			Cron:            cronExpr,
			Timezone:        timezone,
			PayloadTemplate: payload,
			Enabled:         &req.Enabled,
		})
		if err != nil {
			return nil, err
		}
		return toCopyMissionScanScheduleData(updated, personaID, missionID), nil
	}

	created, err := l.svcCtx.Job.CreateSchedule(l.ctx, jobdom.CreateScheduleRequest{
		TemplateType:    viralScanTemplate,
		Scope:           "copy_mission",
		ScopeID:         missionID,
		Cron:            cronExpr,
		Timezone:        timezone,
		PayloadTemplate: payload,
		Enabled:         req.Enabled,
	})
	if err != nil {
		return nil, err
	}
	return toCopyMissionScanScheduleData(created, personaID, missionID), nil
}
