from flask import Flask, request, jsonify
import google.generativeai as genai
import requests
import threading
import logging
import time
import datetime
import os

# Setup logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("instagram_auto_reply.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger()

# Konfigurasi
access_token = "IGAAbDRJqoXZAJBZAE9nSHJVZAWlZAVEpaQkdUb1hYc0pQbEp1SDUwT1dFZAVlBeHBmZAkVYbjBJRExoa3pPN3NyUkhraDdBVGs0WDlGV0EzRHVQZAlF3dVVHWVBvblEzeUY2QWRMMkZAhM2ZA4eTQxQ0E1S1ZAVNERwb1lYYXc1S0puZAERtQm5mSGJUVFMyN2ZA3"
instagram_account_id = "9654344654586349"
post_id = "18011605364714149"  # Post ID yang sudah Anda dapatkan
gemini_api_key = "AIzaSyA1HyFIryiUzwjvpGX1yGJ3uaHLf7sBvqY"
POLLING_INTERVAL = 9  # 15 menit dalam detik 

# Pastikan file untuk menyimpan komentar yang telah dibalas sudah ada
replied_comments_file = "replied_comments.txt"
if not os.path.exists(replied_comments_file):
    with open(replied_comments_file, "w") as f:
        pass

# Konfigurasi Gemini AI
genai.configure(api_key=gemini_api_key)

app = Flask(__name__)

# Fungsi untuk mendapatkan komentar pada post tertentu
def get_comments(post_id):
    url = f"https://graph.instagram.com/v18.0/{post_id}/comments"
    params = {
        "access_token": access_token,
        "fields": "id,text,timestamp,username"
    }
    try:
        response = requests.get(url, params=params)
        
        if response.status_code == 200:
            return response.json().get("data", [])
        else:
            logger.error(f"Error mendapatkan komentar: {response.text}")
            return []
    except Exception as e:
        logger.error(f"Exception saat mengambil komentar: {str(e)}")
        return []

# Fungsi untuk membalas komentar
def reply_to_comment(comment_id, message):
    url = f"https://graph.instagram.com/v18.0/{comment_id}/replies"
    params = {
        "access_token": access_token,
        "message": message
    }
    try:
        response = requests.post(url, params=params)
        
        if response.status_code == 200:
            return True, response.json()
        else:
            return False, response.text
    except Exception as e:
        logger.error(f"Exception saat membalas komentar: {str(e)}")
        return False, str(e)

# Fungsi untuk mendapatkan respons AI dari Gemini
def get_ai_response(username, comment_text):
    try:
        model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25') 
        prompt = f"""
        Buatkan balasan yang ramah, profesional dan singkat (maksimal 2 kalimat) untuk komentar Instagram berikut:
        
        Username: {username}
        Komentar: {comment_text}
        
        Balasan harus sopan, informatif, dan sesuai dengan konteks komentar.
        """
        
        response = model.generate_content(prompt)
        return response.text.strip()
    except Exception as e:
        logger.error(f"Error saat generate AI response: {str(e)}")
        return "Terima kasih atas komentar Anda!"  # Fallback response

# Fungsi untuk menyimpan komentar yang sudah dibalas
def save_replied_comments(comment_id):
    try:
        with open(replied_comments_file, "a") as file:
            file.write(f"{comment_id}\n")
    except Exception as e:
        logger.error(f"Error menyimpan comment ID: {str(e)}")

# Fungsi untuk membaca komentar yang sudah dibalas
def get_replied_comments():
    try:
        with open(replied_comments_file, "r") as file:
            return [line.strip() for line in file.readlines()]
    except FileNotFoundError:
        # Jika file belum ada, buat file kosong
        with open(replied_comments_file, "w") as file:
            pass
        return []

