package job

import (
	"context"
	"strings"

	branddomain "haixun-backend/internal/model/brand/domain/usecase"
	topicdomain "haixun-backend/internal/model/placement_topic/domain/usecase"
)

type placementScope struct {
	TopicID      string
	CatalogBrand string
	Topic        *topicdomain.TopicSummary
	Brand        *branddomain.BrandSummary
}

func topicIDFromPayload(payload map[string]any) string {
	return strings.TrimSpace(stringField(payload, "topic_id"))
}

func resolvePlacementScope(
	ctx context.Context,
	brandUC branddomain.UseCase,
	topicUC topicdomain.UseCase,
	tenantID, ownerUID string,
	payload map[string]any,
) (*placementScope, error) {
	topicID := topicIDFromPayload(payload)
	catalogBrandID := strings.TrimSpace(stringField(payload, "brand_id"))
	if catalogBrandID == "" {
		catalogBrandID = brandIDFromPayload(payload)
	}
	if topicID != "" {
		topic, err := topicUC.Get(ctx, tenantID, ownerUID, topicID)
		if err != nil {
			return nil, err
		}
		catalogBrandID = topic.BrandID
		catalog, err := brandUC.Get(ctx, tenantID, ownerUID, catalogBrandID)
		if err != nil {
			return nil, err
		}
		merged := *catalog
		merged.TopicName = topic.TopicName
		merged.SeedQuery = topic.SeedQuery
		merged.Brief = topic.Brief
		merged.ProductID = topic.ProductID
		merged.ResearchMap = topic.ResearchMap
		return &placementScope{
			TopicID:      topicID,
			CatalogBrand: catalogBrandID,
			Topic:        topic,
			Brand:        &merged,
		}, nil
	}
	brand, err := brandUC.Get(ctx, tenantID, ownerUID, catalogBrandID)
	if err != nil {
		return nil, err
	}
	return &placementScope{
		CatalogBrand: catalogBrandID,
		Brand:        brand,
	}, nil
}

func placementTopicAsBrand(scope *placementScope, topic *topicdomain.TopicSummary) *branddomain.BrandSummary {
	if scope == nil || scope.Brand == nil || topic == nil {
		return scope.Brand
	}
	out := *scope.Brand
	out.TopicName = topic.TopicName
	out.SeedQuery = topic.SeedQuery
	out.Brief = topic.Brief
	out.ProductID = topic.ProductID
	out.ResearchMap = topic.ResearchMap
	return &out
}

func reloadScopeBrand(
	ctx context.Context,
	deps ExpandGraphDeps,
	tenantID, ownerUID string,
	scope *placementScope,
) (*branddomain.BrandSummary, error) {
	if scope == nil || scope.Brand == nil {
		return nil, nil
	}
	if scope.TopicID != "" && deps.PlacementTopic != nil {
		topic, err := deps.PlacementTopic.Get(ctx, tenantID, ownerUID, scope.TopicID)
		if err != nil {
			return nil, err
		}
		return placementTopicAsBrand(scope, topic), nil
	}
	if deps.Brand != nil && strings.TrimSpace(scope.CatalogBrand) != "" {
		return deps.Brand.Get(ctx, tenantID, ownerUID, scope.CatalogBrand)
	}
	return scope.Brand, nil
}
