package newsrepository

import (
	"fmt"
	categorydomain "legalgo-BE-go/internal/domain/category"
	newsdomain "legalgo-BE-go/internal/domain/news"
	tagdomain "legalgo-BE-go/internal/domain/tag"

	"gorm.io/gorm/clause"
)

func (a *accessor) Update(spec newsdomain.News) error {
	tx := a.db.Begin()
	if err := tx.Clauses(clause.OnConflict{
		Columns: []clause.Column{{Name: "id"}},
		DoUpdates: clause.AssignmentColumns([]string{
			"title",
			"content",
			"featured_image",
			"is_premium",
			"slug",
			"author_id",
			"live_at",
			"updated_at",
		}),
	}).Select(
		"title",
		"content",
		"featured_image",
		"is_premium",
		"slug",
		"author_id",
		"live_at",
		"updated_at",
	).Save(&spec).Error; err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to update news: %v", err)
	}

	tagsDeleted := make([]tagdomain.Tag, len(spec.Tags))
	copy(tagsDeleted, spec.Tags)
	if err := tx.Model(&spec).Association("Tags").Clear(); err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to remove previous tags: %v", err)
	}

	if err := tx.Model(&spec).Association("Tags").Append(tagsDeleted); err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to add tags: %v", err)
	}

	categoriesDeleted := make([]categorydomain.Category, len(spec.Categories))
	copy(categoriesDeleted, spec.Categories)
	if err := tx.Model(&spec).Association("Categories").Clear(); err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to remove previous categories: %v", err)
	}

	if err := tx.Model(&spec).Association("Categories").Append(categoriesDeleted); err != nil {
		tx.Rollback()
		return fmt.Errorf("failed to add categories: %v", err)
	}

	if err := tx.Commit().Error; err != nil {
		return fmt.Errorf("failed to commit transaction: %v", err)
	}

	return nil
}
