import asyncio
import os
import sys
import json
import requests
import gspread
import logging 
import smtplib
import subprocess
from datetime import datetime
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command, or_f
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, ReplyKeyboardMarkup, KeyboardButton
from aiogram.enums import ParseMode
from google.oauth2.service_account import Credentials
from dotenv import load_dotenv
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

# --- НАЛАШТУВАННЯ ---
load_dotenv()
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)

TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
ADMIN_CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
GOOGLE_SHEET_ID = os.getenv("GOOGLE_SHEET_ID")
HUGEPROFIT_TOKEN = os.getenv("HUGEPROFIT_TOKEN")
CRM_API_URL = "https://crm.h-profit.com/bapi"
SMTP_EMAIL = os.getenv("SMTP_EMAIL")
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD")

SITE_URL = "https://lvacs.store" 

# Константи CRM
CRM_ACCOUNT_ID = 84538
CRM_SELLER_ID = 31527
UNPAID_STATUS_ID = "10787" # ID статусу "Не оплачено"

bot = Bot(token=TELEGRAM_BOT_TOKEN)
dp = Dispatcher()

# Google Sheets
# Переконайся, що файл .json лежить поруч із ботом
scopes = ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive"]
creds = Credentials.from_service_account_file("wheelstore-drive-bot-2d1ebc787bf7.json", scopes=scopes)
client = gspread.authorize(creds)

try:
    users_sheet = client.open_by_key(GOOGLE_SHEET_ID).worksheet("Users")
    orders_sheet = client.open_by_key(GOOGLE_SHEET_ID).worksheet("Orders")
except Exception as e:
    logger.error(f"Sheets Error: {e}")

# --- 📧 ФУНКЦІЇ EMAIL (TOKYO STYLE) ---

def send_email_html(to_email, subject, html_body):
    """Відправка HTML листа"""
    if not to_email: return
    
    msg = MIMEMultipart()
    msg['From'] = SMTP_EMAIL
    msg['To'] = to_email
    msg['Subject'] = Header(subject, 'utf-8')
    msg.attach(MIMEText(html_body, 'html', 'utf-8'))

    try:
        with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
            server.login(SMTP_EMAIL, SMTP_PASSWORD)
            server.send_message(msg)
            logger.info(f"✅ Лист надіслано: {to_email}")
    except Exception as e:
        logger.error(f"❌ SMTP Error: {e}")

def get_order_email_body(order_id, items, total_usd):
    """Генерує лист про замовлення (Tokyo Style)"""
    rows_html = ""
    for item in items:
        # Безпечне отримання значень
        name = item.get('name', 'Товар')
        qty = item.get('qty', 1)
        price = item.get('price', 0)
        
        rows_html += f"""
        <tr style="border-bottom: 1px solid #E0E6E8;">
            <td align="left" style="padding: 10px; color: #555555; font-size: 14px;">{name}</td>
            <td align="center" style="padding: 10px; color: #555555; font-size: 14px;">{qty}</td>
            <td align="right" style="padding: 10px; color: #282B2B; font-size: 14px; font-weight: bold;">${price}</td>
        </tr>
        """
    
    return f"""
    <!DOCTYPE html>
    <html>
    <body style="margin: 0; padding: 0; background-color: #f4f4f4; font-family: Helvetica, Arial, sans-serif;">
        <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.05);">
            <tr>
                <td align="center" style="background-color: #282B2B; padding: 30px 0;">
                    <h1 style="color: #ffffff; font-size: 24px; margin: 0; letter-spacing: 2px; font-weight: 300;">LV ACS</h1>
                    <p style="color: #bbbbbb; font-size: 12px; margin: 5px 0 0 0; text-transform: uppercase;">Оптові аксесуари</p>
                </td>
            </tr>
            <tr>
                <td style="padding: 40px 30px;">
                    <h2 style="color: #282B2B; font-size: 20px; margin-bottom: 20px;">Замовлення #{order_id} прийнято</h2>
                    <p style="color: #555; font-size: 16px; margin-bottom: 30px;">
                        Ми підтвердили ваше замовлення та передали його на склад для збірки.
                    </p>
                    <table border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; margin-bottom: 30px;">
                        <thead>
                            <tr style="background-color: #f8f9fa; border-bottom: 2px solid #E0E6E8;">
                                <th align="left" style="padding: 10px; color: #282B2B; font-size: 14px;">Товар</th>
                                <th align="center" style="padding: 10px; color: #282B2B; font-size: 14px;">К-сть</th>
                                <th align="right" style="padding: 10px; color: #282B2B; font-size: 14px;">Ціна</th>
                            </tr>
                        </thead>
                        <tbody>
                            {rows_html}
                        </tbody>
                    </table>
                    <div style="text-align: right; margin-bottom: 30px;">
                        <p style="color: #282B2B; font-size: 18px; font-weight: bold; margin: 0;">
                            До сплати: <span style="color: #EE6C29;">${total_usd}</span>
                        </p>
                    </div>
                    <div style="text-align: center;">
                        <a href="{SITE_URL}/orders" style="background-color: #EE6C29; color: #ffffff; padding: 14px 30px; text-decoration: none; border-radius: 50px; font-weight: bold; display: inline-block;">
                            Історія замовлень
                        </a>
                    </div>
                </td>
            </tr>
        </table>
    </body>
    </html>
    """

