import os
from fastapi import FastAPI, HTTPException, Depends, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlalchemy.orm import Session
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field
from .database import engine, Base
from starlette.middleware.sessions import SessionMiddleware
from .models import User, SearchHistory
from app.router import router as lead_router
from typing import List, Dict, Optional
from .utils import PincodeGeoLocator
from .services import get_nearby_businesses, get_coordinates_from_google
from .auth import router as auth_router
from .dependencies import get_approved_user
from .database import get_db

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PINCODE_PATH = os.path.join(BASE_DIR, "data", "india_pincodes.csv")
STATIC_PATH = os.path.join(BASE_DIR, "static")

# app initialization
app = FastAPI(title="Local Business Lead Finder")
# static path mounting
app.mount("/static", StaticFiles(directory=STATIC_PATH), name="static")
locator = PincodeGeoLocator(PINCODE_PATH)
# routers
app.include_router(lead_router)
app.include_router(auth_router)


Base.metadata.create_all(bind=engine)
app.add_middleware(SessionMiddleware, secret_key="a-very-secret-key-change-this-later")
# class SearchRequest(BaseModel):
#     pincodes: List[int] = Field(..., max_items=10)
#     keyword: str
#     distance: int

class SearchRequest(BaseModel):
    pincodes: List[int]
    keyword: str
    distance: int
    tokens: Optional[Dict[str, str]] = None


@app.get("/")
async def read_index():
    return FileResponse(os.path.join(STATIC_PATH, 'index.html'))


@app.post("/search-businesses")
async def search_businesses(request: SearchRequest, db: Session = Depends(get_db), current_user: User = Depends(get_approved_user)):
    all_results = []
    new_tokens = {}
    
    if not request.tokens:
        new_history = SearchHistory(
            user_id=current_user.id,
            keyword=request.keyword,
            pincodes=", ".join(map(str, request.pincodes))
        )
        db.add(new_history)
        db.commit()
    
    for pin in request.pincodes:
        # If this is a "Load More" call, check if this specific pin still has more results
        current_token = request.tokens.get(str(pin)) if request.tokens else None
        
        # If we are loading more but this pin has no more results, skip it
        if request.tokens and not current_token:
            continue

        lat, lng = locator.get_coordinates(pin)
        
        if not lat or not lng:
            print(f"Pincode {pin} missing in CSV. Attempting Google Geocoding fallback...")
            lat, lng = await get_coordinates_from_google(pin)

        if not lat or not lng:
            print(f"Pincode {pin} could not be geocoded. Skipping...")
            continue
        
        print(f"Searching for {request.keyword} around pin {pin} at ({lat}, {lng}) with radius {request.distance}m and token {current_token}")
        results, next_token = await get_nearby_businesses(lat, lng, request.distance, request.keyword, current_token)

        for r in results:
            r["pincode"] = pin
            all_results.append(r)
        
        if next_token:
            new_tokens[str(pin)] = next_token
        if len(all_results) == 0:
            all_results.append('No data for this pincode')
        

    return {
        "count": len(all_results),
        "data": all_results,
        "nextPageTokens": new_tokens # Send these back to the frontend
    }


@app.get("/admin-panel")
async def admin_page(request: Request, db: Session = Depends(get_db)):
    user_session = request.session.get('user')
    if not user_session:
        return RedirectResponse(url="/auth/login")
    
    user = db.query(User).filter(User.email == user_session['email']).first()
    if not user or not user.is_superuser:
        return HTMLResponse(content="<h1>403 Forbidden: Admin Access Only</h1>", status_code=403)
    
    return FileResponse("static/admin.html")


@app.get("/recent-searches")
async def get_recent_searches(
    db: Session = Depends(get_db), 
    current_user: User = Depends(get_approved_user)
):
    # Get last 10 searches for this user
    history = db.query(SearchHistory)\
        .filter(SearchHistory.user_id == current_user.id)\
        .order_by(SearchHistory.created_at.desc())\
        .limit(10).all()
    
    return history