from ...base.firebase_collection import FirebaseCollectionBase
from ....utils import (DictUtils, DateUtils, get_object_model_class, init_class_kwargs, BaseClass, get_request_fields, RequestFields)
from ....utils.response import ApiResponse, Error, ResponseStatus, StatusCode
from .base_campaign_fields import BaseCampaignFieldsProps, STANDARD_FIELDS, BASE_CAMPAIGN_PICKABLE_FIELDS
from typing import Any
from dataclasses import dataclass

from .objective import Objective
from .adchannel import AdChannel
from .ages import Ages
from .genders import Genders
from .locations import Location
from .adschedules import AdsSchedules
from .custom_parameters import CustomParameters
from .devices import Devices


def filter_request_fields(fields, default_fields = BASE_CAMPAIGN_PICKABLE_FIELDS):
    request_fields = get_request_fields(fields, default_fields, [default_fields[0]])
    if request_fields is None or bool(request_fields) is False:
        request_fields = [default_fields[0]]
    return request_fields





@dataclass(init=False)
class BaseCampaign(FirebaseCollectionBase):
    id: str
    id_campagne: int
    name: str
    status: str
    objective: Objective
    adChannel: AdChannel
    startDate: str
    endDate: str
    startDateFormattedGoogle: str
    endDateFormattedGoogle: str
    areaTargetedOption: str
    areaExcludedOption: str
    budget: int
    budgetId: int
    dailyBudget: int
    bid: float
    strategie: str
    urlPromote: str
    ages: list[Ages]
    genders: list[Genders]
    targetedLocations: list[Location]
    excludedLocations: list[Location]
    devicesTargeted: list[Devices]
    devicesExcluded: list[Devices]
    deliveryMethod: str
    trackingTemplate: str
    finalUrlSuffix: str
    accountId: str
    type: str
    is_removed: bool
    isEnded: bool
    isComplete: bool
    isPayed: bool
    publish: bool
    publishing: bool
    budgetEnded: bool
    ad_group_id: int
    ad_group_id_firebase: str
    servingStatus: str
    owner: str
    provider: str
    urlCustomParameters: list[CustomParameters]
    adsSchedules: list[AdsSchedules]
    createdAt: any
    createdBy: any
    clientCustomerId: str
    __realBudget: int
    google_ads_campaign: dict
    _locations_targeted: bool
    _locations_excluded: bool
    _schedules_targeted: bool
    _upgraded_urls_targeted: bool
    _ads_cloned: bool = False
    api_version: str
    __baseFields = BaseCampaignFieldsProps


    def calculate_budget(self, value):
        budget = self.to_budget(value);
        return round((budget * 30)/100)
    def __init__(self, campaign=None, collection_name=None, **kwargs):
        _campaign = campaign;
        if type(campaign) is str:
            _campaign = {'id': campaign};
        (cls_object, keys, data_args) = init_class_kwargs(self, _campaign, STANDARD_FIELDS, BaseCampaignFieldsProps, collection_name, ['id'], **kwargs)
        super().__init__(**data_args);
        for key in keys:
            if key == "objective":
                setattr(self, key, Objective().from_dict(cls_object[key]))
            elif key == "adChannel":
                setattr(self, key, AdChannel().from_dict(cls_object[key]))
            elif key == "ages":
                setattr(self, key, Ages().fromListDict(cls_object[key]))
            elif key == "genders":
                setattr(self, key, Genders().fromListDict(cls_object[key]))
            elif key == "targetedLocations":
                setattr(self, key, Location().fromListDict(cls_object[key]))
            elif key == "excludedLocations":
                setattr(self, key, Location().fromListDict(cls_object[key]))
            elif key == "devicesTargeted":
                setattr(self, key, Devices().fromListDict(cls_object[key]))
            elif key == "devicesExcluded":
                setattr(self, key, Devices().fromListDict(cls_object[key]))
            elif key == "urlCustomParameters":
                setattr(self, key, CustomParameters().fromListDict(cls_object[key]))
            elif key == "adsSchedules":
                setattr(self, key, AdsSchedules().fromListDict(cls_object[key]))
            elif key == "createdAt":
                # print('created at int', type(cls_object[key]))
                # setattr(self, key, cls_object[key]) 
                setattr(self, key, DateUtils.convert_firestore_timestamp_to_str(cls_object[key])) 
            elif key == 'realBudget':
                setattr(self, f"__{key}", cls_object[key])
            elif key == 'budget':
                if 'realBudget' not in cls_object or cls_object['realBudget'] is None or self.to_budget(cls_object['realBudget'])==0 or self.to_budget(cls_object['realBudget']) > self.to_budget(cls_object[key]):
                    setattr(self, 'realBudget', self.calculate_budget(cls_object[key]))
                setattr(self, key, self.to_budget(cls_object[key]))
            else:
                setattr(self, key, cls_object[key]) 
    def to_budget(self, value):
        try:
            if isinstance(value, (int, float)):
                return value
            if float(str(value)) == int(str(value)):
                return int(value)
            return float(str(value))
        except Exception as e:
            raise ApiResponse(ResponseStatus.ERROR, StatusCode.status_500, None, Error(f"{str(e)}","INVALID_REQUEST", 1))
    def ages_to_list(self, ages: list[Ages] | None = None):
        if ages is None:
            return [];
        return Ages().toListDict(ages, None)
    def genders_to_list(self, genders: list[Genders] | None = None):
        if genders is None:
            return [];
        return Genders().toListDict(genders, None)
    def devices_to_list(self, devices: list[Devices] | None = None):
        if devices is None:
            return [];
        return Devices().toListDict(devices, None)
    def locations_to_list(self, locations: list[Location] | None = None, fields=None):
        if locations is None:
            return []
        return Location().toListDict(locations, fields)
    def schedules_to_list(self, schedules: list[AdsSchedules] | None = None, fields=None):
        if schedules is None:
            return []
        return AdsSchedules().toListDict(schedules, fields)
    def custom_parameters_to_list(self, custom_parameters: list[CustomParameters] | None = None, fields=None):
        if custom_parameters is None:
            return []
        return CustomParameters().toListDict(custom_parameters, None, fields)
    
    def list_to_ages(self, ages: list[Ages] | None = None):
        if ages is None:
            return [];
        return Ages().fromListDict(ages, Ages)
    def list_to_genders(self, genders: list[Genders] | None = None):
        if genders is None:
            return [];
        return Genders().fromListDict(genders, Genders)
    def list_to_devices(self, devices: list[Devices] | None = None):
        if devices is None:
            return [];
        return Devices().fromListDict(devices, Devices)
    def is_published(self):
        return self.id_campagne is not None and self.id_campagne > 0
    @staticmethod
    def generate_model(_key_="default_value"):
        campaign = {};
        props = BaseCampaignFieldsProps
        for k in DictUtils.get_keys(props):
            campaign[k] = props[k][_key_];
        return campaign;

    
    def to_dict(self, fields=None):
        createdAt = DateUtils.convert_firestore_timestamp_to_str(self.createdAt)
        id_campagne = self.id_campagne
        ad_group_id = self.ad_group_id
        budget_id = self.budgetId
        ad_group_id_firebase = self.ad_group_id_firebase

        if id_campagne == 0:
            id_campagne = None
        if ad_group_id == 0:
            ad_group_id = None
        if budget_id == 0:
            budget_id = None
        if ad_group_id_firebase == "":
            ad_group_id_firebase = None

        
        return DictUtils.remove_none_values({
            "id": self.id,
            "id_campagne": id_campagne,
            "name": self.name,
            "status": self.status,
            "objective": self.objective.to_dict(None),
            "adChannel": self.adChannel.to_dict(None),
            "startDate": self.startDate,
            "endDate": self.endDate,
            "startDateFormattedGoogle": self.startDateFormattedGoogle,
            "endDateFormattedGoogle": self.endDateFormattedGoogle,  
            "areaTargetedOption": self.areaTargetedOption,
            "areaExcludedOption": self.areaExcludedOption,  
            "budget": self.budget,
            "realBudget": self.__realBudget,
            "budgetId": budget_id,
            "dailyBudget": self.dailyBudget,
            "bid": self.bid,
            "strategie": self.strategie,
            "urlPromote": self.urlPromote,
            "ages": Ages().toListDict(self.ages, None),
            "genders": Genders().toListDict(self.genders, None),
            "targetedLocations": Location().toListDict(self.targetedLocations, None),
            "excludedLocations": Location().toListDict(self.excludedLocations, None),
            "devicesTargeted": Devices().toListDict(self.devicesTargeted, None),
            "devicesExcluded": Devices().toListDict(self.devicesExcluded, None),
            "deliveryMethod": self.deliveryMethod,
            "trackingTemplate": self.trackingTemplate,
            "finalUrlSuffix": self.finalUrlSuffix,
            "accountId": self.accountId,
            "type": self.type,
            "is_removed": self.is_removed,
            "isEnded": self.isEnded,
            "isComplete": self.isComplete,
            "isPayed": self.isPayed,
            "publish": self.publish,
            "publishing": self.publishing,
            "budgetEnded": self.budgetEnded,
            "ad_group_id": ad_group_id,
            "ad_group_id_firebase": ad_group_id_firebase,
            "servingStatus": self.servingStatus,
            "owner": self.owner,
            "provider": self.provider,
            "urlCustomParameters": CustomParameters().toListDict(self.urlCustomParameters, None),
            "adsSchedules": AdsSchedules().toListDict(self.adsSchedules, None),
            "clientCustomerId": self.clientCustomerId,
            "createdAt": createdAt,
            "createdBy": self.createdBy,
            "google_ads_campaign": self.google_ads_campaign,
            "api_version": self.api_version,
        })
        