def get_activation_email_body(login):
    """Генерує лист про активацію (Tokyo Style)"""
    return f"""
    <!DOCTYPE html>
    <html>
    <body style="margin: 0; padding: 0; background-color: #f4f4f4; font-family: Helvetica, Arial, sans-serif;">
        <table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px; margin: 20px auto; background-color: #ffffff; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 10px rgba(0,0,0,0.05);">
            <tr>
                <td align="center" style="background-color: #282B2B; padding: 30px 0;">
                    <h1 style="color: #ffffff; font-size: 24px; margin: 0; letter-spacing: 2px; font-weight: 300;">LV ACS</h1>
                </td>
            </tr>
            <tr>
                <td style="padding: 40px 30px; text-align: center;">
                    <h2 style="color: #282B2B; font-size: 22px; margin-bottom: 15px;">Акаунт активовано! 🚀</h2>
                    <p style="color: #555; font-size: 16px; margin-bottom: 30px;">
                        Ваш логін: <b>{login}</b><br>
                        Тепер ви маєте повний доступ до каталогу та оптових цін.
                    </p>
                    <a href="{SITE_URL}/login" style="background-color: #EE6C29; color: #ffffff; padding: 14px 30px; text-decoration: none; border-radius: 50px; font-weight: bold; display: inline-block;">
                        Увійти в кабінет
                    </a>
                </td>
            </tr>
        </table>
    </body>
    </html>
    """

# --- ФУНКЦІЇ CRM ---

def get_mid(pid):
    try:
        r = requests.get(f"{CRM_API_URL}/products", headers={"Authorization": HUGEPROFIT_TOKEN}, params={"filter[id]": pid})
        return r.json().get("data")[0].get("stock", [])[0].get("mid") if r.ok else 0
    except: return 0

def create_sale_in_crm(order_id, items, total, customer, comment):
    prods = {}
    for i, item in enumerate(items):
        try:
            pid = int(item['id'])
            prods[str(i)] = {"pid": pid, "mid": get_mid(pid), "count": int(item['qty']), "finish_price": float(item['price']), "discount": 0}
        except: pass
    
    desc = f"Site Order #{order_id} | {comment}\n{customer.get('lastName','')} {customer.get('phone','')}"
    payload = {
        "amount": float(total), "amount_sale": float(total), "client_id": None, "channel_id": [],
        "order_status": "pending", "account_id": CRM_ACCOUNT_ID, "user_id": CRM_SELLER_ID, 
        "responsible_user_id": CRM_SELLER_ID, "date": datetime.now().strftime("%Y-%m-%dT%H:%M:%S.000Z"),
        "products": prods, "comment": desc, "prepaid_amount": "", "tracking_number": "", "clients_delivery_id": 0 
    }
    try:
        r = requests.put(f"{CRM_API_URL}/sales", headers={"Authorization": HUGEPROFIT_TOKEN, "Content-Type": "application/json"}, json=payload)
        if r.status_code in [200, 201] and r.json().get("success"): return r.json().get('oid')
    except Exception as e: logger.error(f"CRM Request Error: {e}")
    return None

