package jobs

import (
	"context"
	"time"

	"quyun/app/models"
	"quyun/database/fields"
	"quyun/database/schemas/public/model"
	"quyun/pkg/utils"
	"quyun/providers/ali"
	"quyun/providers/app"
	"quyun/providers/job"

	"github.com/pkg/errors"
	. "github.com/riverqueue/river"
	"github.com/samber/lo"
	log "github.com/sirupsen/logrus"
	_ "go.ipao.vip/atom"
	"go.ipao.vip/atom/contracts"
)

var _ contracts.JobArgs = (*PublishDraftPosts)(nil)

type PublishDraftPosts struct {
	MediaHash string `json:"media_hash"`
}

func (s PublishDraftPosts) InsertOpts() InsertOpts {
	return InsertOpts{
		Queue:    QueueDefault,
		Priority: PriorityDefault,
	}
}

func (s PublishDraftPosts) Kind() string     { return "publish_draft_posts" }
func (a PublishDraftPosts) UniqueID() string { return a.Kind() }

var _ Worker[PublishDraftPosts] = (*PublishDraftPostsWorker)(nil)

// @provider(job)
type PublishDraftPostsWorker struct {
	WorkerDefaults[PublishDraftPosts]

	oss *ali.OSSClient
	job *job.Job
	app *app.Config
}

func (w *PublishDraftPostsWorker) NextRetry(job *Job[PublishDraftPosts]) time.Time {
	return time.Now().Add(30 * time.Second)
}

func (w *PublishDraftPostsWorker) Work(ctx context.Context, job *Job[PublishDraftPosts]) error {
	log := log.WithField("job", job.Args.Kind())

	log.Infof("[Start] Working on job with strings: %+v", job.Args)
	defer log.Infof("[End] Finished %s", job.Args.Kind())

	media, err := models.Medias.GetByHash(ctx, job.Args.MediaHash)
	if err != nil {
		log.Errorf("Error getting media by ID: %v", err)
		return JobCancel(err)
	}

	relationMedias, err := models.Medias.GetRelations(ctx, media.Hash)
	if err != nil {
		log.Errorf("Error getting relation medias: %v", err)
		return JobCancel(err)
	}

	assets := lo.FilterMap(relationMedias, func(media *model.Medias, _ int) (fields.MediaAsset, bool) {
		return fields.MediaAsset{
			Type:  media.MimeType,
			Media: media.ID,
			Metas: &media.Metas.Data,
		}, media.MimeType != "image/jpeg"
	})
	assets = append(assets, fields.MediaAsset{
		Type:  media.MimeType,
		Media: media.ID,
		Metas: &media.Metas.Data,
	})

	// publish a draft posts
	post := &model.Posts{
		Status:      fields.PostStatusDraft,
		Title:       utils.FormatTitle(media.Name),
		Description: "",
		Content:     "",
		Price:       0,
		Discount:    100,
		Views:       0,
		Likes:       0,
		Tags:        fields.Json[[]string]{},
		Assets:      fields.ToJson(assets),
		HeadImages: fields.ToJson(lo.FilterMap(relationMedias, func(media *model.Medias, _ int) (int64, bool) {
			return media.ID, media.MimeType == "image/jpeg"
		})),
	}
	if err := models.Posts.Create(ctx, post); err != nil {
		log.Errorf("Error creating post: %v", err)
		return errors.Wrap(err, "create post")
	}
	log.Infof("Post created successfully with ID: %d", post.ID)

	return nil
}
