from fastapi import Request, Query, Depends, Header, APIRouter, HTTPException
from fastapi.responses import JSONResponse
import pytz
import os
import uuid
from datetime import datetime, timedelta
from connectors.firebase.firebase import Firebase

from api.feature.automation.node import *

import logging
logging.basicConfig(level=logging.INFO)
timezone_utc = pytz.utc
timezone_bkk = pytz.timezone('Asia/Bangkok')

fb = Firebase(host=os.environ.get("FIREBASE_HOST"))

router = APIRouter()

LOGGING_PREFIX = "api_job_audience"

def transform_logs(nodes):
    result = []

    for node in nodes:
        base = {
            "node_id": node["node_id"],
            "node_name": node["name"],
            "type": node["type"],
            "timestamp": node["timestamp"],
        }

        # CASE 1: Cron Trigger
        if node["type"] == "trigger":
            result.append({
                **base,
                "user_pseudo_id": None,
                "action": "triggered",
                "status": node.get("triggered"),
            })

        # CASE 2: Audience segment
        elif node["type"] == "audience":
            for uid in node["user_pseudo_ids"]:
                result.append({
                    **base,
                    "user_pseudo_id": uid,
                    "action": "audience_match",
                    "status": True,
                })

        # CASE 3: Destination (success / fail per user)
        elif node["type"] == "destination":
            # Success
            for uid in node.get("user_pseudo_ids_success", []):
                result.append({
                    **base,
                    "user_pseudo_id": uid,
                    "action": "send_message",
                    "status": "success",
                })

            # Fail
            for uid in node.get("user_pseudo_ids_fail", []):
                result.append({
                    **base,
                    "user_pseudo_id": uid,
                    "action": "send_message",
                    "status": "fail",
                })
    return result

@router.post("/v1", description="Scheduled job to execute automation version 1")
async def automation_scheduled_func_v1(request: Request):
    try:
        now = datetime.now(timezone_bkk).replace(second=0, microsecond=0)
        accounts = fb.db.reference().child('account').get(shallow=True)
        for acc in accounts:
            activeAutomate = fb.db.reference().child(f"account/{acc}/automation_active_index").get()
            if not activeAutomate:
                print(f"No active automate for account {acc}")
                continue
            
            for automate_id in activeAutomate:
                automate = fb.db.reference().child(f"account/{acc}/automation/{automate_id}").get()
                last_triggered = automate.get('last_triggered')
                automateJSON = automate.get('json')
                startingNode = automateJSON.get('starting_node')
                automateNodes = automateJSON.get('nodes')
                
                should_trigger_now = False
                for node in automateNodes:
                    if node.get('id') == startingNode:
                        trigNode = TriggerNode(node["id"], node["name"], node['trigger'], node.get("cron",None), node.get("interval",None), last_triggered, now, node['datebegin'], node['dateend'], node['alwaywhen'])
                        should_trigger_now = trigNode.should_trigger_now()
                        if not should_trigger_now:
                            break
                
                if should_trigger_now:
                    executor = FlowExecutor(acc, automate, now)
                    result = executor.execute()
                    
                    #Save result
                    fb.db.reference().child(f"account/{acc}/automation/{automate_id}/last_triggered").set(now.strftime("%Y-%m-%d %H:%M:00"))
                    
                    resultObject = {
                        "log_id": str(uuid.uuid4()),
                        "logs": result
                    }
                    #Get logs
                    logs = fb.db.reference().child(f"account/{acc}/automation/{automate_id}/logs").get()
                    logs = [] if not logs else logs
                    logs.append(resultObject)
                    fb.db.reference().child(f"account/{acc}/automation/{automate_id}/logs").set(logs)
        return JSONResponse(status_code=200, content={"status": "ok", "message": "Automation scheduled function executed"})
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})
    
@router.post("/v2", description="Scheduled job to execute automation version 2")
async def automation_scheduled_func_v2(request: Request):
    try:
        now = datetime.now(timezone).replace(second=0, microsecond=0)
        nowStr = now.strftime("%Y-%m-%d %H:%M:00")
        from utility.dashboard.genQuery import GenerateQuery
        from connectors.cloudSQL.cloudsql import CloudSQL
        csql = CloudSQL("asia-southeast1", os.environ.get("INSTANCE_NAME"))
        csql.create_engine(os.environ.get("POSTGRES_USER"), os.environ.get("POSTGRES_PASSWORD"), os.environ.get("POSTGRES_DB"))
        
        accounts = fb.db.reference().child('account').get(shallow=True)
        for acc in accounts:
            genq = GenerateQuery(acc)
            query = genq.schedualAutomation(nowStr)
            resultQuery = csql.query(query)
            if not resultQuery:
                continue
            for automateRow in resultQuery:
                automation_id = automateRow[2]
                log_id = automateRow[0]
                #Get autoamte
                automate = fb.db.reference().child(f"account/{acc}/automation/{automation_id}").get()

                executor = FlowExecutor(acc, automate, now)
                result = executor.execute()
                
                #Save result
                fb.db.reference().child(f"account/{acc}/automation/{automation_id}/last_triggered").set(nowStr)
                
                #Get logs
                logs = fb.db.reference().child(f"account/{acc}/automation/{automation_id}/logs").get(shallow=True)
                if not logs:
                    max_key = -1
                else:
                    max_key = max(int(k) for k in logs)

                #Update Postgres
                queryUpdateLog = genq.updateAutomationLog(automation_id, log_id)
                resultUpdate = csql.query(queryUpdateLog)

                #Log user data to Postgres
                ## Start with result
                logs_transform = transform_logs(result)
                fb.db.reference().child(f"account/{acc}/automation/{automation_id}/logs/{log_id}/data/{int(max_key)+1}").set(logs_transform)
                fb.db.reference().child(f"account/{acc}/automation/{automation_id}/logs/{log_id}/timestamp").set(nowStr)

        return JSONResponse(status_code=200, content={"status": "ok", "message": "Automation scheduled function v2 executed"})
    except Exception as e:
        logging.error(f"Error parsing {LOGGING_PREFIX}: {e}")
        return JSONResponse(status_code=500, content={'status': 'error', 'message': str(e)})