# --- TELEGRAM COMMANDS ---

@dp.message(Command("start"))
async def start(m: types.Message):
    if str(m.chat.id) != ADMIN_CHAT_ID: return
    # 🔥 ОНОВЛЕНІ КНОПКИ
    kb = ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text="👥 Користувачі"), KeyboardButton(text="📦 Замовлення")], 
            [KeyboardButton(text="💸 Неоплачені замовлення")],
            [KeyboardButton(text="🔄 Оновити таблицю")]
        ], 
        resize_keyboard=True
    )
    await m.answer("Адмін-бот LV ACS.", reply_markup=kb)

# Реагуємо на /users АБО на кнопку "👥 Користувачі"
@dp.message(or_f(Command("users"), F.text == "👥 Користувачі"))
async def users(m: types.Message):
    if str(m.chat.id) != ADMIN_CHAT_ID: return
    try:
        records = users_sheet.get_all_records()
        if not records: await m.answer("Пусто."); return
        for u in records:
            status_icon = "🟢" if str(u.get("Active")).lower() == "true" else "🔴"
            login = u.get('Login', 'No Login')
            text = f"{status_icon} <b>{login}</b>\n🏠 {u.get('Shop_name')}\n👤 {u.get('First_name')} {u.get('Last_name')}\n📞 {u.get('Phone')}"
            kb = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="✅ Вкл", callback_data=f"up_T_{login}"), InlineKeyboardButton(text="🚫 Викл", callback_data=f"up_F_{login}"), InlineKeyboardButton(text="🗑 Вид", callback_data=f"del_{login}")]])
            await m.answer(text, reply_markup=kb, parse_mode=ParseMode.HTML)
    except Exception as e: await m.answer(f"Error: {e}")

# Реагуємо на /orders АБО на кнопку "📦 Замовлення"
@dp.message(or_f(Command("orders"), F.text == "📦 Замовлення"))
async def orders(m: types.Message):
    if str(m.chat.id) != ADMIN_CHAT_ID: return
    try:
        all_rows = orders_sheet.get_all_values()
        if len(all_rows) < 2: await m.answer("Замовлень немає."); return
        for row in reversed(all_rows[1:][-5:]):
            if len(row) < 9: continue
            oid, user_login, items_json, total, crm_id, customer_json, comment, status = row[0], row[1], row[3], row[4], row[5], row[6], row[7], row[8]
            try: items = json.loads(items_json); customer = json.loads(customer_json)
            except: items = []; customer = {}
            items_text = "".join([f"  • {i.get('name')} x{i.get('qty')} (${i.get('price')})\n" for i in items])
            txt = f"📦 <b>Замовлення #{oid}</b>\n👤 {customer.get('firstName', '')} {customer.get('lastName', '')} (@{user_login})\n📞 <code>{customer.get('phone', '')}</code>\n📍 {customer.get('city', '')}, {customer.get('warehouse', '')}\n🛒 <b>Товари:</b>\n{items_text}💰 <b>Сума: ${total}</b>\n📝 Статус: {status}\n🆔 CRM: {crm_id if str(crm_id).strip() else '—'}\n"
            if comment: txt += f"💬 Комент: {comment}"
            kb = None
            if not str(crm_id).strip() or str(crm_id) in ["—", "0", "None", ""]:
                kb = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="✅ Створити в CRM", callback_data=f"confirm_order_{oid}")]])
            await m.answer(txt, reply_markup=kb, parse_mode=ParseMode.HTML)
    except Exception as e: await m.answer(f"Помилка: {e}")

