"""
Canifa Chatbot Automated Testing Script
========================================
Tự động test chatbot bằng cách:
1. Tạo Google Sheet (nếu chưa có)
2. Ghi danh sách câu hỏi test lên sheet
3. Call API chatbot cho từng câu hỏi
4. Ghi câu trả lời vào sheet

Usage:
    python backend/tests/auto_test_chatbot.py
    python backend/tests/auto_test_chatbot.py --api-url http://172.16.2.207:5000
"""

from __future__ import annotations

import argparse
import logging
import sys
import time
from datetime import datetime
from pathlib import Path

import gspread
import requests
from google.oauth2.service_account import Credentials

# ==============================================================================
# CONFIGURATION
# ==============================================================================

# Google Sheets
CREDENTIALS_FILE = Path(__file__).parent / "google_sheets_credentials.json"
SHEET_NAME = "Canifa Chatbot Test Results"
SCOPES = [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/drive",
]

# Service account email - share sheet với email này
SERVICE_ACCOUNT_EMAIL = "canifa-chatbot-test@rapid-potential-480209-q7.iam.gserviceaccount.com"

# Chatbot API
DEFAULT_API_URL = "http://localhost:5000"
CHAT_ENDPOINT = "/api/agent/chat-dev"
REQUEST_TIMEOUT = 120  # seconds

# Test questions - Các câu hỏi để test chatbot
TEST_QUESTIONS = [
    # Tìm kiếm sản phẩm cơ bản
    "Tìm cho mình chân váy màu đỏ",
    "Tìm quần màu đỏ",
    "Tìm áo polo nam",
    "Tìm áo khoác nữ mùa đông",

    # Tư vấn thời trang
    "Mình muốn mua đồ đi biển, gợi ý cho mình",
    "Cho mình xem áo sơ mi đi làm",
    "Gợi ý outfit đi dự tiệc",

    # Các tình huống đặc biệt
    "Áo size S giá dưới 500k",
    "Có khuyến mãi gì không?",
    "Cách đặt hàng online",
    "Cửa hàng nào gần nhất ở Hà Nội",

    # Edge cases
    "Xin chào",
    "Cảm ơn bạn",
    "Tìm sản phẩm abc123 không tồn tại",
]

# ==============================================================================
# LOGGING
# ==============================================================================

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s | %(levelname)-7s | %(message)s",
    datefmt="%H:%M:%S",
)
logger = logging.getLogger(__name__)


# ==============================================================================
# GOOGLE SHEETS FUNCTIONS
# ==============================================================================


def get_gspread_client() -> gspread.Client:
    """Khởi tạo gspread client với service account credentials."""
    if not CREDENTIALS_FILE.exists():
        logger.error(f"❌ Không tìm thấy file credentials: {CREDENTIALS_FILE}")
        logger.info(f"   Hãy download JSON key từ Google Cloud Console")
        logger.info(f"   và đặt tại: {CREDENTIALS_FILE}")
        sys.exit(1)

    creds = Credentials.from_service_account_file(str(CREDENTIALS_FILE), scopes=SCOPES)
    return gspread.authorize(creds)


def create_or_get_sheet(client: gspread.Client) -> gspread.Spreadsheet:
    """Tạo mới hoặc mở Google Sheet đã tồn tại."""
    try:
        # Thử mở sheet đã có
        spreadsheet = client.open(SHEET_NAME)
        logger.info(f"📄 Đã tìm thấy sheet: {SHEET_NAME}")
        return spreadsheet
    except gspread.SpreadsheetNotFound:
        # Tạo mới
        logger.info(f"📝 Tạo Google Sheet mới: {SHEET_NAME}")
        spreadsheet = client.create(SHEET_NAME)

        # Share sheet cho owner account
        spreadsheet.share("anhvuhoang2k2@gmail.com", perm_type="user", role="writer")
        logger.info(f"✅ Đã share sheet cho anhvuhoang2k2@gmail.com")

        return spreadsheet


