from dostadmin import db, app_logger
from dostadmin.db_model import PreCalculatedUserCampaignData, Campaign
from utils.helpers.helpers import get_current_isttime, is_current_date_timestamp


class PreCalculatedCampaignService:
    def add_new_experience(self, experience_id):
        new_campaign_data = PreCalculatedUserCampaignData(
            experience_id=experience_id, is_eligible_to_call=True
        )
        db.session.add(new_campaign_data)
        db.session.commit()
        return new_campaign_data

    def update_pre_calculated_user_campaign_data(self, campaign_data):
        mapping = {
            "cron_regular": {
                "previous_campaign_id": "previous_regular_campaign_id",
                "previous_campaign_name": "previous_campaign_name",
                "previous_call_deploy_time": "previous_regular_call_deploy_time",
                "previous_content_id": "previous_content_id",
                "previous_content_version_id": "previous_content_version_id",
                "previous_campaign_status": "previous_regular_campaign_status",
            },
            "cron_missed_call": {
                "previous_campaign_id": "previous_missed_call_campaign_id",
                "previous_campaign_name": "previous_campaign_name",
                "previous_call_deploy_time": "previous_missed_call_deploy_time",
                "previous_content_id": "previous_content_id",
                "previous_content_version_id": "previous_content_version_id",
                "previous_campaign_status": "previous_missed_call_campaign_status",
            },
            "cron_nudge": {
                "previous_campaign_id": "previous_nudge_campaign_id",
                "previous_campaign_name": "previous_nudge_campaign_name",
                "previous_call_deploy_time": "previous_nudge_call_deploy_time",
                "previous_content_id": "previous_nudge_content_id",
                "previous_content_version_id": "previous_nudge_content_version_id",
                "previous_campaign_status": "previous_nudge_campaign_status",
            },
            "ui_manual": {
                "previous_campaign_id": "previous_blast_campaign_id",
                "previous_campaign_name": "previous_blast_campaign_name",
                "previous_call_deploy_time": "previous_blast_call_deploy_time",
                "previous_content_id": "previous_blast_content_id",
                "previous_content_version_id": "previous_blast_content_version_id",
                "previous_campaign_status": "previous_blast_call_campaign_status",
            },
        }

        experience_id = campaign_data.get("experience_id")
        scheduled_by = campaign_data.get("scheduled_by")
        if experience_id is None:
            return
        pre_calculated_campaign_data = (
            PreCalculatedUserCampaignData.query.get_data_by_experience_id(experience_id)
        )

        if not pre_calculated_campaign_data:
            pre_calculated_campaign_data = self.add_new_experience(experience_id)

        if scheduled_by not in mapping:
            return

        try:
            if campaign_data.get("exotel_status") is None:
                if campaign_data.get("campaign_id") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_campaign_id"],
                        campaign_data.get("campaign_id"),
                    )
                if campaign_data.get("campaign_name") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_campaign_name"],
                        campaign_data.get("campaign_name"),
                    )
                if campaign_data.get("deploy_datetime") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_call_deploy_time"],
                        campaign_data.get("deploy_datetime"),
                    )

                if campaign_data.get("content_id") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_content_id"],
                        campaign_data.get("content_id"),
                    )

                if campaign_data.get("content_version_id") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_content_version_id"],
                        campaign_data.get("content_version_id"),
                    )

                if campaign_data.get("campaign_status") is not None:
                    pre_calculated_campaign_data.__setattr__(
                        mapping[scheduled_by]["previous_campaign_status"],
                        campaign_data.get("campaign_status"),
                    )

                pre_calculated_campaign_data.call_details_for_date = (
                    get_current_isttime()
                )
                db.session.commit()
            else:
                call_status = Campaign.get_campaign_status_from_exotel_status(
                    campaign_data.get("exotel_status")
                )
                pre_calculated_campaign_data.__setattr__(
                    mapping[scheduled_by]["previous_campaign_status"], call_status
                )
                db.session.commit()
        except Exception as error:
            app_logger.error(
                f"Pre Calculated Campaign Service: Error while updating details for experience {experience_id}. Exception: {error}"
            )

    def get_previous_campaign_data(
        self,
        pre_calculated_user_campaign,
        only_content_call=False,
        only_non_content_call=False,
    ):
        data = {
            "campaign_id": pre_calculated_user_campaign.previous_regular_campaign_id,
            "status": pre_calculated_user_campaign.previous_regular_campaign_status,
            "deploy_time": pre_calculated_user_campaign.previous_regular_call_deploy_time,
            "campaign_name": pre_calculated_user_campaign.previous_campaign_name,
            "scheduled_by": Campaign.ScheduledBy.CRON_REGULAR,
        }

        if data.get("deploy_time") is None:
            data[
                "deploy_time"
            ] = pre_calculated_user_campaign.previous_missed_call_deploy_time

        if data.get("deploy_time") is None:
            return data

        if data.get("deploy_time") is None or (
            pre_calculated_user_campaign.previous_missed_call_deploy_time
            and pre_calculated_user_campaign.previous_missed_call_deploy_time
            >= data.get("deploy_time")
        ):
            data[
                "campaign_id"
            ] = pre_calculated_user_campaign.previous_missed_call_campaign_id
            data[
                "status"
            ] = pre_calculated_user_campaign.previous_missed_call_campaign_status
            data["scheduled_by"] = Campaign.ScheduledBy.CRON_MISSED_CALL
            data[
                "deploy_time"
            ] = pre_calculated_user_campaign.previous_missed_call_deploy_time

        if only_non_content_call:
            data = {
                "deploy_time": pre_calculated_user_campaign.previous_nudge_call_deploy_time
            }

        if not only_content_call:
            is_current_date_call = is_current_date_timestamp(
                pre_calculated_user_campaign.previous_nudge_call_deploy_time
            )

            if is_current_date_call and (
                data.get("deploy_time") is None
                or pre_calculated_user_campaign.previous_nudge_call_deploy_time
                > data.get("deploy_time")
            ):
                data[
                    "campaign_id"
                ] = pre_calculated_user_campaign.previous_nudge_campaign_id
                data[
                    "status"
                ] = pre_calculated_user_campaign.previous_nudge_campaign_status
                data[
                    "deploy_time"
                ] = pre_calculated_user_campaign.previous_nudge_call_deploy_time
                data[
                    "campaign_name"
                ] = pre_calculated_user_campaign.previous_nudge_campaign_name
                data["scheduled_by"] = Campaign.ScheduledBy.CRON_NUDGE

            is_current_date_call = is_current_date_timestamp(
                pre_calculated_user_campaign.previous_blast_call_deploy_time
            )

            if is_current_date_call and (
                data.get("deploy_time") is None
                or pre_calculated_user_campaign.previous_blast_call_deploy_time
                > data.get("deploy_time")
            ):
                data[
                    "campaign_id"
                ] = pre_calculated_user_campaign.previous_blast_campaign_id
                data[
                    "status"
                ] = pre_calculated_user_campaign.previous_blast_call_campaign_status
                data[
                    "deploy_time"
                ] = pre_calculated_user_campaign.previous_blast_call_deploy_time
                data[
                    "campaign_name"
                ] = pre_calculated_user_campaign.previous_blast_campaign_name
                data["scheduled_by"] = Campaign.ScheduledBy.UI_MANUAL

        return data

    def get_user_campaign_data_dict(self, users_campaign_data_list):
        users_campaign_data_dict = {}

        for user_campaign_data in users_campaign_data_list:
            users_campaign_data_dict[
                user_campaign_data.experience_id
            ] = user_campaign_data

        return users_campaign_data_dict
