from flask import Blueprint, request
import logging
from datetime import datetime
from firebase.firebase import Firebase
import pytz 
import utility.function as func
import os
import uuid
from utility.bucketstorage import Storage
from werkzeug.utils import secure_filename
logging.basicConfig(level=logging.INFO)

evntFunction = func.Event()
feature_content = Blueprint('feature_content', __name__, url_prefix='/feature/content')

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

@feature_content.route('/image/upload',  methods=['POST'])
@feature_content.route('/image/upload/',  methods=['POST'])
def feature_content_image_upload():
    try:
        if request.content_type != 'image/jpeg':
            return {"status": "error","error": "Content-Type must be image/jpeg"}, 400
        
        image_data = request.data
        if not image_data:
            return {"status": "error",'message': 'No selected image'}, 400
        
        now = datetime.now(timezone)
        time_now = int(now.timestamp())
        generate_image_file_name = f"""{uuid.uuid4()}_{time_now}.png"""

        try:
            filename = secure_filename(generate_image_file_name)
            gcs_blob_name = f"content/{filename}"

            # Upload to GCS
            storage = Storage(project_id=os.environ.get("GCP_PROJECT"), bucket_name=os.environ.get("GC_BUCKET_NAME"))
            link = storage.upload_from_byte(file_path=gcs_blob_name, image_bytes=image_data)

            if link:
                #Update DB
                return {"status": "ok",'message': 'Image uploaded successfully', 'image_address': link}, 201
            else:
                return {"status": "error",'message': 'Failed to upload image to GCS'}, 500

        except Exception as e:
            logging.info(f"Error processing upload: {e}")
            return {"status": "error",'message': f'An error occurred: {e}'}, 500
        
    
    except Exception as e:
        logging.error(e)
        return {'status': 'error', 'message': e}, 500


