from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from sqlalchemy import or_
from typing import Optional
from ...shared.config.database import get_db
from ...security.middleware.auth import get_current_user, authorize_roles
from ...auth.models.user import User
from ..models.service import Service
from ..models.service_usage import ServiceUsage
from ...bookings.models.booking import Booking, BookingStatus
router = APIRouter(prefix='/services', tags=['services'])

@router.get('/')
async def get_services(search: Optional[str]=Query(None), status_filter: Optional[str]=Query(None, alias='status'), page: int=Query(1, ge=1), limit: int=Query(10, ge=1, le=100), db: Session=Depends(get_db)):
    try:
        query = db.query(Service)
        if search:
            query = query.filter(or_(Service.name.like(f'%{search}%'), Service.description.like(f'%{search}%')))
        if status_filter:
            is_active = status_filter == 'active'
            query = query.filter(Service.is_active == is_active)
        total = query.count()
        offset = (page - 1) * limit
        services = query.order_by(Service.created_at.desc()).offset(offset).limit(limit).all()
        result = []
        for service in services:
            service_dict = {
                'id': service.id, 
                'name': service.name, 
                'description': service.description, 
                'price': float(service.price) if service.price else 0.0, 
                'category': service.category,
                'slug': service.slug,
                'image': service.image,
                'content': service.content,
                'sections': service.sections,
                'meta_title': service.meta_title,
                'meta_description': service.meta_description,
                'meta_keywords': service.meta_keywords,
                'is_active': service.is_active,
                'status': 'active' if service.is_active else 'inactive',
                'unit': service.category,  # For backward compatibility
                'created_at': service.created_at.isoformat() if service.created_at else None
            }
            result.append(service_dict)
        return {'status': 'success', 'data': {'services': result, 'pagination': {'total': total, 'page': page, 'limit': limit, 'totalPages': (total + limit - 1) // limit}}}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get('/{id}')
async def get_service_by_id(id: int, db: Session=Depends(get_db)):
    try:
        service = db.query(Service).filter(Service.id == id).first()
        if not service:
            raise HTTPException(status_code=404, detail='Service not found')
        service_dict = {
            'id': service.id, 
            'name': service.name, 
            'description': service.description, 
            'price': float(service.price) if service.price else 0.0, 
            'category': service.category,
            'slug': service.slug,
            'image': service.image,
            'content': service.content,
            'sections': service.sections,
            'meta_title': service.meta_title,
            'meta_description': service.meta_description,
            'meta_keywords': service.meta_keywords,
            'is_active': service.is_active,
            'status': 'active' if service.is_active else 'inactive',
            'unit': service.category,  # For backward compatibility
            'created_at': service.created_at.isoformat() if service.created_at else None
        }
        return {'status': 'success', 'data': {'service': service_dict}}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.get('/slug/{slug}')
async def get_service_by_slug(slug: str, db: Session=Depends(get_db)):
    try:
        service = db.query(Service).filter(Service.slug == slug, Service.is_active == True).first()
        if not service:
            raise HTTPException(status_code=404, detail='Service not found')
        service_dict = {
            'id': service.id, 
            'name': service.name, 
            'description': service.description, 
            'price': float(service.price) if service.price else 0.0, 
            'category': service.category,
            'slug': service.slug,
            'image': service.image,
            'content': service.content,
            'sections': service.sections,
            'meta_title': service.meta_title,
            'meta_description': service.meta_description,
            'meta_keywords': service.meta_keywords,
            'is_active': service.is_active,
            'status': 'active' if service.is_active else 'inactive',
            'unit': service.category,  # For backward compatibility
            'created_at': service.created_at.isoformat() if service.created_at else None
        }
        return {'status': 'success', 'data': {'service': service_dict}}
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.post('/', dependencies=[Depends(authorize_roles('admin'))])
async def create_service(service_data: dict, current_user: User=Depends(authorize_roles('admin')), db: Session=Depends(get_db)):
    try:
        name = service_data.get('name')
        existing = db.query(Service).filter(Service.name == name).first()
        if existing:
            raise HTTPException(status_code=400, detail='Service name already exists')
        
        # Generate slug from name if not provided
        slug = service_data.get('slug')
        if not slug and name:
            import re
            slug = re.sub(r'[^a-z0-9-]', '', name.lower().replace(' ', '-'))
            # Ensure slug is unique
            counter = 1
            original_slug = slug
            while db.query(Service).filter(Service.slug == slug).first():
                slug = f"{original_slug}-{counter}"
                counter += 1
        
        # Handle sections as JSON string
        sections = service_data.get('sections')
        if sections and isinstance(sections, (list, dict)):
            import json
            sections = json.dumps(sections)
        
        service = Service(
            name=name, 
            description=service_data.get('description'), 
            price=float(service_data.get('price', 0)), 
            category=service_data.get('category'),
            slug=slug,
            image=service_data.get('image'),
            content=service_data.get('content'),
            sections=sections,
            meta_title=service_data.get('meta_title'),
            meta_description=service_data.get('meta_description'),
            meta_keywords=service_data.get('meta_keywords'),
            is_active=service_data.get('status') == 'active' if service_data.get('status') else True
        )
        db.add(service)
        db.commit()
        db.refresh(service)
        return {'status': 'success', 'message': 'Service created successfully', 'data': {'service': service}}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

@router.put('/{id}', dependencies=[Depends(authorize_roles('admin'))])
async def update_service(id: int, service_data: dict, current_user: User=Depends(authorize_roles('admin')), db: Session=Depends(get_db)):
    try:
        service = db.query(Service).filter(Service.id == id).first()
        if not service:
            raise HTTPException(status_code=404, detail='Service not found')
        name = service_data.get('name')
        if name and name != service.name:
            existing = db.query(Service).filter(Service.name == name, Service.id != id).first()
            if existing:
                raise HTTPException(status_code=400, detail='Service name already exists')
        
        # Check slug uniqueness if provided
        slug = service_data.get('slug')
        if slug and slug != service.slug:
            existing = db.query(Service).filter(Service.slug == slug, Service.id != id).first()
            if existing:
                raise HTTPException(status_code=400, detail='Service slug already exists')
        
        if 'name' in service_data:
            service.name = service_data['name']
        if 'description' in service_data:
            service.description = service_data['description']
        if 'price' in service_data:
            service.price = float(service_data['price'])
        if 'category' in service_data:
            service.category = service_data['category']
        if 'slug' in service_data:
            service.slug = service_data['slug']
        if 'image' in service_data:
            service.image = service_data['image']
        if 'content' in service_data:
            service.content = service_data['content']
        if 'sections' in service_data:
            sections = service_data['sections']
            if sections and isinstance(sections, (list, dict)):
                import json
                service.sections = json.dumps(sections)
            else:
                service.sections = sections
        if 'meta_title' in service_data:
            service.meta_title = service_data['meta_title']
        if 'meta_description' in service_data:
            service.meta_description = service_data['meta_description']
        if 'meta_keywords' in service_data:
            service.meta_keywords = service_data['meta_keywords']
        if 'status' in service_data:
            service.is_active = service_data['status'] == 'active'
        db.commit()
        db.refresh(service)
        return {'status': 'success', 'message': 'Service updated successfully', 'data': {'service': service}}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

@router.delete('/{id}', dependencies=[Depends(authorize_roles('admin'))])
async def delete_service(id: int, current_user: User=Depends(authorize_roles('admin')), db: Session=Depends(get_db)):
    try:
        service = db.query(Service).filter(Service.id == id).first()
        if not service:
            raise HTTPException(status_code=404, detail='Service not found')
        active_usage = db.query(ServiceUsage).join(Booking).filter(ServiceUsage.service_id == id, Booking.status.in_([BookingStatus.pending, BookingStatus.confirmed, BookingStatus.checked_in])).count()
        if active_usage > 0:
            raise HTTPException(status_code=400, detail='Cannot delete service that is used in active bookings')
        db.delete(service)
        db.commit()
        return {'status': 'success', 'message': 'Service deleted successfully'}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))

@router.post('/use')
async def use_service(usage_data: dict, current_user: User=Depends(get_current_user), db: Session=Depends(get_db)):
    try:
        booking_id = usage_data.get('booking_id')
        service_id = usage_data.get('service_id')
        quantity = usage_data.get('quantity', 1)
        booking = db.query(Booking).filter(Booking.id == booking_id).first()
        if not booking:
            raise HTTPException(status_code=404, detail='Booking not found')
        service = db.query(Service).filter(Service.id == service_id).first()
        if not service or not service.is_active:
            raise HTTPException(status_code=404, detail='Service not found or inactive')
        total_price = float(service.price) * quantity
        service_usage = ServiceUsage(booking_id=booking_id, service_id=service_id, quantity=quantity, unit_price=service.price, total_price=total_price)
        db.add(service_usage)
        db.commit()
        db.refresh(service_usage)
        return {'status': 'success', 'message': 'Service added to booking successfully', 'data': {'bookingService': service_usage}}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))