import logging
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy import delete
from sqlalchemy import text
from sqlalchemy.exc import SQLAlchemyError
from app.api.routes.products import router as product_router
from app.api.routes.auth import router as auth_router
from app.api.routes.vendors import router as vendor_router
from app.api.routes.violations import router as violations_router
from app.api.routes.dashboard import router as dashboard_router
#from app.core.config import settings
from app.db.base import Base
from app.db.session import engine
#from app import models  # noqa: F401
from app.core.security import utcnow
from app.models.password_reset_token import PasswordResetToken
# Import all models to ensure they are registered with SQLAlchemy
from app.models import User, RefreshToken, Vendor, Violation, Product, ScrapingResult  # noqa: F401

# Configure logging to show INFO level and above
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# Set log level for all app loggers to INFO
for logger_name in ['app', 'app.services', 'app.api']:
    logging.getLogger(logger_name).setLevel(logging.INFO)



def create_app() -> FastAPI:
    app = FastAPI(title="MARCO Scraping")

    # app.add_middleware(
    #     CORSMiddleware,
    #     allow_origin_regex=r"^(https:\/\/marco-fe\.testyourapp\.online\/?|<your-second-url-regex>\/?)$",
    #     allow_credentials=True,
    #     allow_methods=["*"],
    #     allow_headers=["*"],
    # )

    app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://marco-fe.testyourapp.online",
    ],
    allow_origin_regex=r"^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$",
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
    )

    @app.on_event("startup")
    async def _create_tables() -> None:
        try:
            async with engine.begin() as conn:
                await conn.run_sync(Base.metadata.create_all)
                await conn.execute(
                    text(
                        "ALTER TABLE users "
                        "ADD COLUMN IF NOT EXISTS tokens_invalid_before TIMESTAMPTZ NULL"
                    )
                )
                await conn.execute(
                    delete(PasswordResetToken).where(
                        (PasswordResetToken.expires_at <= utcnow())
                        | (PasswordResetToken.used_at.is_not(None))
                    )
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS barcode_number VARCHAR(255);")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS reference_id VARCHAR(255);")
                )
                # Add new columns for violation tracking
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS confirmation_count INTEGER DEFAULT 1;")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS source_type VARCHAR(50) DEFAULT 'registered';")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS last_confirmed_date TIMESTAMPTZ NULL;")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS notification_sent_at TIMESTAMPTZ NULL;")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS vendor_name VARCHAR(512);")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS marketplace VARCHAR(255);")
                )
                # make vendor_id nullable for discovered violations and scraping results
                await conn.execute(
                    text(
                        "ALTER TABLE violations ALTER COLUMN vendor_id DROP NOT NULL;"
                    )
                )
                await conn.execute(
                    text(
                        "ALTER TABLE scraping_results ALTER COLUMN vendor_id DROP NOT NULL;"
                    )
                )
                # Add price tracking columns to violations table
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS price_difference NUMERIC;")
                )
                await conn.execute(
                    text(
                        "ALTER TABLE violations ADD COLUMN IF NOT EXISTS percentage_difference NUMERIC;")
                )
                # Add last_scraped_date to products table
                await conn.execute(
                    text(
                        "ALTER TABLE products ADD COLUMN IF NOT EXISTS last_scraped_date TIMESTAMPTZ NULL;")
                )
                # Add last_execution_time to products table
                await conn.execute(
                    text(
                        "ALTER TABLE products ADD COLUMN IF NOT EXISTS last_execution_time VARCHAR(255);")
                )
                # Add domain_name to scraping_results table
                await conn.execute(
                    text(
                        "ALTER TABLE scraping_results ADD COLUMN IF NOT EXISTS domain_name VARCHAR(255);")
                )
        except SQLAlchemyError as e:
            raise RuntimeError(
                "Database connection failed during startup. "
                "Check DATABASE_URL in .env (username/password/host/port/db) and ensure Postgres is running."
            ) from e

    app.include_router(auth_router, prefix="/auth", tags=["auth"])
    app.include_router(vendor_router, tags=["vendors"])
    app.include_router(product_router, prefix="/api/products", tags=["products"])
    app.include_router(violations_router, prefix="/api/violations", tags=["violations"])
    app.include_router(dashboard_router, prefix="/api", tags=["dashboard"])
    return app


app = create_app()