# 🔥 НОВИЙ ФУНКЦІОНАЛ: НЕОПЛАЧЕНІ ЗАМОВЛЕННЯ 🔥
@dp.message(F.text == "💸 Неоплачені замовлення")
async def unpaid_orders(m: types.Message):
    if str(m.chat.id) != ADMIN_CHAT_ID: return
    await m.answer("🔎 Шукаю неоплачені замовлення в CRM...")
    
    try:
        # Отримуємо останні 100 замовлень
        r = requests.get(
            f"{CRM_API_URL}/orders", 
            headers={"Authorization": HUGEPROFIT_TOKEN}, 
            params={"limit": 100, "order": "id:desc"} 
        )
        
        if r.status_code != 200:
            await m.answer(f"❌ Помилка CRM API: {r.status_code}")
            return

        orders = r.json().get("data", [])
        unpaid_found = 0
        
        for order in orders:
            # Фільтруємо по статусу 10787 ("Не оплачено")
            if str(order.get('order_status')) == UNPAID_STATUS_ID:
                unpaid_found += 1
                
                # Витягуємо дані
                oid = order.get('order_number', '???')
                date_raw = str(order.get('date_ident', ''))
                # Форматування дати: 20260105 -> 05.01.2026
                if len(date_raw) == 8:
                    date_fmt = f"{date_raw[6:8]}.{date_raw[4:6]}.{date_raw[:4]}"
                else:
                    date_fmt = date_raw

                amount = float(order.get('amount') or 0.0)
                client = order.get('client', {})
                client_name = f"{client.get('first_name', '')} {client.get('last_name', '')}".strip()
                if not client_name: client_name = "Невідомий клієнт"
                
                # Формуємо повідомлення
                msg_text = (
                    f"⚠️ <b>НЕ ОПЛАЧЕНО</b>\n\n"
                    f"👤 {client_name}\n"
                    f"📅 {date_fmt}\n"
                    f"💰 {amount}$\n"
                    f"🆔 #{oid}\n\n"
                    f"👉 <a href='https://crm.h-profit.com/sales/{oid}'>Відкрити замовлення в CRM</a>"
                )
                
                await m.answer(msg_text, parse_mode="HTML", disable_web_page_preview=True)

        if unpaid_found == 0:
            await m.answer("✅ Неоплачених замовлень не знайдено.")
        else:
            await m.answer(f"Знайдено: {unpaid_found} шт.")

    except Exception as e:
        await m.answer(f"🔥 Помилка при обробці: {e}")

# --- CALLBACKS ---

@dp.callback_query(F.data.startswith("confirm_order_"))
async def confirm(q: types.CallbackQuery):
    oid = q.data.split("_")[-1]
    cell = orders_sheet.find(oid)
    if not cell: await q.answer("Не знайдено"); return
    row_num = cell.row; row = orders_sheet.row_values(row_num)
    while len(row) < 10: row.append("")
    user_email = row[1]
    try: items = json.loads(row[3])
    except: items = []
    try: total_val = float(row[4].replace(',','.'))
    except: total_val = 0.0
    try: customer_info = json.loads(row[6])
    except: customer_info = {}
    comment_val = row[7]
    
    crm_id = create_sale_in_crm(oid, items, total_val, customer_info, comment_val)
    
    if crm_id:
        orders_sheet.update_cell(row_num, 6, str(crm_id))
        orders_sheet.update_cell(row_num, 9, "Створено в CRM")
        
        # 🔥 ВІДПРАВКА ЛИСТА
        if user_email and "@" in user_email:
            send_email_html(user_email, f"Замовлення #{oid} підтверджено", get_order_email_body(oid, items, total_val))
        
        old_text = q.message.html_text if q.message.html_text else q.message.text
        new_text = f"{old_text}\n\n✅ <b>Створено в CRM (ID: {crm_id})</b>"
        await q.message.edit_text(new_text, parse_mode=ParseMode.HTML, reply_markup=None)
        await q.answer("Оброблено!")
    else: await q.answer("❌ Помилка CRM", show_alert=True)

