"""
Business endpoints (Restaurants, Markets, Adventures)
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import or_
from typing import List, Optional
from uuid import UUID

from app.db.session import get_db
from app.models.business import (
    Restaurant as RestaurantModel, 
    RestaurantCategory as RestaurantCategoryModel, 
    RestaurantItem as RestaurantItemModel, 
    RestaurantPhoto as RestaurantPhotoModel,
    Market, MarketCategory, MarketItem, Adventure, AdventureSchedule
)
from app.models.company import Company
from app.models.beach import BeachPlace
from app.models.user import Currency, Country
from app.schemas.business import (
    RestaurantCreate, RestaurantUpdate, Restaurant, RestaurantPhoto,
    RestaurantCategoryCreate, RestaurantCategoryUpdate, RestaurantCategory,
    RestaurantItemCreate, RestaurantItemUpdate, RestaurantItem,
    MarketCreate, MarketUpdate, Market,
    MarketCategoryCreate, MarketCategoryUpdate, MarketCategory,
    MarketItemCreate, MarketItemUpdate, MarketItem,
    AdventureCreate, AdventureUpdate, Adventure,
    AdventureScheduleCreate, AdventureScheduleUpdate, AdventureSchedule
)

router = APIRouter()


# Restaurant endpoints
@router.post("/restaurants/", response_model=Restaurant)
def create_restaurant(
    restaurant: RestaurantCreate,
    db: Session = Depends(get_db)
):
    # Verify company exists
    db_company = db.query(Company).filter(Company.company_id == restaurant.company_id).first()
    if db_company is None:
        raise HTTPException(status_code=404, detail="Company not found")
    
    # Verify beach place exists
    db_beach_place = db.query(BeachPlace).filter(BeachPlace.beach_place_id == restaurant.beach_place_id).first()
    if db_beach_place is None:
        raise HTTPException(status_code=404, detail="Beach place not found")
    
    db_restaurant = Restaurant(**restaurant.dict())
    db.add(db_restaurant)
    db.commit()
    db.refresh(db_restaurant)
    return db_restaurant


@router.get("/restaurants/", response_model=dict)
def read_restaurants(
    skip: int = 0,
    limit: int = 100,
    search: Optional[str] = None,
    city: Optional[str] = None,
    cuisine_type: Optional[str] = None,
    db: Session = Depends(get_db)
):
    query = db.query(RestaurantModel).options(joinedload(RestaurantModel.photos))
    
    # Apply filters
    if search:
        search_term = f"%{search}%"
        query = query.filter(
            or_(
                RestaurantModel.restaurant_name.ilike(search_term),
                RestaurantModel.description.ilike(search_term),
                RestaurantModel.cuisine_type.ilike(search_term)
            )
        )
    
    if city:
        query = query.filter(RestaurantModel.city.ilike(f"%{city}%"))
    
    if cuisine_type:
        query = query.filter(RestaurantModel.cuisine_type.ilike(f"%{cuisine_type}%"))
    
    # Get total count
    total = query.count()
    
    # Apply pagination
    restaurants = query.offset(skip).limit(limit).all()
    
    # Prepare response with additional data
    restaurant_data = []
    for restaurant in restaurants:
        restaurant_dict = {
            "restaurant_id": restaurant.restaurant_id,
            "name": restaurant.restaurant_name,
            "description": restaurant.description,
            "cuisine_type": restaurant.cuisine_type,
            "category_name": restaurant.cuisine_type,  # Using cuisine_type as category for now
            "address": restaurant.address,
            "city": restaurant.city,
            "latitude": restaurant.latitude,
            "longitude": restaurant.longitude,
            "opening_time": restaurant.opening_time.strftime("%H:%M") if restaurant.opening_time else None,
            "closing_time": restaurant.closing_time.strftime("%H:%M") if restaurant.closing_time else None,
            "is_active": restaurant.is_active,
            "created_at": restaurant.created_at,
            "photos": [
                {
                    "photo_id": photo.photo_id,
                    "photo_url": photo.photo_url,
                    "photo_caption": photo.photo_caption,
                    "is_primary": photo.is_primary,
                    "photo_type": photo.photo_type
                }
                for photo in restaurant.photos
            ],
            "rating": None,  # Real rating data when available
            "booking_count": 0  # Real booking count when available
        }
        restaurant_data.append(restaurant_dict)
    
    return {
        "restaurants": restaurant_data,
        "total": total,
        "skip": skip,
        "limit": limit
    }


@router.get("/restaurants/{restaurant_id}", response_model=dict)
def read_restaurant(
    restaurant_id: UUID,
    db: Session = Depends(get_db)
):
    db_restaurant = db.query(RestaurantModel).options(
        joinedload(RestaurantModel.photos),
        joinedload(RestaurantModel.items)
    ).filter(RestaurantModel.restaurant_id == restaurant_id).first()
    
    if db_restaurant is None:
        raise HTTPException(status_code=404, detail="Restaurant not found")
    
    # Prepare detailed response
    restaurant_data = {
        "restaurant_id": db_restaurant.restaurant_id,
        "name": db_restaurant.restaurant_name,
        "description": db_restaurant.description,
        "cuisine_type": db_restaurant.cuisine_type,
        "category_name": db_restaurant.cuisine_type,  # Using cuisine_type as category for now
        "address": db_restaurant.address,
        "city": db_restaurant.city,
        "latitude": db_restaurant.latitude,
        "longitude": db_restaurant.longitude,
        "opening_time": db_restaurant.opening_time.strftime("%H:%M") if db_restaurant.opening_time else None,
        "closing_time": db_restaurant.closing_time.strftime("%H:%M") if db_restaurant.closing_time else None,
        "is_active": db_restaurant.is_active,
        "created_at": db_restaurant.created_at,
        "photos": [
            {
                "photo_id": photo.photo_id,
                "photo_url": photo.photo_url,
                "photo_caption": photo.photo_caption,
                "is_primary": photo.is_primary,
                "photo_type": photo.photo_type
            }
            for photo in db_restaurant.photos
        ],
        "menu_items": [
            {
                "item_id": item.item_id,
                "name": item.item_name,
                "description": item.description,
                "price": float(item.price) if item.price else None,
                "category": item.category.category_name if item.category else None
            }
            for item in db_restaurant.items
        ],
        "rating": None,  # Real rating data when available
        "booking_count": 0  # Real booking count when available
    }
    
    return restaurant_data


@router.put("/restaurants/{restaurant_id}", response_model=Restaurant)
def update_restaurant(
    restaurant_id: UUID,
    restaurant: RestaurantUpdate,
    db: Session = Depends(get_db)
):
    db_restaurant = db.query(Restaurant).filter(Restaurant.restaurant_id == restaurant_id).first()
    if db_restaurant is None:
        raise HTTPException(status_code=404, detail="Restaurant not found")
    
    update_data = restaurant.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_restaurant, key, value)
    
    db.commit()
    db.refresh(db_restaurant)
    return db_restaurant


@router.delete("/restaurants/{restaurant_id}")
def delete_restaurant(
    restaurant_id: UUID,
    db: Session = Depends(get_db)
):
    db_restaurant = db.query(Restaurant).filter(Restaurant.restaurant_id == restaurant_id).first()
    if db_restaurant is None:
        raise HTTPException(status_code=404, detail="Restaurant not found")
    
    db.delete(db_restaurant)
    db.commit()
    return {"message": "Restaurant deleted successfully"}


# Restaurant Category endpoints
@router.post("/restaurant-categories/", response_model=RestaurantCategory)
def create_restaurant_category(
    category: RestaurantCategoryCreate,
    db: Session = Depends(get_db)
):
    # Verify restaurant exists
    db_restaurant = db.query(Restaurant).filter(Restaurant.restaurant_id == category.restaurant_id).first()
    if db_restaurant is None:
        raise HTTPException(status_code=404, detail="Restaurant not found")
    
    db_category = RestaurantCategory(**category.dict())
    db.add(db_category)
    db.commit()
    db.refresh(db_category)
    return db_category


@router.get("/restaurant-categories/", response_model=List[RestaurantCategory])
def read_restaurant_categories(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    categories = db.query(RestaurantCategory).offset(skip).limit(limit).all()
    return categories


@router.get("/restaurant-categories/{category_id}", response_model=RestaurantCategory)
def read_restaurant_category(
    category_id: int,
    db: Session = Depends(get_db)
):
    db_category = db.query(RestaurantCategory).filter(RestaurantCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Restaurant category not found")
    return db_category


@router.put("/restaurant-categories/{category_id}", response_model=RestaurantCategory)
def update_restaurant_category(
    category_id: int,
    category: RestaurantCategoryUpdate,
    db: Session = Depends(get_db)
):
    db_category = db.query(RestaurantCategory).filter(RestaurantCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Restaurant category not found")
    
    update_data = category.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_category, key, value)
    
    db.commit()
    db.refresh(db_category)
    return db_category


@router.delete("/restaurant-categories/{category_id}")
def delete_restaurant_category(
    category_id: int,
    db: Session = Depends(get_db)
):
    db_category = db.query(RestaurantCategory).filter(RestaurantCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Restaurant category not found")
    
    db.delete(db_category)
    db.commit()
    return {"message": "Restaurant category deleted successfully"}


# Restaurant Item endpoints
@router.post("/restaurant-items/", response_model=RestaurantItem)
def create_restaurant_item(
    item: RestaurantItemCreate,
    db: Session = Depends(get_db)
):
    # Verify restaurant exists
    db_restaurant = db.query(Restaurant).filter(Restaurant.restaurant_id == item.restaurant_id).first()
    if db_restaurant is None:
        raise HTTPException(status_code=404, detail="Restaurant not found")
    
    # Verify category exists
    db_category = db.query(RestaurantCategory).filter(RestaurantCategory.category_id == item.category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Restaurant category not found")
    
    # Verify currency exists
    db_currency = db.query(Currency).filter(Currency.currency_id == item.currency_id).first()
    if db_currency is None:
        raise HTTPException(status_code=404, detail="Currency not found")
    
    db_item = RestaurantItem(**item.dict())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item


@router.get("/restaurant-items/", response_model=List[RestaurantItem])
def read_restaurant_items(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    items = db.query(RestaurantItem).offset(skip).limit(limit).all()
    return items


@router.get("/restaurant-items/{item_id}", response_model=RestaurantItem)
def read_restaurant_item(
    item_id: UUID,
    db: Session = Depends(get_db)
):
    db_item = db.query(RestaurantItem).filter(RestaurantItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Restaurant item not found")
    return db_item


@router.put("/restaurant-items/{item_id}", response_model=RestaurantItem)
def update_restaurant_item(
    item_id: UUID,
    item: RestaurantItemUpdate,
    db: Session = Depends(get_db)
):
    db_item = db.query(RestaurantItem).filter(RestaurantItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Restaurant item not found")
    
    update_data = item.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_item, key, value)
    
    db.commit()
    db.refresh(db_item)
    return db_item


@router.delete("/restaurant-items/{item_id}")
def delete_restaurant_item(
    item_id: UUID,
    db: Session = Depends(get_db)
):
    db_item = db.query(RestaurantItem).filter(RestaurantItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Restaurant item not found")
    
    db.delete(db_item)
    db.commit()
    return {"message": "Restaurant item deleted successfully"}


# Market endpoints
@router.post("/markets/", response_model=Market)
def create_market(
    market: MarketCreate,
    db: Session = Depends(get_db)
):
    # Verify company exists
    db_company = db.query(Company).filter(Company.company_id == market.company_id).first()
    if db_company is None:
        raise HTTPException(status_code=404, detail="Company not found")
    
    # Verify beach place exists
    db_beach_place = db.query(BeachPlace).filter(BeachPlace.beach_place_id == market.beach_place_id).first()
    if db_beach_place is None:
        raise HTTPException(status_code=404, detail="Beach place not found")
    
    db_market = Market(**market.dict())
    db.add(db_market)
    db.commit()
    db.refresh(db_market)
    return db_market


@router.get("/markets/", response_model=List[Market])
def read_markets(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    markets = db.query(Market).offset(skip).limit(limit).all()
    return markets


@router.get("/markets/{market_id}", response_model=Market)
def read_market(
    market_id: UUID,
    db: Session = Depends(get_db)
):
    db_market = db.query(Market).filter(Market.market_id == market_id).first()
    if db_market is None:
        raise HTTPException(status_code=404, detail="Market not found")
    return db_market


@router.put("/markets/{market_id}", response_model=Market)
def update_market(
    market_id: UUID,
    market: MarketUpdate,
    db: Session = Depends(get_db)
):
    db_market = db.query(Market).filter(Market.market_id == market_id).first()
    if db_market is None:
        raise HTTPException(status_code=404, detail="Market not found")
    
    update_data = market.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_market, key, value)
    
    db.commit()
    db.refresh(db_market)
    return db_market


@router.delete("/markets/{market_id}")
def delete_market(
    market_id: UUID,
    db: Session = Depends(get_db)
):
    db_market = db.query(Market).filter(Market.market_id == market_id).first()
    if db_market is None:
        raise HTTPException(status_code=404, detail="Market not found")
    
    db.delete(db_market)
    db.commit()
    return {"message": "Market deleted successfully"}


# Market Category endpoints
@router.post("/market-categories/", response_model=MarketCategory)
def create_market_category(
    category: MarketCategoryCreate,
    db: Session = Depends(get_db)
):
    # Verify market exists
    db_market = db.query(Market).filter(Market.market_id == category.market_id).first()
    if db_market is None:
        raise HTTPException(status_code=404, detail="Market not found")
    
    db_category = MarketCategory(**category.dict())
    db.add(db_category)
    db.commit()
    db.refresh(db_category)
    return db_category


@router.get("/market-categories/", response_model=List[MarketCategory])
def read_market_categories(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    categories = db.query(MarketCategory).offset(skip).limit(limit).all()
    return categories


@router.get("/market-categories/{category_id}", response_model=MarketCategory)
def read_market_category(
    category_id: int,
    db: Session = Depends(get_db)
):
    db_category = db.query(MarketCategory).filter(MarketCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Market category not found")
    return db_category


@router.put("/market-categories/{category_id}", response_model=MarketCategory)
def update_market_category(
    category_id: int,
    category: MarketCategoryUpdate,
    db: Session = Depends(get_db)
):
    db_category = db.query(MarketCategory).filter(MarketCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Market category not found")
    
    update_data = category.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_category, key, value)
    
    db.commit()
    db.refresh(db_category)
    return db_category


@router.delete("/market-categories/{category_id}")
def delete_market_category(
    category_id: int,
    db: Session = Depends(get_db)
):
    db_category = db.query(MarketCategory).filter(MarketCategory.category_id == category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Market category not found")
    
    db.delete(db_category)
    db.commit()
    return {"message": "Market category deleted successfully"}


# Market Item endpoints
@router.post("/market-items/", response_model=MarketItem)
def create_market_item(
    item: MarketItemCreate,
    db: Session = Depends(get_db)
):
    # Verify market exists
    db_market = db.query(Market).filter(Market.market_id == item.market_id).first()
    if db_market is None:
        raise HTTPException(status_code=404, detail="Market not found")
    
    # Verify category exists
    db_category = db.query(MarketCategory).filter(MarketCategory.category_id == item.category_id).first()
    if db_category is None:
        raise HTTPException(status_code=404, detail="Market category not found")
    
    # Verify currency exists
    db_currency = db.query(Currency).filter(Currency.currency_id == item.currency_id).first()
    if db_currency is None:
        raise HTTPException(status_code=404, detail="Currency not found")
    
    db_item = MarketItem(**item.dict())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item


@router.get("/market-items/", response_model=List[MarketItem])
def read_market_items(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    items = db.query(MarketItem).offset(skip).limit(limit).all()
    return items


@router.get("/market-items/{item_id}", response_model=MarketItem)
def read_market_item(
    item_id: UUID,
    db: Session = Depends(get_db)
):
    db_item = db.query(MarketItem).filter(MarketItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Market item not found")
    return db_item


@router.put("/market-items/{item_id}", response_model=MarketItem)
def update_market_item(
    item_id: UUID,
    item: MarketItemUpdate,
    db: Session = Depends(get_db)
):
    db_item = db.query(MarketItem).filter(MarketItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Market item not found")
    
    update_data = item.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_item, key, value)
    
    db.commit()
    db.refresh(db_item)
    return db_item


@router.delete("/market-items/{item_id}")
def delete_market_item(
    item_id: UUID,
    db: Session = Depends(get_db)
):
    db_item = db.query(MarketItem).filter(MarketItem.item_id == item_id).first()
    if db_item is None:
        raise HTTPException(status_code=404, detail="Market item not found")
    
    db.delete(db_item)
    db.commit()
    return {"message": "Market item deleted successfully"}


# Adventure endpoints
@router.post("/adventures/", response_model=Adventure)
def create_adventure(
    adventure: AdventureCreate,
    db: Session = Depends(get_db)
):
    # Verify company exists
    db_company = db.query(Company).filter(Company.company_id == adventure.company_id).first()
    if db_company is None:
        raise HTTPException(status_code=404, detail="Company not found")
    
    # Verify beach place exists
    db_beach_place = db.query(BeachPlace).filter(BeachPlace.beach_place_id == adventure.beach_place_id).first()
    if db_beach_place is None:
        raise HTTPException(status_code=404, detail="Beach place not found")
    
    # Verify currency exists
    db_currency = db.query(Currency).filter(Currency.currency_id == adventure.currency_id).first()
    if db_currency is None:
        raise HTTPException(status_code=404, detail="Currency not found")
    
    db_adventure = Adventure(**adventure.dict())
    db.add(db_adventure)
    db.commit()
    db.refresh(db_adventure)
    return db_adventure


@router.get("/adventures/", response_model=List[Adventure])
def read_adventures(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    adventures = db.query(Adventure).offset(skip).limit(limit).all()
    return adventures


@router.get("/adventures/{adventure_id}", response_model=Adventure)
def read_adventure(
    adventure_id: UUID,
    db: Session = Depends(get_db)
):
    db_adventure = db.query(Adventure).filter(Adventure.adventure_id == adventure_id).first()
    if db_adventure is None:
        raise HTTPException(status_code=404, detail="Adventure not found")
    return db_adventure


@router.put("/adventures/{adventure_id}", response_model=Adventure)
def update_adventure(
    adventure_id: UUID,
    adventure: AdventureUpdate,
    db: Session = Depends(get_db)
):
    db_adventure = db.query(Adventure).filter(Adventure.adventure_id == adventure_id).first()
    if db_adventure is None:
        raise HTTPException(status_code=404, detail="Adventure not found")
    
    update_data = adventure.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_adventure, key, value)
    
    db.commit()
    db.refresh(db_adventure)
    return db_adventure


@router.delete("/adventures/{adventure_id}")
def delete_adventure(
    adventure_id: UUID,
    db: Session = Depends(get_db)
):
    db_adventure = db.query(Adventure).filter(Adventure.adventure_id == adventure_id).first()
    if db_adventure is None:
        raise HTTPException(status_code=404, detail="Adventure not found")
    
    db.delete(db_adventure)
    db.commit()
    return {"message": "Adventure deleted successfully"}


# Adventure Schedule endpoints
@router.post("/adventure-schedules/", response_model=AdventureSchedule)
def create_adventure_schedule(
    schedule: AdventureScheduleCreate,
    db: Session = Depends(get_db)
):
    # Verify adventure exists
    db_adventure = db.query(Adventure).filter(Adventure.adventure_id == schedule.adventure_id).first()
    if db_adventure is None:
        raise HTTPException(status_code=404, detail="Adventure not found")
    
    db_schedule = AdventureSchedule(**schedule.dict())
    db.add(db_schedule)
    db.commit()
    db.refresh(db_schedule)
    return db_schedule


@router.get("/adventure-schedules/", response_model=List[AdventureSchedule])
def read_adventure_schedules(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    schedules = db.query(AdventureSchedule).offset(skip).limit(limit).all()
    return schedules


@router.get("/adventure-schedules/{schedule_id}", response_model=AdventureSchedule)
def read_adventure_schedule(
    schedule_id: int,
    db: Session = Depends(get_db)
):
    db_schedule = db.query(AdventureSchedule).filter(AdventureSchedule.schedule_id == schedule_id).first()
    if db_schedule is None:
        raise HTTPException(status_code=404, detail="Adventure schedule not found")
    return db_schedule


@router.put("/adventure-schedules/{schedule_id}", response_model=AdventureSchedule)
def update_adventure_schedule(
    schedule_id: int,
    schedule: AdventureScheduleUpdate,
    db: Session = Depends(get_db)
):
    db_schedule = db.query(AdventureSchedule).filter(AdventureSchedule.schedule_id == schedule_id).first()
    if db_schedule is None:
        raise HTTPException(status_code=404, detail="Adventure schedule not found")
    
    update_data = schedule.dict(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_schedule, key, value)
    
    db.commit()
    db.refresh(db_schedule)
    return db_schedule


@router.delete("/adventure-schedules/{schedule_id}")
def delete_adventure_schedule(
    schedule_id: int,
    db: Session = Depends(get_db)
):
    db_schedule = db.query(AdventureSchedule).filter(AdventureSchedule.schedule_id == schedule_id).first()
    if db_schedule is None:
        raise HTTPException(status_code=404, detail="Adventure schedule not found")
    
    db.delete(db_schedule)
    db.commit()
    return {"message": "Adventure schedule deleted successfully"}