def setup_worksheet(spreadsheet: gspread.Spreadsheet, test_week: str) -> gspread.Worksheet:
    """Setup worksheet với headers và câu hỏi test."""
    # Tạo hoặc lấy worksheet cho tuần test này
    worksheet_title = test_week

    try:
        worksheet = spreadsheet.worksheet(worksheet_title)
        logger.info(f"📋 Đã tìm thấy worksheet: {worksheet_title}")
    except gspread.WorksheetNotFound:
        worksheet = spreadsheet.add_worksheet(title=worksheet_title, rows=100, cols=6)
        logger.info(f"📋 Tạo worksheet mới: {worksheet_title}")

    # Setup headers
    headers = [
        "STT",
        "Câu hỏi test",
        "Tuần test & Lần test",
        "Câu trả lời của chatbot",
        "Thời gian response (ms)",
        "Trạng thái",
    ]

    # Check nếu headers đã có
    existing = worksheet.row_values(1)
    if not existing or existing[0] != "STT":
        worksheet.update("A1:F1", [headers])
        # Format header row - bold
        worksheet.format("A1:F1", {
            "textFormat": {"bold": True},
            "backgroundColor": {"red": 0.2, "green": 0.6, "blue": 0.9},
            "horizontalAlignment": "CENTER",
        })
        logger.info("✅ Đã setup headers")

    return worksheet


def fill_questions(worksheet: gspread.Worksheet, questions: list[str], test_label: str) -> int:
    """Ghi danh sách câu hỏi vào sheet. Returns starting row."""
    # Tìm row trống tiếp theo
    all_values = worksheet.get_all_values()
    start_row = len(all_values) + 1

    # Chuẩn bị data
    rows_data = []
    for i, question in enumerate(questions, 1):
        rows_data.append([
            start_row - 1 + i - 1,  # STT
            question,                # Câu hỏi
            test_label,             # Tuần test & Lần test
            "",                      # Câu trả lời (sẽ fill sau)
            "",                      # Thời gian
            "⏳ Đang chờ...",       # Trạng thái
        ])

    # Batch update
    cell_range = f"A{start_row}:F{start_row + len(questions) - 1}"
    worksheet.update(cell_range, rows_data)
    logger.info(f"✅ Đã ghi {len(questions)} câu hỏi (từ row {start_row})")

    return start_row


# ==============================================================================
# CHATBOT API FUNCTIONS
# ==============================================================================


def call_chatbot(api_url: str, question: str) -> dict:
    """
    Call chatbot API và trả về response.

    Returns:
        dict với keys: ai_response, response_time_ms, status, error
    """
    url = f"{api_url}{CHAT_ENDPOINT}"
    payload = {
        "user_query": question,
        "images": [],
    }

    try:
        start_time = time.time()
        response = requests.post(
            url,
            json=payload,
            headers={"Content-Type": "application/json"},
            timeout=REQUEST_TIMEOUT,
        )
        elapsed_ms = int((time.time() - start_time) * 1000)

        if response.status_code == 200:
            data = response.json()
            ai_response = data.get("ai_response", "")
            return {
                "ai_response": ai_response,
                "response_time_ms": elapsed_ms,
                "status": "✅ OK",
                "error": None,
            }
        else:
            return {
                "ai_response": f"HTTP {response.status_code}: {response.text[:200]}",
                "response_time_ms": elapsed_ms,
                "status": f"❌ HTTP {response.status_code}",
                "error": response.text[:200],
            }

    except requests.exceptions.Timeout:
        return {
            "ai_response": "TIMEOUT - Quá thời gian chờ",
            "response_time_ms": REQUEST_TIMEOUT * 1000,
            "status": "⏰ Timeout",
            "error": "Request timeout",
        }
    except requests.exceptions.ConnectionError:
        return {
            "ai_response": f"CONNECTION ERROR - Không thể kết nối tới {url}",
            "response_time_ms": 0,
            "status": "🔴 Connection Error",
            "error": f"Cannot connect to {url}",
        }
    except Exception as e:
        return {
            "ai_response": f"ERROR: {str(e)[:200]}",
            "response_time_ms": 0,
            "status": f"❌ Error",
            "error": str(e)[:200],
        }