@dp.callback_query(F.data.startswith("reg_approve_"))
async def reg_app(q: types.CallbackQuery):
    # Використовуємо split з обмеженням, щоб не ламати email, якщо там є _
    parts = q.data.split("_")
    email = "_".join(parts[2:]) # reg_approve_email@com -> email@com
    
    cell = users_sheet.find(email)
    if cell:
        users_sheet.update_cell(cell.row, 4, "TRUE")
        
        # 🔥 ВІДПРАВКА ЛИСТА
        send_email_html(email, "Акаунт активовано! Вітаємо", get_activation_email_body(email))
        
        old_text = q.message.html_text if q.message.html_text else q.message.text
        await q.message.edit_text(f"{old_text}\n\n✅ <b>АКТИВОВАНО</b>", parse_mode="HTML", reply_markup=None)
    else: await q.answer("Не знайдено в таблиці")

@dp.callback_query(F.data.startswith("reg_reject_"))
async def reg_rej(q: types.CallbackQuery):
    old_text = q.message.html_text if q.message.html_text else q.message.text
    await q.message.edit_text(f"{old_text}\n\n🚫 <b>ВІДХИЛЕНО</b>", parse_mode=ParseMode.HTML, reply_markup=None)

@dp.callback_query(F.data.startswith("up_"))
async def user_status(q: types.CallbackQuery):
    parts = q.data.split("_")
    # Формат up_T_login або up_F_login
    status_code = parts[1]
    login = "_".join(parts[2:])
    
    val = "TRUE" if status_code == "T" else "FALSE"
    
    c = users_sheet.find(login)
    if c: 
        users_sheet.update_cell(c.row, 4, val)
        await q.answer(f"Статус {login}: {val}")
    else:
        await q.answer("Користувача не знайдено")

@dp.callback_query(F.data.startswith("del_"))
async def user_del(q: types.CallbackQuery):
    login = q.data.split("_", 1)[1]
    c = users_sheet.find(login)
    if c: 
        users_sheet.delete_rows(c.row)
        await q.message.delete()
    else:
        await q.answer("Користувача не знайдено")

@dp.message(F.text == "🔄 Оновити таблицю")
async def run_sync_script(m: types.Message):
    if str(m.chat.id) != ADMIN_CHAT_ID: return
    status_msg = await m.answer("⏳ Запускаю оновлення таблиці (це може зайняти хвилину)...")
    
    # --- ВИПРАВЛЕННЯ ДЛЯ CPANEL ---
    # Отримуємо шлях до поточного python (того, що у віртуальному оточенні)
    venv_python = sys.executable 
    
    # Шукаємо скрипт поруч із ботом
    current_dir = os.path.dirname(os.path.abspath(__file__))
    script_path = os.path.join(current_dir, "crm2sheets.py")
    
    if not os.path.exists(script_path):
         await status_msg.edit_text(f"❌ Помилка: файл {script_path} не знайдено.")
         return

    try:
        # Запускаємо в окремому потоці, щоб не блокувати бота
        process = await asyncio.to_thread(subprocess.run, [venv_python, script_path], capture_output=True, text=True)
        
        if process.returncode == 0: 
            await status_msg.edit_text("✅ <b>Таблицю успішно оновлено!</b>\n\nДані з CRM завантажено.", parse_mode="HTML")
        else: 
            # Показуємо останні 500 символів помилки
            error_msg = process.stderr[-500:] if process.stderr else "Unknown error"
            await status_msg.edit_text(f"❌ <b>Помилка при оновленні:</b>\n<code>{error_msg}</code>", parse_mode="HTML")
    except Exception as e: 
        await status_msg.edit_text(f"❌ <b>Критична помилка бота:</b> {e}", parse_mode="HTML")

async def main():
    await bot.delete_webhook(drop_pending_updates=True)
    await dp.start_polling(bot)

if __name__ == "__main__":
    print("Bot is starting...")
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("Bot stopped by user")
    except Exception as e:
        print(f"Critical Error: {e}")