from flask import Blueprint, request, jsonify
import logging
import pytz
import os
import json
import uuid
from datetime import datetime
from firebase.firebase import Firebase
from feature.ad_integration.facebook.FacebookAds import FacebookAdIntegration

logging.basicConfig(level=logging.INFO)
timezone = pytz.timezone('Asia/Bangkok')
ad_connect= Blueprint('ad_connect', __name__, url_prefix='/ad-connect')
fb = Firebase(host=os.environ.get("FIREBASE_HOST"))

@ad_connect.route('/', methods=['GET'])
def ad_connect_list():
    try:
        if request.method == 'GET':
            data = request.args
            for req in ['property_id', 'channel']:
                if req not in data:
                    return {"status":"error",'message': f"{req} is require"}, 400
                
            property_id = data.get("property_id")
            channel = data.get("channel")
            if channel not in ['all','facebook', 'google_customer_match']:
                return {'status': 'not_spport', 'message': f"Not support {channel} channel"}, 400

            if channel != 'all':
                ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}").get()
                if ad_account_context:
                    return {'status': 'ok', 'data': ad_account_context},200

                return {'status': 'Not fond'},404
            else:
                ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account").get()
                if ad_account_context:
                    return {'status': 'ok', 'data': ad_account_context},200
                return {'status': 'Not fond', 'message': 'This property is not yet configured with a Facebook Ad account'},404
        return {'status': 'error', 'message': 'Method not allowed'}, 405
    except Exception as e:
        logging.error(e)
        return {"status": "error", "message": e}, 500
    
@ad_connect.route('/account', methods=['POST','GET','DELETE'])
@ad_connect.route('/account/', methods=['POST','GET','DELETE'])
def ad_connect_issue_account():
    now = datetime.now(timezone)
    time = now.strftime('%Y-%m-%d %H:%M:%S')
    try:
        if request.method == 'POST':
            data = request.get_json()
            for req in ['property_id', 'channel', 'ad_account_id', 'name']:
                if req not in data:
                    return {"status":"error",'message': f"{req} is require"}, 400
            
            property_id = data.get("property_id")
            ad_account_id = data.get("ad_account_id")
            channel = data.get("channel")
            name = data.get("name")
            
            if channel not in ['facebook', 'google_customer_match']:
                return {'status': 'not_spport', 'message': f"Not support {channel} channel"}, 400
            
            if channel == 'facebook':
                if not str(ad_account_id).startswith("act_"):
                    ad_account_id = 'act_' + str(ad_account_id)
                
                #Step: check permision
                fbAds = FacebookAdIntegration(
                    access_token=os.environ.get("FB_TOKEN"),
                    app_id=os.environ.get("FB_APP_ID"),
                    app_secret=os.environ.get("FB_APP_SECRET"),
                    ad_account_id=ad_account_id
                )

                is_grant, message = fbAds.check_permission()
                if not is_grant:
                    return {"status": "Fail", "message": str(message)}, 400

                #Setup Firebase context
                fb.db.reference().child(f"account/{property_id}/ad_connect./account/facebook/{ad_account_id}/id").set(ad_account_id)
                fb.db.reference().child(f"account/{property_id}/ad_connect/account/facebook/{ad_account_id}/name").set(name)
                fb.db.reference().child(f"account/{property_id}/ad_connect/account/facebook/{ad_account_id}/createdate").set(time)
                fb.db.reference().child(f"account/{property_id}/ad_connect/account/facebook/{ad_account_id}/lastupdate").set(time)

                return {'status': 'ok', 'message': f"Ad account {message} is connected", 'ad_account_id': ad_account_id}, 200
            elif channel == 'google_customer_match':
                return {'status': 'not_support', 'message': 'Not support this request for now'}, 400

        elif request.method == 'GET':
            data = request.args
            for req in ['property_id', 'channel','ad_account_id']:
                if req not in data:
                    return {"status":"error",'message': f"{req} is require"}, 400
                
            property_id = data.get("property_id")
            channel = data.get('channel')
            ad_account_id = data.get("ad_account_id")

            if channel == 'all':
                ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account").get()
                if ad_account_context:
                    return {'status': 'ok', 'data': ad_account_context},200
                return {'status': 'Not fond', 'message': 'This property is not yet configured with a Ad account'},404

            if ad_account_id != 'all':
                ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}/{ad_account_id}").get()
                if ad_account_context:
                    return {'status': 'ok', 'data': ad_account_context},200

                return {'status': 'Not fond'},404
            else:
                ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}").get()
                if ad_account_context:
                    return {'status': 'ok', 'data': ad_account_context},200
                return {'status': 'Not fond', 'message': f'This property is not yet configured with a {channel} Ad account'},404

        elif request.method == 'DELETE':
            data = request.get_json()
            for req in ['property_id','channel','ad_account_id']:
                if req not in data:
                    return {"status":"error",'message': f"{req} is require"}, 400
            
            property_id = data.get("property_id")
            ad_account_id = data.get("ad_account_id")
            channel = data.get('channel')
            
            #check
            ad_account_context = fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}/{ad_account_id}").get(shallow=True)
            if not ad_account_context:
                return {'status': 'not fond'}, 404
            
            fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}/{ad_account_id}").delete()
            return {'status': 'ok', 'message': f"Ad account {ad_account_id} connection was deleted"}, 200

        return {'status': 'error', 'message': 'Method not allowed'}, 405
    except Exception as e:
        logging.error(e)
        return {"status": "error", "message": e}, 500

