from flask import Blueprint, request
import requests
import logging
from datetime import datetime, timedelta
from firebase.firebase import Firebase
import pytz
import os
import json
from google.cloud import pubsub_v1
logging.basicConfig(level=logging.INFO)

hook = Blueprint('hook', __name__, url_prefix='/hook')

fb = Firebase(host=os.environ.get("FIREBASE_HOST"))
timezone = pytz.timezone('Asia/Bangkok')
LINE_CHANNEL_CLIENT = os.environ.get("LINE_CHANNEL_LIST")
LINE_CHANNEL_LIST = LINE_CHANNEL_CLIENT.strip().split(",")

PROJECT_ID = os.environ.get('GCP_PROJECT') 
TOPIC_ID = os.environ.get('PUBSUB_TOPIC_ID')

publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(PROJECT_ID, TOPIC_ID)

@hook.route('/facebook',  methods=['GET','POST'])
@hook.route('/facebook/',  methods=['GET','POST'])
def webhooks_facebook():
    if request.method == "GET":
        data = request.args
        logging.info(f"Webhook received:{data}")
        challenge = request.args.get('hub.challenge')
        return challenge, 200
    elif request.method == "POST":
        data = request.json
        if data['object'] == 'page':
            logging.info(f"Hook FB: {data}")
            if 'messaging' in data['entry'][0]:
                messageObject = data['entry'][0]['messaging'][0]
                if ('message' in messageObject and 'text' in messageObject['message']) or ('referral' in messageObject):
                    data.update({"social": "facebook"})
                    message_data = json.dumps(data).encode('utf-8')
                    future = publisher.publish(topic_path, message_data)
                    logging.info(future.result())
                    # logging.info(f"Webhook received:{data}")
                    # fb.db.reference().child(f"log/facebook/hook/{dateStr}/{hourStr}").push(data)
                    return {"status":"success"}, 200
            elif 'changes' in data['entry'][0]:
                data.update({"social": "facebook"})
                message_data = json.dumps(data).encode('utf-8')
                future = publisher.publish(topic_path, message_data)
                logging.info(future.result())
                return {"status":"success"}, 200
            return {"status":"error",'message': "Invalid message format"}, 400
        return {"status":"error",'message': "Invalid object type"}, 400
    return {"status":"error",'message': "Method not allowed"}, 405


@hook.route('/line/<hook_id>/',  methods=['POST'])
@hook.route('/line/<hook_id>',  methods=['POST'])
def webhooks_line(hook_id):
    if request.method == "POST":
        data = request.get_json()
        source_userId = data['destination']

        if source_userId not in LINE_CHANNEL_LIST:
            return {"status":"error",'message': "This channel not in list of subscription channel"}, 500
        
        # dateStr = datetime.now(timezone).date().strftime("%Y%m%d")
        # hourStr = datetime.now(timezone).strftime("%H")
        data.update({"internal_hook_id": hook_id})
        data.update({"social": "line"})
        message_data = json.dumps(data).encode('utf-8')
        future = publisher.publish(topic_path, message_data)
        logging.info(future.result())
        # logging.info(f"Webhook received:{data}")
        # fb.db.reference().child(f"log/line/hook/{dateStr}/{hourStr}").push(data)
        return {"status":"success"}, 200
    return {"status":"error",'message': "Method not allowed"}, 405

@hook.route('/instagram',  methods=['GET','POST'])
@hook.route('/instagram/',  methods=['GET','POST'])
def webhooks_instagram():
    if request.method == "GET":
        data = request.args
        logging.info(f"Webhook received:{data}")
        challenge = request.args.get('hub.challenge')
        return challenge, 200
    elif request.method == "POST":
        dateStr = datetime.now(timezone).date().strftime("%Y%m%d")
        hourStr = datetime.now(timezone).strftime("%H")
        data = request.json
        # logging.info(f"Webhook received:{data}")
        fb.db.reference().child(f"log/instagram/hook/{dateStr}/{hourStr}").push(data)
        return {"status":"success"}, 200
    return {"status":"error",'message': "Method not allowed"}, 405