# ==============================================================================
# MAIN TEST RUNNER
# ==============================================================================


def run_tests(api_url: str, test_week: str, test_round: int) -> None:
    """Chạy toàn bộ test flow."""
    test_label = f"{test_week} - Lần {test_round}"
    logger.info("=" * 60)
    logger.info(f"🚀 BẮT ĐẦU TEST: {test_label}")
    logger.info(f"   API URL: {api_url}")
    logger.info(f"   Số câu hỏi: {len(TEST_QUESTIONS)}")
    logger.info("=" * 60)

    # Step 1: Setup Google Sheets
    logger.info("\n📊 [Step 1] Khởi tạo Google Sheets...")
    client = get_gspread_client()
    spreadsheet = create_or_get_sheet(client)
    worksheet = setup_worksheet(spreadsheet, test_week)

    # Step 2: Fill câu hỏi
    logger.info("\n📝 [Step 2] Ghi câu hỏi test...")
    start_row = fill_questions(worksheet, TEST_QUESTIONS, test_label)

    # Step 3: Call chatbot API & update kết quả
    logger.info(f"\n🤖 [Step 3] Bắt đầu test {len(TEST_QUESTIONS)} câu hỏi...\n")

    success_count = 0
    total_time = 0

    for i, question in enumerate(TEST_QUESTIONS):
        row_idx = start_row + i
        logger.info(f"  [{i+1}/{len(TEST_QUESTIONS)}] Testing: '{question[:50]}...'")

        # Call API
        result = call_chatbot(api_url, question)

        # Truncate response cho sheet (max 50000 chars)
        ai_response = result["ai_response"]
        if len(ai_response) > 5000:
            ai_response = ai_response[:5000] + "... (truncated)"

        # Update sheet
        worksheet.update(f"D{row_idx}", [[ai_response]])
        worksheet.update(f"E{row_idx}", [[result["response_time_ms"]]])
        worksheet.update(f"F{row_idx}", [[result["status"]]])

        # Stats
        if "OK" in result["status"]:
            success_count += 1
        total_time += result["response_time_ms"]

        logger.info(f"         → {result['status']} ({result['response_time_ms']}ms)")

        # Rate limit: đợi 1 giây giữa các request
        if i < len(TEST_QUESTIONS) - 1:
            time.sleep(1)

    # Step 4: Summary
    logger.info("\n" + "=" * 60)
    logger.info("📊 KẾT QUẢ TEST:")
    logger.info(f"   ✅ Thành công: {success_count}/{len(TEST_QUESTIONS)}")
    logger.info(f"   ❌ Thất bại:   {len(TEST_QUESTIONS) - success_count}/{len(TEST_QUESTIONS)}")
    logger.info(f"   ⏱️  Tổng thời gian: {total_time}ms")
    logger.info(f"   📈 Trung bình:      {total_time // len(TEST_QUESTIONS)}ms/câu")
    logger.info(f"\n   📄 Sheet URL: {spreadsheet.url}")
    logger.info("=" * 60)


# ==============================================================================
# CLI ENTRY POINT
# ==============================================================================


def main():
    parser = argparse.ArgumentParser(description="Canifa Chatbot Automated Testing")
    parser.add_argument(
        "--api-url",
        default=DEFAULT_API_URL,
        help=f"Base URL of chatbot API (default: {DEFAULT_API_URL})",
    )
    parser.add_argument(
        "--week",
        default=None,
        help="Test week label (default: auto-calculated from current date)",
    )
    parser.add_argument(
        "--round",
        type=int,
        default=1,
        help="Test round number (default: 1)",
    )

    args = parser.parse_args()

    # Auto-calculate test week
    if args.week is None:
        now = datetime.now()
        week_num = now.isocalendar()[1]
        args.week = f"Tuần {week_num} ({now.strftime('%m/%Y')})"

    run_tests(
        api_url=args.api_url,
        test_week=args.week,
        test_round=args.round,
    )


if __name__ == "__main__":
    main()