@ad_connect.route('/audience/link', methods=['POST'])
def ad_connect_audience_link():
    now = datetime.now(timezone)
    time = now.strftime('%Y-%m-%d %H:%M:%S')
    try:
        if request.method == 'POST':
            data = request.get_json()
            for req in ['property_id','channel', 'ad_account_id','audiences']:
                if req not in data:
                    return {"status":"error",'message': f"{req} is require"}, 400
            property_id = data.get("property_id")
            channel = data.get("channel")
            ad_account_id = data.get("ad_account_id")
            audiences = data.get("audiences") #Provide audience ids
            
            if type(audiences) != list:
                return {'status': 'error', 'message': "audiences must be array"}, 400

            if channel not in ['facebook', 'google_customer_match']:
                return {'status': 'not_spport', 'message': f"Not support {channel} channel"}, 400
            
            #check ad_account_id
            ad_account_id_exsit = fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}/{ad_account_id}").get(shallow=True)
            if not ad_account_id_exsit:
                return {'status': 'not_fond', 'message': f'Ad account {ad_account_id} not fond in {channel}'},404
            
            #Get audience context
            audiences_context = []
            for au in audiences:
                au_name = fb.db.reference().child(f"account/{property_id}/audience/{au}/audience_name").get()
                description = fb.db.reference().child(f"account/{property_id}/audience/{au}/description").get()
                context = {
                    "audience_id": au,
                    "audience_name": au_name,
                    "audience_description": description

                }
                audiences_context.append(context)
            
            logging_list = []

            if channel == 'facebook':
                fbAds = FacebookAdIntegration(
                    access_token=os.environ.get("FB_TOKEN"),
                    app_id=os.environ.get("FB_APP_ID"),
                    app_secret=os.environ.get("FB_APP_SECRET"),
                    ad_account_id=ad_account_id
                )

                for au in audiences_context:
                    status = fbAds.create_audience(name=au['audience_name'], description=au['audience_description'])
                    if not status:
                        logging_list.append(
                            {
                                'ad_account_id': ad_account_id,
                                'audience_id': au,
                                "status": 'fail',
                                'message': 'Create connect to ad account fail'
                            }
                        )
                    else:
                        logging_list.append(
                            {
                                'ad_account_id': ad_account_id,
                                'audience_id': au,
                                "status": 'succes',
                                'message': 'Create connect to ad account succes'
                            }
                        )
                        # Wait: Update to ad account audince active (matching audience ID from system to Facebook Audience ID)
                        




                    


            audiences_exsit = fb.db.reference().child(f"account/{property_id}/ad_connect/job/{channel}/{ad_account_id}/audiences").get()
            audiences_exsit = audiences_exsit if audiences_exsit else []
            audiences_exsit.extend(audiences)

            fb.db.reference().child(f"account/{property_id}/ad_connect/job/{channel}/{ad_account_id}/audiences").set(audiences_exsit)
            fb.db.reference().child(f"account/{property_id}/ad_connect/account/{channel}/{ad_account_id}/lastupdate").set(time)

            return {'status': 'ok', 'message': f'Add new audiences toi ad account {ad_account_id} successfully'}, 200
    
    except Exception as e:
        logging.error(e)
        return {"status": "error", "message": e}, 500
    
@ad_connect.route('/audience/job', methods=['POST'])
def ad_connect_audience_job():
    try:
        #Get all job
        accounts = fb.db.reference().child(f"account").get(shallow=True)
        for acc in accounts:
            channels = fb.db.reference().child(f"account/{acc}/ad_connect/job").get(shallow=True)
            if not channels:
                continue
            for channel in channels:
                context = fb.db.reference().child(f"account/{acc}/ad_connect/job/{channel}").get()

                if channel == 'facebook':
                    pass

                elif channel =='google_customer_match':
                    continue


    
    except Exception as e:
        logging.error(e)
        return {"status": "error", "message": e}, 500