import os
from datetime import datetime
from pydantic import BaseModel
from typing import Optional
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse, FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import sqlite3

app = FastAPI(title="Scanner Pro Python")

# สร้างฐานข้อมูล SQLite และตารางถ้ายังไม่มี
DB_FILE = "database.db"

def init_db():
    conn = sqlite3.connect(DB_FILE)
    cursor = conn.cursor()
    cursor.execute("""
    CREATE TABLE IF NOT EXISTS scan_history (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        code TEXT NOT NULL,
        device_name TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    """)
    cursor.execute("""
    CREATE TABLE IF NOT EXISTS system_settings (
        setting_key TEXT PRIMARY KEY,
        setting_value TEXT
    );
    """)
    # ใส่ค่าเริ่มต้นสำหรับ URL แชร์
    cursor.execute("INSERT OR IGNORE INTO system_settings (setting_key, setting_value) VALUES ('share_url', '');")
    conn.commit()
    conn.close()

init_db()

# คอนฟิกหน้าเว็บ (Templates)
templates = Jinja2Templates(directory="templates")

# โมเดลรับข้อมูล JSON API (เทียบเท่า $input ใน PHP)
class APIRequest(BaseModel):
    action: str
    data: Optional[dict] = None

# ---- หน้าเว็บหน้าแรก & แดชบอร์ด ----
@app.get("/", response_class=HTMLResponse)
async def read_index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.get("/dashboard", response_class=HTMLResponse)
async def read_dashboard(request: Request):
    return templates.TemplateResponse("dashboard.html", {"request": request})

# ส่งไฟล์เสียง beep.mp3 ออกไปตาม request หน้าบ้าน
@app.get("/beep.mp3")
async def get_beep():
    if os.path.exists("beep.mp3"):
        return FileResponse("beep.mp3", media_type="audio/mpeg")
    return JSONResponse(status_code=404, content={"error": "File not found"})


# ---- ระบบ API ส่วนกลาง (ทดแทน api.php) ----
@app.post("/api.php")
async def handle_api(req: APIRequest):
    action = req.action
    data = req.data or {}

    conn = sqlite3.connect(DB_FILE)
    conn.row_factory = sqlite3.Row
    cursor = conn.cursor()

    # 1. ฟีเจอร์ saveCode
    if action == 'saveCode':
        code = data.get('code', '')
        device = data.get('deviceName', 'Unknown')
        if not code:
            conn.close()
            return {"success": False}

        # เช็คข้อมูลซ้ำ
        cursor.execute("SELECT id FROM scan_history WHERE code = ?", (code,))
        if cursor.fetchone():
            conn.close()
            return {"success": False, "duplicate": True}

        # บันทึกข้อมูล
        cursor.execute("INSERT INTO scan_history (code, device_name) VALUES (?, ?)", (code, device))
        conn.commit()
        conn.close()
        return {"success": True}

    # 2. ฟีเจอร์ getHistory
    elif action == 'getHistory':
        cursor.execute("SELECT COUNT(*) as total FROM scan_history")
        total = cursor.fetchone()['total']

        cursor.execute("SELECT id, code, device_name, created_at FROM scan_history ORDER BY created_at DESC LIMIT 50")
        rows = cursor.fetchall()

        history_list = []
        for row in rows:
            # แปลงเวลาให้แสดงผลรูปแบบ H:i:s (ใช้เวลาจาก SQLite คอนเวิร์ตเป็น Object ก่อน)
            try:
                dt = datetime.strptime(row['created_at'], "%Y-%m-%d %H:%M:%S")
            except:
                dt = datetime.now() # ค่าสำรองกรณีแปลงพาร์สไม่ผ่าน
            
            history_list.append({
                'row': row['id'],
                'code': row['code'],
                'time': dt.strftime('%H:%M:%S'),
                'device': row['device_name']
            })

        conn.close()
        return {"history": history_list, "total": total}

    # 3. ฟีเจอร์ getAllHistory (สำหรับ Export Excel)
    elif action == 'getAllHistory':
        cursor.execute("SELECT created_at, code, device_name FROM scan_history ORDER BY created_at DESC")
        rows = cursor.fetchall()

        data_list = []
        for i, row in enumerate(rows, 1):
            data_list.append({
                'No': i,
                'Date Time': row['created_at'],
                'Code': row['code'],
                'Device': row['device_name']
            })
        conn.close()
        return {"data": data_list}

    # 4. ฟีเจอร์ deleteAllHistory (ล้างข้อมูลตารางและ Reset ID ด้วยคำสั่งสไตล์ SQLite)
    elif action == 'deleteAllHistory':
        password = data.get('password', '')
        if password == '1234':
            cursor.execute("DELETE FROM scan_history")
            cursor.execute("DELETE FROM sqlite_sequence WHERE name='scan_history'") # SQLite Reset Auto Increment เริ่มต้นนับ 1 ใหม่
            conn.commit()
            conn.close()
            return {"success": True}
        else:
            conn.close()
            return {"success": False, "message": "Incorrect Password"}

    # 5. ฟีเจอร์ deleteHistory (ลบรายชิ้น)
    elif action == 'deleteHistory':
        # ใน index.php ส่ง data มาเป็นตัวเลขตรงๆ, ใน dashboard ส่งเป็น Object ต้องเช็คประเภทข้อมูล
        id_to_delete = data if isinstance(data, int) else data.get('id', 0)
        cursor.execute("DELETE FROM scan_history WHERE id = ?", (id_to_delete,))
        conn.commit()
        conn.close()
        return {"success": True}

    # 6. ฟีเจอร์ saveConfig
    elif action == 'saveConfig':
        url = data.get('url', '')
        cursor.execute("INSERT INTO system_settings (setting_key, setting_value) VALUES ('share_url', ?) ON CONFLICT(setting_key) DO UPDATE SET setting_value = ?", (url, url))
        conn.commit()
        conn.close()
        return {"success": True}

    # 7. ฟีเจอร์ getConfig
    elif action == 'getConfig':
        cursor.execute("SELECT setting_value FROM system_settings WHERE setting_key = 'share_url'")
        res = cursor.fetchone()
        url_val = res['setting_value'] if res else ''
        conn.close()
        return {"url": url_val}

    conn.close()
    raise HTTPException(status_code=400, detail="Invalid Action")