from flask import Blueprint, request
import requests
import logging
from datetime import datetime, timedelta
from firebase.firebase import Firebase
import pytz 
import utility.function as func
import os
import uuid
from feature.automation.node import *
from feature.audience.audience_builder import AudinceBuilder
logging.basicConfig(level=logging.INFO)

audience_scheduled = Blueprint('audience_scheduled', __name__, url_prefix='/audience/scheduled')

fb = Firebase(host=os.environ.get("FIREBASE_HOST"))
timezone = pytz.timezone('Asia/Bangkok')

def is_divisible_hour(n: int, hour_str: str) -> bool:
    # hour_str format: "HH:MM"
    hour = int(hour_str.split(":")[0])
    return hour % n == 0

def handel_audience_recal(audience_context:dict):
    builder = AudinceBuilder(json=audience_context, cache=False)
    valid, message = builder._validate_json_data()
    if not valid:
        return {'status': 'error', 'message': message}, 500

    final_result = builder.get_final_audience()
    total_audience = len(final_result)
    return final_result, total_audience

def handel_set_new_audience_data(property_id, audience_id, final_result:list, total_audience:int):
    fb.db.reference().child(f"account/{property_id}/audience/{audience_id}/total_audience").set(int(total_audience))
    fb.db.reference().child(f"account/{property_id}/audience/{audience_id}/user_pseudo_ids").set(final_result)
    return True


@audience_scheduled.route('/calculate',  methods=['POST'])
@audience_scheduled.route('/calculate/',  methods=['POST'])
def audience_scheduled_calculate():
    try:
        date_str = datetime.now(timezone).strftime("%Y%m%d%H00")
        now_hour = datetime.now(timezone).strftime("%H:00")
        prefix_logging = "audience_scheduled_calculate"
        logging.info(f"{prefix_logging}: START JOB")

        fb_ref = fb.db.reference()

        accounts = fb_ref.child("account").get(shallow=True)
        
        for account in accounts:
            log_job = []
            audiences = fb_ref.child(f"account/{account}/audience/").get(shallow=True)
            if not audiences:
                continue
            for audience in audiences:
                is_active = fb_ref.child(f"account/{account}/audience/{audience}/active").get()
                if not is_active:
                    continue
                setting = fb_ref.child(f"account/{account}/audience/{audience}/settings").get()
                cal_type = setting['type']
                if cal_type != 'dynamic':
                    continue

                calculation = setting['calculation']
                calculation_type = calculation['type']
                calculation_time = calculation['time']

                if calculation_type == 'daily':
                    if now_hour == calculation_time:
                        #Re-cal
                        audience_context = fb_ref.child(f"account/{account}/audience/{audience}").get()
                        final_result, total_audience = handel_audience_recal(audience_context)
                        result = handel_set_new_audience_data(account, audience, final_result, total_audience)

                        log_job.append(
                            {
                                "property_id": account,
                                "audience_id": audience,
                                "status": result,
                            }
                        )
                        fb_ref.child(f"account/{account}/audience/{audience}/lastupdate").set(datetime.now(timezone).isoformat())

                elif calculation_type == 'hourly':
                    if is_divisible_hour(int(calculation_time)):
                        #Re-cal
                        audience_context = fb_ref.child(f"account/{account}/audience/{audience}").get()
                        final_result, total_audience = handel_audience_recal(audience_context)
                        result = handel_set_new_audience_data(account, audience, final_result, total_audience)
                        
                        log_job.append(
                            {
                                "property_id": account,
                                "audience_id": audience,
                                "status": result,
                            }
                        )
                        fb_ref.child(f"account/{account}/audience/{audience}/lastupdate").set(datetime.now(timezone).isoformat())
            fb_ref.child(f"account/{account}/job/log/audience/{date_str}").set(log_job)
        
        return {'status': 'ok'}, 200

    except Exception as e:
        logging.error(f"Error in audience_scheduled_calculate: {e}")
        return {'status': 'error', 'message': str(e)}, 500