import os
import sys
import uvicorn
import logging
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from starlette.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response
from dotenv import load_dotenv

from src.cache.cache import PRODUCTS_CACHE, CATEGORIES_CACHE
from src.cache.download_cache import load_products_cache, load_categories_cache
from src.database import async_session
from src.manufacturer import router as manufacturer_router
from src.address import router as address_router
from src.store import router as store_router
from src.user import router as user_router
from src.auth import router as auth_router
from src.customer import router as customer_router
from src.review import router as review_router
from src.category import router as category_router
from src.product import router as product_router
from src.public import router as public_router
from src.seo import router as seo_router
from src.cache.clear_cache import router as clear_router
from src.cart import router as cart_router
from src.error.handlers import api_error_handler, http_exception_handler, general_exception_handler
from src.error.exceptions import APIError
from fastapi import HTTPException

if "--dev" in sys.argv:
    load_dotenv(".env")
else:
    load_dotenv(".env")

# Налаштування логування
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)


# Визначаємо BASE_DIR на початку для використання у middleware
BASE_DIR = Path(__file__).resolve().parent.parent

# Middleware для логування запитів до статичних файлів
class StaticFileLoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # Логуємо всі запити до /upload/
        if request.url.path.startswith("/upload/"):
            file_path = request.url.path.replace("/upload/", "")
            if file_path.startswith("converted/"):
                actual_path = BASE_DIR / "src" / "utils" / "upload" / file_path
                logger.info(f"📁 Static file request: {request.url.path}")
                logger.info(f"🔍 Looking for file: {actual_path}")
                logger.info(f"📂 File exists: {actual_path.exists()}")
                if actual_path.exists():
                    stat = actual_path.stat()
                    logger.info(f"📏 File size: {stat.st_size} bytes")
                    logger.info(f"🔐 File permissions: {oct(stat.st_mode)[-3:]}")
                    logger.info(f"👤 File owner: {stat.st_uid}")
                else:
                    logger.warning(f"❌ File not found: {actual_path}")

        response = await call_next(request)

        # Логуємо всі відповіді для статичних файлів
        if request.url.path.startswith("/upload/"):
            logger.info(f"📤 Response status: {response.status_code} for {request.url.path}")
            if response.status_code == 404:
                logger.error(f"🚫 404 for static file: {request.url.path}")
            elif response.status_code == 200:
                logger.info(f"✅ Successfully served: {request.url.path}")

        return response


# Створюємо папки, щоб вони гарантовано існували перед монтуванням
(BASE_DIR / "src" / "utils" / "upload" / "original").mkdir(parents=True, exist_ok=True)
(BASE_DIR / "src" / "utils" / "upload" / "converted").mkdir(parents=True, exist_ok=True)
(BASE_DIR / "src" / "utils" / "assets").mkdir(parents=True, exist_ok=True)

# Визначаємо шляхи до статичних файлів
original_dir = BASE_DIR / "src" / "utils" / "upload" / "original"
converted_dir = BASE_DIR / "src" / "utils" / "upload" / "converted"
assets_dir = BASE_DIR / "src" / "utils" / "assets"

app = FastAPI(
    title="XPRO ERP API",
    version="1.0.0",
    openapi_version="3.0.3",
    description="ERP API for XPRO"
    # root_path="/api" - убрано, потому что Apache вже видаляє /api/ при проксуванні
)
app.add_exception_handler(APIError, api_error_handler)
app.add_exception_handler(HTTPException, http_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)

# Монтуємо статичні файли ПЕРЕД додаванням middleware та роутерів
logger.info(f"📁 Mounting static directories:")
logger.info(f"  /upload/original -> {original_dir} (exists: {original_dir.exists()})")
logger.info(f"  /upload/converted -> {converted_dir} (exists: {converted_dir.exists()})")
logger.info(f"  /assets -> {assets_dir} (exists: {assets_dir.exists()})")

# Показуємо вміст директорій
if converted_dir.exists():
    files = list(converted_dir.glob("*.webp"))[:5]
    logger.info(f"📂 Sample files in converted: {[f.name for f in files]}")

try:
    app.mount("/upload/original", StaticFiles(directory=str(original_dir), follow_symlink=True), name="original")
    app.mount("/upload/converted", StaticFiles(directory=str(converted_dir), follow_symlink=True), name="converted")
    app.mount("/assets", StaticFiles(directory=str(assets_dir), follow_symlink=True), name="assets")
    logger.info("✅ Static files mounted successfully")
except Exception as e:
    logger.error(f"❌ Failed to mount static files: {e}")
    import traceback
    logger.error(traceback.format_exc())

# Додаємо middleware для логування ПІСЛЯ монтування статичних файлів
app.add_middleware(StaticFileLoggingMiddleware)

app.include_router(manufacturer_router.router)
app.include_router(address_router.router)
app.include_router(store_router.router)
app.include_router(user_router.router)
app.include_router(auth_router.router)
app.include_router(customer_router.router)
app.include_router(review_router.router)
app.include_router(category_router.router)
app.include_router(product_router.router)
app.include_router(public_router.router)
app.include_router(cart_router.router)
app.include_router(seo_router.router)
app.include_router(clear_router)

origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.on_event("startup")
async def startup_event():
    async with async_session() as session:
        await load_products_cache(batch_size=50_000)
        await load_categories_cache(session)
    print(f"✅ Завантажено {len(PRODUCTS_CACHE)} продуктів")
    print(f"✅ Завантажено {len(CATEGORIES_CACHE)} категорій")


if __name__ == "__main__":
    uvicorn.run(
        "src.main:app",
        host="0.0.0.0",
        port=int(os.getenv("FASTAPI_PORT")),
        reload=True
    )