package kz.konturai.parser.dto.targeting;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.List;

/**
 * Root DTO for parsing the Targeting Orchestrator response.
 * Maps the AI output to concrete typed objects.
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class TargetingOrchestrationDto {

    @NotBlank
    private String orchestrationId;

    @NotNull
    private PlatformTarget platformTarget;

    @Valid
    @NotNull
    private List<CampaignDto> campaigns;

    @Valid
    @NotNull
    private List<AutomationRuleDto> automationRules;

    public enum PlatformTarget {
        META_ADS, GOOGLE_ADS, TIKTOK_ADS
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class CampaignDto {
        @NotBlank
        private String campaignName;
        
        @NotBlank
        private String objective;
        
        private List<String> specialAdCategories;
        
        @NotBlank
        private String buyingType;
        
        @NotNull
        @Valid
        private BudgetStrategyDto budgetStrategy;
        
        @NotNull
        @Valid
        private List<AdSetDto> adsets;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class BudgetStrategyDto {
        @NotNull
        private Boolean isCbo;
        
        private BigDecimal campaignDailyBudgetUsd;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class AdSetDto {
        @NotBlank
        private String adsetName;
        
        @NotNull
        @Min(0)
        private BigDecimal dailyBudgetUsd;
        
        @NotBlank
        private String optimizationGoal;
        
        @NotBlank
        private String billingEvent;
        
        @NotBlank
        private String bidStrategy;
        
        @NotNull
        @Valid
        private TargetingDto targeting;
        
        @NotNull
        @Valid
        private List<AdDto> ads;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class TargetingDto {
        @NotNull
        @Valid
        private GeoLocationsDto geoLocations;
        
        @NotNull
        private Integer ageMin;
        
        @NotNull
        private Integer ageMax;
        
        private List<Integer> genders;
        
        @Valid
        private List<FlexibleSpecDto> flexibleSpec;
        
        @Valid
        private ExclusionsDto exclusions;
        
        private List<String> publisherPlatforms;
        
        private List<String> devicePlatforms;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class GeoLocationsDto {
        private List<String> countries;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class FlexibleSpecDto {
        @Valid
        private List<InterestDto> interests;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class InterestDto {
        @NotBlank
        private String id;
        
        @NotBlank
        private String name;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class ExclusionsDto {
        @Valid
        private List<CustomAudienceDto> customAudiences;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class CustomAudienceDto {
        @NotBlank
        private String id;
        
        @NotBlank
        private String name;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class AdDto {
        @NotBlank
        private String adName;
        
        @NotNull
        @Valid
        private CreativePayloadDto creativePayload;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class CreativePayloadDto {
        @NotBlank
        private String assetId;
        
        @NotBlank
        private String bodyTextId;
        
        @NotBlank
        private String headlineId;
        
        @NotBlank
        private String callToAction;
        
        @NotBlank
        private String destinationUrl;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class AutomationRuleDto {
        @NotBlank
        private String ruleId;
        
        @NotBlank
        private String entityLevel;
        
        @NotNull
        private ConditionGroup conditionGroup;
        
        @NotNull
        @Valid
        private List<ConditionDto> conditions;
        
        @NotBlank
        private String action;
        
        private BigDecimal actionValue;
    }

    public enum ConditionGroup {
        AND, OR
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
    public static class ConditionDto {
        @NotBlank
        private String metric;
        
        @NotNull
        private Operator operator;
        
        @NotNull
        private BigDecimal value;
    }

    public enum Operator {
        EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, IN, NOT_IN
    }
}