# Logika utama untuk auto-reply
def auto_reply_system():
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    logger.info(f"Mulai proses auto-reply pada {current_time}")
    
    try:
        # Ambil komentar yang sudah pernah dibalas
        replied_comments = get_replied_comments()
        
        # Ambil semua komentar dari post
        comments = get_comments(post_id)
        logger.info(f"Mendapatkan {len(comments)} komentar")
        
        # Proses setiap komentar
        for comment in comments:
            comment_id = comment["id"]
            username = comment.get("username", "pengguna")
            comment_text = comment["text"]
            
            # Cek apakah komentar sudah pernah dibalas
            if comment_id not in replied_comments:
                logger.info(f"Memproses komentar baru dari {username}: '{comment_text}'")
                
                # Generate balasan dengan Gemini AI
                ai_reply = get_ai_response(username, comment_text)
                
                # Kirim balasan ke Instagram
                success, result = reply_to_comment(comment_id, ai_reply)
                
                if success:
                    logger.info(f"Berhasil membalas komentar dengan: '{ai_reply}'")
                    # Catat komentar yang sudah dibalas
                    save_replied_comments(comment_id)
                else:
                    logger.error(f"Gagal membalas komentar: {result}")
                
                # Tunggu sebentar agar tidak terkena rate limit
                time.sleep(5)
            else:
                logger.debug(f"Komentar dari {username} sudah pernah dibalas sebelumnya")
        
        logger.info(f"Proses auto-reply selesai")
        return {"status": "success", "processed_comments": len(comments)}
    except Exception as e:
        logger.error(f"Error dalam auto_reply_system: {str(e)}")
        return {"status": "error", "message": str(e)}

# Background task untuk polling
def background_polling():
    while True:
        try:
            auto_reply_system()
            logger.info(f"Tidur selama {POLLING_INTERVAL} detik...")
            time.sleep(POLLING_INTERVAL)
        except Exception as e:
            logger.error(f"Error dalam background polling: {str(e)}")
            # Tetap coba kembali setelah interval yang ditentukan
            time.sleep(POLLING_INTERVAL)

# Endpoints
@app.route('/')
def home():
    return jsonify({
        "status": "active",
        "service": "Instagram Auto Reply Bot",
        "version": "1.0.0",
        "endpoints": {
            "/check-comments": "Trigger manual untuk memeriksa dan membalas komentar",
            "/status": "Mendapatkan status sistem",
            "/webhook": "Endpoint untuk webhook Instagram (POST)"
        }
    })

@app.route('/check-comments')
def check_comments():
    # Jalankan dalam thread terpisah agar tidak memblokir respons
    thread = threading.Thread(target=auto_reply_system)
    thread.start()
    return jsonify({
        "status": "initiated",
        "message": "Pengecekan komentar sedang diproses di background"
    })

@app.route('/status')
def status():
    # Cek apakah sistem berjalan dengan mengambil last modified time dari log file
    try:
        log_last_modified = os.path.getmtime("instagram_auto_reply.log")
        last_active = datetime.datetime.fromtimestamp(log_last_modified).strftime('%Y-%m-%d %H:%M:%S')
    except:
        last_active = "Unknown"
    
    return jsonify({
        "status": "active",
        "post_id": post_id,
        "last_active": last_active,
        "polling_interval_seconds": POLLING_INTERVAL
    })

@app.route('/webhook', methods=['POST'])
def webhook():
    # Implementasi webhook jika Anda ingin mengintegrasikan dengan webhook Instagram
    data = request.json
    logger.info(f"Webhook received: {data}")
    
    # Anda bisa menambahkan logika untuk memproses webhook di sini
    thread = threading.Thread(target=auto_reply_system)
    thread.start()
    
    return jsonify({"status": "received"})

if __name__ == '__main__':
    # Mulai thread polling di background
    polling_thread = threading.Thread(target=background_polling)
    polling_thread.daemon = True  # Akan berhenti ketika program utama berhenti
    polling_thread.start()
    
    # Jalankan server Flask
    app.run(host='0.0.0.0', port=5444, debug=False)
