"""
Public Quote API router for ClaudeTools.

This module defines all public REST API endpoints for the MSP Quote Wizard,
allowing prospects to create, view, and submit quotes without authentication.
"""

from typing import Optional
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Query, Request, status
from sqlalchemy.orm import Session

from api.database import get_db
from api.schemas.quote import (
    QuoteCreate,
    QuoteCreatedResponse,
    QuoteItemCreate,
    QuoteResponse,
    QuoteItemResponse,
    QuoteSubmit,
    QuoteUpdate,
)
from api.services import quote_service

# Create router (no authentication required for public endpoints)
router = APIRouter()


def get_client_ip(request: Request) -> Optional[str]:
    """Extract client IP from request, handling proxies."""
    forwarded = request.headers.get("X-Forwarded-For")
    if forwarded:
        return forwarded.split(",")[0].strip()
    return request.client.host if request.client else None


def get_user_agent(request: Request) -> Optional[str]:
    """Extract user agent from request."""
    return request.headers.get("User-Agent")


@router.post(
    "",
    response_model=QuoteCreatedResponse,
    summary="Create new quote draft",
    description="Create a new quote draft. Returns an access token for future access.",
    status_code=status.HTTP_201_CREATED,
    responses={
        201: {
            "description": "Quote created successfully",
            "model": QuoteCreatedResponse,
        },
        500: {
            "description": "Server error",
            "content": {
                "application/json": {
                    "example": {"detail": "Failed to create quote"}
                }
            },
        },
    },
)
def create_quote(
    quote_data: QuoteCreate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    Create a new quote draft.

    This endpoint does not require authentication. A unique access token is
    generated for the quote which can be used to access it later.

    **Example Request:**
    ```json
    POST /api/quotes
    Content-Type: application/json

    {
        "employee_count": 25
    }
    ```

    **Example Response:**
    ```json
    {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "access_token": "xYz123abc456def789ghi012jkl345mno678pqr901stu",
        "status": "draft",
        "message": "Quote created successfully. Use the access_token to access your quote."
    }
    ```
    """
    ip_address = get_client_ip(request)
    user_agent = get_user_agent(request)

    quote = quote_service.create_quote(
        db=db,
        quote_data=quote_data,
        ip_address=ip_address,
        user_agent=user_agent
    )

    return QuoteCreatedResponse(
        id=quote.id,
        access_token=quote.access_token,
        status=quote.status,
        message="Quote created successfully. Use the access_token to access your quote."
    )


@router.get(
    "/{access_token}",
    response_model=QuoteResponse,
    summary="Get quote by access token",
    description="Retrieve a quote by its access token",
    status_code=status.HTTP_200_OK,
    responses={
        200: {
            "description": "Quote found and returned",
            "model": QuoteResponse,
        },
        404: {
            "description": "Quote not found",
            "content": {
                "application/json": {
                    "example": {"detail": "Quote not found"}
                }
            },
        },
    },
)
def get_quote(
    access_token: str,
    db: Session = Depends(get_db),
):
    """
    Get a quote by its access token.

    Returns the quote with all its items. This is the public endpoint
    for viewing a quote.

    **Example Request:**
    ```
    GET /api/quotes/xYz123abc456def789ghi012jkl345mno678pqr901stu
    ```

    **Example Response:**
    ```json
    {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "access_token": "xYz123abc456def789ghi012jkl345mno678pqr901stu",
        "status": "draft",
        "company_name": null,
        "contact_name": null,
        "contact_email": null,
        "employee_count": 25,
        "monthly_total": "450.00",
        "setup_total": "500.00",
        "items": [
            {
                "id": "456e7890-e89b-12d3-a456-426614174001",
                "service_name": "Managed Endpoint Protection",
                "category": "security",
                "unit_price": "15.00",
                "quantity": 25,
                "billing_frequency": "monthly",
                "line_total": "375.00",
                "monthly_amount": "375.00"
            }
        ],
        "created_at": "2024-01-15T10:30:00Z",
        "updated_at": "2024-01-15T10:30:00Z"
    }
    ```
    """
    quote = quote_service.get_quote_by_token(db, access_token)

    # Build response with calculated fields for items
    items_response = []
    for item in quote.items:
        item_dict = QuoteItemResponse(
            id=item.id,
            quote_id=item.quote_id,
            category=item.category,
            product_code=item.product_code,
            product_name=item.product_name,
            description=item.description,
            quantity=item.quantity,
            unit_price=item.unit_price,
            setup_price=item.setup_price,
            billing_frequency=item.billing_frequency,
            tier=item.tier,
            is_recommended=item.is_recommended,
            line_total=item.line_total,
            monthly_amount=item.monthly_amount,
            created_at=item.created_at,
        )
        items_response.append(item_dict)

    return QuoteResponse(
        id=quote.id,
        access_token=quote.access_token,
        status=quote.status,
        company_name=quote.company_name,
        contact_name=quote.contact_name,
        contact_email=quote.contact_email,
        contact_phone=quote.contact_phone,
        employee_count=quote.employee_count,
        monthly_total=quote.monthly_total,
        setup_total=quote.setup_total,
        expires_at=quote.expires_at,
        submitted_at=quote.submitted_at,
        created_at=quote.created_at,
        updated_at=quote.updated_at,
        items=items_response
    )


@router.put(
    "/{access_token}",
    response_model=QuoteResponse,
    summary="Update quote",
    description="Update a quote's details and/or items",
    status_code=status.HTTP_200_OK,
    responses={
        200: {
            "description": "Quote updated successfully",
            "model": QuoteResponse,
        },
        400: {
            "description": "Quote cannot be modified (not a draft)",
            "content": {
                "application/json": {
                    "example": {"detail": "Cannot update quote with status 'submitted'. Only drafts can be modified."}
                }
            },
        },
        404: {
            "description": "Quote not found",
        },
    },
)
def update_quote(
    access_token: str,
    quote_data: QuoteUpdate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    Update a quote.

    Updates quote details and/or replaces all items. Only draft quotes
    can be modified.

    **Example Request:**
    ```json
    PUT /api/quotes/xYz123abc456def789ghi012jkl345mno678pqr901stu
    Content-Type: application/json

    {
        "employee_count": 30,
        "items": [
            {
                "service_name": "Managed Endpoint Protection",
                "category": "security",
                "unit_price": "15.00",
                "quantity": 30,
                "billing_frequency": "monthly"
            },
            {
                "service_name": "Cloud Backup",
                "category": "backup",
                "unit_price": "5.00",
                "quantity": 30,
                "billing_frequency": "monthly",
                "setup_fee": "250.00"
            }
        ]
    }
    ```
    """
    ip_address = get_client_ip(request)

    quote = quote_service.update_quote(
        db=db,
        access_token=access_token,
        quote_data=quote_data,
        ip_address=ip_address
    )

    return get_quote(access_token, db)


@router.post(
    "/{access_token}/items",
    response_model=QuoteResponse,
    summary="Add item to quote",
    description="Add a single item to the quote",
    status_code=status.HTTP_201_CREATED,
    responses={
        201: {
            "description": "Item added successfully",
            "model": QuoteResponse,
        },
        400: {
            "description": "Quote cannot be modified",
        },
        404: {
            "description": "Quote not found",
        },
    },
)
def add_item(
    access_token: str,
    item_data: QuoteItemCreate,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    Add a single item to a quote.

    **Example Request:**
    ```json
    POST /api/quotes/xYz123abc456def789ghi012jkl345mno678pqr901stu/items
    Content-Type: application/json

    {
        "service_name": "24/7 Help Desk Support",
        "category": "support",
        "unit_price": "50.00",
        "quantity": 1,
        "billing_frequency": "monthly"
    }
    ```
    """
    ip_address = get_client_ip(request)

    quote_service.add_item_to_quote(
        db=db,
        access_token=access_token,
        item_data=item_data,
        ip_address=ip_address
    )

    return get_quote(access_token, db)


@router.delete(
    "/{access_token}/items/{item_id}",
    response_model=QuoteResponse,
    summary="Remove item from quote",
    description="Remove an item from the quote",
    status_code=status.HTTP_200_OK,
    responses={
        200: {
            "description": "Item removed successfully",
            "model": QuoteResponse,
        },
        400: {
            "description": "Quote cannot be modified or item is required",
        },
        404: {
            "description": "Quote or item not found",
        },
    },
)
def remove_item(
    access_token: str,
    item_id: UUID,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    Remove an item from a quote.

    Required items cannot be removed.

    **Example Request:**
    ```
    DELETE /api/quotes/xYz123abc456def789ghi012jkl345mno678pqr901stu/items/456e7890-e89b-12d3-a456-426614174001
    ```
    """
    ip_address = get_client_ip(request)

    quote_service.remove_item_from_quote(
        db=db,
        access_token=access_token,
        item_id=item_id,
        ip_address=ip_address
    )

    return get_quote(access_token, db)


@router.post(
    "/{access_token}/submit",
    response_model=QuoteResponse,
    summary="Submit quote",
    description="Submit the quote with contact information",
    status_code=status.HTTP_200_OK,
    responses={
        200: {
            "description": "Quote submitted successfully",
            "model": QuoteResponse,
        },
        400: {
            "description": "Quote cannot be submitted (not a draft or no items)",
            "content": {
                "application/json": {
                    "examples": {
                        "not_draft": {
                            "value": {"detail": "Cannot submit quote with status 'submitted'. Only drafts can be submitted."}
                        },
                        "no_items": {
                            "value": {"detail": "Cannot submit quote without any items. Please add at least one service."}
                        }
                    }
                }
            },
        },
        404: {
            "description": "Quote not found",
        },
        422: {
            "description": "Validation error - missing required fields",
        },
    },
)
async def submit_quote_endpoint(
    access_token: str,
    submit_data: QuoteSubmit,
    request: Request,
    db: Session = Depends(get_db),
):
    """
    Submit a quote with contact information.

    This finalizes the quote and sends it for review. Contact information
    is required at this stage. An email notification is sent to the admin.

    **Example Request:**
    ```json
    POST /api/quotes/xYz123abc456def789ghi012jkl345mno678pqr901stu/submit
    Content-Type: application/json

    {
        "company_name": "Acme Corporation",
        "contact_name": "John Doe",
        "contact_email": "john.doe@acme.com",
        "contact_phone": "555-123-4567"
    }
    ```

    **Example Response:**
    ```json
    {
        "id": "123e4567-e89b-12d3-a456-426614174000",
        "access_token": "xYz123abc456def789ghi012jkl345mno678pqr901stu",
        "status": "submitted",
        "company_name": "Acme Corporation",
        "contact_name": "John Doe",
        "contact_email": "john.doe@acme.com",
        "submitted_at": "2024-01-15T14:30:00Z",
        ...
    }
    ```
    """
    import logging
    from api.config import get_settings
    from api.services.email_service import send_email, build_quote_notification_html

    logger = logging.getLogger(__name__)
    ip_address = get_client_ip(request)

    quote = quote_service.submit_quote(
        db=db,
        access_token=access_token,
        submit_data=submit_data,
        ip_address=ip_address
    )

    # Send email notification (non-blocking, don't fail the request if email fails)
    try:
        settings = get_settings()
        items_data = [
            {
                "service_name": item.product_name,
                "billing_frequency": item.billing_frequency,
                "unit_price": str(item.unit_price),
                "quantity": item.quantity,
            }
            for item in quote.items
        ]

        html = build_quote_notification_html(
            company_name=submit_data.company_name,
            contact_name=submit_data.contact_name,
            contact_email=submit_data.contact_email,
            contact_phone=submit_data.contact_phone,
            monthly_total=str(quote.monthly_total),
            setup_total=str(quote.setup_total),
            items=items_data,
            notes=submit_data.notes,
        )

        sent = await send_email(
            to_email=settings.ADMIN_NOTIFICATION_EMAIL,
            subject=f"New Quote Submission: {submit_data.company_name} - ${quote.monthly_total}/mo",
            body_html=html,
        )

        # Update notification record status
        if quote.notifications:
            notification = quote.notifications[-1]
            notification.status = "sent" if sent else "failed"
            if not sent:
                notification.error_message = "Graph API send failed"
            db.commit()

    except Exception as e:
        logger.error(f"Failed to send quote notification email: {e}")
        # Don't fail the submission - email is best-effort

    return get_quote(access_token, db)


@router.get(
    "/{access_token}/pdf",
    summary="Get quote PDF (placeholder)",
    description="Generate and return a PDF version of the quote",
    status_code=status.HTTP_501_NOT_IMPLEMENTED,
    responses={
        501: {
            "description": "PDF generation not yet implemented",
            "content": {
                "application/json": {
                    "example": {"detail": "PDF generation is not yet implemented"}
                }
            },
        },
    },
)
def get_quote_pdf(
    access_token: str,
    db: Session = Depends(get_db),
):
    """
    Generate a PDF version of the quote.

    **Note:** This endpoint is a placeholder. PDF generation will be
    implemented in a future update.
    """
    # Verify quote exists
    quote_service.get_quote_by_token(db, access_token)

    raise HTTPException(
        status_code=status.HTTP_501_NOT_IMPLEMENTED,
        detail="PDF generation is not yet implemented"
    )