@feature_content.route('/line',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content.route('/line/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route():
    try:
        now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
        if request.method == 'POST':
            
            data = request.get_json()
            for req in ['property_id','json', 'json_preview', 'name', 'user_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            property_id = data.get("property_id", None)
            name = data.get("name", None)
            json = data.get("json", None)
            json_preview = data.get("json_preview", None)
            user_id = data.get("user_id", None)
                
            #Gen content ID
            contentId = func.Function.generate_uuid_from_text(f"{now}_{name}")

            #Save content to FB
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/json").set(json)
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/json_preview").set(json_preview)
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/createdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/lastupdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/line/{contentId}/lastupdate_by").set(user_id)

            return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200

        elif request.method == 'GET':
            data = request.args
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is required"}, 400
            
            property_id = data.get("property_id", None)
            content_id = data.get("content_id", None)

            if content_id != 'all':
                newListContent = fb.db.reference().child(f"account/{property_id}/content/line/{content_id}").get()
                newListContent = [newListContent]
            else:
                contentData = fb.db.reference().child(f"account/{property_id}/content/line").get()
                if not contentData:
                    return {'status': 'not_found', 'message': 'No content created'},404
                newListContent = []
                for con in contentData:
                    context = contentData[con]
                    context['content_id'] = con
                    newListContent.append(context)
            
            if newListContent:
                cotent_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                return {'status': 'ok', 'data': cotent_desc}, 200
            else:
                return {'status': 'not found', 'message': "No content was created"}, 404

        elif request.method == 'PUT':

            data = request.get_json()
            for req in ['property_id', 'content_id', 'user_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            user_id = data.get("user_id")
            
            name = data.get("name", None) if 'name' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/name").get()
            json = data.get("json") if 'json' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/json").get()
            json_preview = data.get("json_preview") if 'json_preview' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/json_preview").get()

            #Update
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/lastupdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/json").set(json)
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/json_preview").set(json_preview)
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/lastupdate_by").set(user_id)

            return {"status": "ok", "message": f"Content {content_id} was updated"}, 200
        
        elif request.method == 'DELETE':
            data = request.get_json()
            for req in ['property_id', 'user_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400 
            
            property_id = data.get("property_id", None)
            content_id = data.get("content_id", None)
            user_id = data.get("user_id", None)

            #Delete process
            fb.db.reference().child(f"account/{property_id}/content/line/{content_id}").delete()
            return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200  

        return {'status': 'error', 'message': 'Method not allowed'}, 405
    
    except Exception as e:
        logging.error(f"Content Fucn error: {e}")
        return {'status': 'error', 'message': e}, 500
    
@feature_content.route('/line/automation',  methods=['GET'])
@feature_content.route('/line/automation/',  methods=['GET'])
def feature_content_line_automation():
    data = request.args
    for req in ['property_id', 'content_id']:
        if req not in data:
            return {'message': f"{req} is required"}, 400
    
    property_id = data.get("property_id")
    content_id = data.get("content_id")

    now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M")
    contentAutomations = fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/automations").get()
    if contentAutomations:
        
        # Loop get name
        from dashboard.genQuery import GenerateQuery
        from utility.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"))
        
        listAutomation = []
        for auto in contentAutomations:
            autoName = fb.db.reference().child(f"account/{property_id}/automation/{auto}/name").get()

            genq = GenerateQuery(property_id=property_id)
            query = genq.getNextSchedual(automation_id=auto, now=now)
            result = csql.query(query)
            nextSchedual = result[0][0].strftime("%Y-%m-%d %H:%M") if result[0][0] else 'Automation not active'

            #Get next push
            packAuto = {
                "automation_id": auto,
                "automation_name": autoName,
                "next_schedual": nextSchedual
            }
            listAutomation.append(packAuto)
        return {'status': 'ok', 'data': listAutomation}, 200
    else:
        return {'status': 'ok', 'message': 'This content not use in any automation flow'}, 200
    

@feature_content.route('/facebook',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content.route('/facebook/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route_facebook():
    try:
        now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
        if request.method == 'POST':
            
            data = request.get_json()
            for req in ['property_id','json', 'name']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            property_id = data.get("property_id", None)
            name = data.get("name", None)
            json = data.get("json", None)
            
            contentId = func.Function.generate_uuid_from_text(f"{now}_{name}")
            
            #Save content to FB
            fb.db.reference().child(f"account/{property_id}/content/facebook/{contentId}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/facebook/{contentId}/json").set(json)
            fb.db.reference().child(f"account/{property_id}/content/facebook/{contentId}/createdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/facebook/{contentId}/lastupdate").set(now)

            return {'status': 'ok', 'message': f'Content {name} was created successfully', "content_id": contentId}, 200
        
        elif request.method == 'GET':
            data = request.args
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is required"}, 400
            
            property_id = data.get("property_id", None)
            content_id = data.get("content_id", None)

            if content_id != 'all':
                newListContent = fb.db.reference().child(f"account/{property_id}/content/facebook/{content_id}").get()
                newListContent = [newListContent]
            else:
                contentData = fb.db.reference().child(f"account/{property_id}/content/facebook").get()
                if not contentData:
                    return {'status': 'not_found', 'message': 'No content created'},404
                newListContent = []
                for con in contentData:
                    context = contentData[con]
                    context['content_id'] = con
                    newListContent.append(context)
            
            if newListContent:
                cotent_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                return {'status': 'ok', 'data': cotent_desc}, 200
            else:
                return {'status': 'not found', 'message': "No content was created"}, 404  
            
        elif request.method == 'PUT':

            data = request.get_json()
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            
            name = data.get("name", None) if 'name' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/name").get()
            json = data.get("json") if 'json' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/json").get()

            #Update
            fb.db.reference().child(f"account/{property_id}/content/facebook/{content_id}/lastupdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/facebook/{content_id}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/facebook/{content_id}/json").set(json)

            return {"status": "ok", "message": f"Content {content_id} was updated"}, 200    
        
        elif request.method == 'DELETE':
            data = request.get_json()
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400 
            
            property_id = data.get("property_id", None)
            content_id = data.get("content_id", None)

            #Delete process
            fb.db.reference().child(f"account/{property_id}/content/facebook/{content_id}").delete()
            return {'status': 'ok', 'message': f'Content {content_id} was deleted'}, 200  

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

@feature_content.route('/sms',  methods=['GET','POST', 'PUT', 'DELETE'])
@feature_content.route('/sms/',  methods=['GET','POST', 'PUT', 'DELETE'])
def feature_content_route_sms():
    now = datetime.now(timezone).strftime("%Y-%m-%d %H:%M:%S")
    try:
        if request.method == 'POST':
            data = request.get_json()
            for req in ['property_id','text', 'name']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            property_id = data.get("property_id", None)
            name = data.get("name", None)
            text = data.get("text", None)

            contentId = func.Function.generate_uuid_from_text(f"{now}_{name}")

            fb.db.reference().child(f"account/{property_id}/content/sms/{contentId}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/sms/{contentId}/text").set(text)
            fb.db.reference().child(f"account/{property_id}/content/sms/{contentId}/createdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/sms/{contentId}/lastupdate").set(now)

            return {'status': 'ok', 'message': f'SMS {name} was created successfully', "content_id": contentId}, 200
        
        elif request.method == 'GET':
            data = request.args
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is required"}, 400
            
            property_id = data.get("property_id", None)
            content_id = data.get("content_id", None)

            if content_id != 'all':
                newListContent = fb.db.reference().child(f"account/{property_id}/content/sms/{content_id}").get()
                newListContent = [newListContent]
            else:
                contentData = fb.db.reference().child(f"account/{property_id}/content/sms").get()
                if not contentData:
                    return {'status': 'not_found', 'message': 'No content created'},404
                newListContent = []
                for con in contentData:
                    context = contentData[con]
                    context['content_id'] = con
                    newListContent.append(context)
            
            if newListContent:
                cotent_desc = sorted(newListContent, key=lambda x: x['createdate'], reverse=True)
                return {'status': 'ok', 'data': cotent_desc}, 200
            else:
                return {'status': 'not found', 'message': "No content was created"}, 404
            
        elif request.method == 'PUT':

            data = request.get_json()
            for req in ['property_id', 'content_id']:
                if req not in data:
                    return {'message': f"{req} is require"}, 400
            
            content_id = data.get("content_id")
            property_id = data.get("property_id")
            
            text = data.get("text", None) if 'text' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/text").get()
            name = data.get("name") if 'name' in data else fb.db.reference().child(f"account/{property_id}/content/line/{content_id}/name").get()

            #Update
            fb.db.reference().child(f"account/{property_id}/content/sms/{content_id}/lastupdate").set(now)
            fb.db.reference().child(f"account/{property_id}/content/sms/{content_id}/name").set(name)
            fb.db.reference().child(f"account/{property_id}/content/sms/{content_id}/text").set(text)

            return {"status": "ok", "message": f"Content {content_id} was updated"}, 200

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