"""
Company endpoints for API v1.

Provides CRUD operations for Company entities with filtering and search.
"""
from typing import List, Optional
from uuid import UUID
from django.shortcuts import get_object_or_404
from django.db.models import Q
from ninja import Router, Query
from ninja.pagination import paginate, PageNumberPagination

from apps.entities.models import Company
from ..schemas import (
    CompanyCreate,
    CompanyUpdate,
    CompanyOut,
    CompanyListOut,
    ErrorResponse
)


router = Router(tags=["Companies"])


class CompanyPagination(PageNumberPagination):
    """Custom pagination for companies."""
    page_size = 50


@router.get(
    "/",
    response={200: List[CompanyOut]},
    summary="List companies",
    description="Get a paginated list of companies with optional filtering"
)
@paginate(CompanyPagination)
def list_companies(
    request,
    search: Optional[str] = Query(None, description="Search by company name"),
    company_type: Optional[str] = Query(None, description="Filter by company type"),
    location_id: Optional[UUID] = Query(None, description="Filter by location"),
    ordering: Optional[str] = Query("-created", description="Sort by field (prefix with - for descending)")
):
    """
    List all companies with optional filters.
    
    **Filters:**
    - search: Search company names (case-insensitive partial match)
    - company_type: Filter by specific company type
    - location_id: Filter by headquarters location
    - ordering: Sort results (default: -created)
    
    **Returns:** Paginated list of companies
    """
    queryset = Company.objects.all()
    
    # Apply search filter
    if search:
        queryset = queryset.filter(
            Q(name__icontains=search) | Q(description__icontains=search)
        )
    
    # Apply company type filter
    if company_type:
        queryset = queryset.filter(company_types__contains=[company_type])
    
    # Apply location filter
    if location_id:
        queryset = queryset.filter(location_id=location_id)
    
    # Apply ordering
    valid_order_fields = ['name', 'created', 'modified', 'founded_date', 'park_count', 'ride_count']
    order_field = ordering.lstrip('-')
    if order_field in valid_order_fields:
        queryset = queryset.order_by(ordering)
    else:
        queryset = queryset.order_by('-created')
    
    return queryset


@router.get(
    "/{company_id}",
    response={200: CompanyOut, 404: ErrorResponse},
    summary="Get company",
    description="Retrieve a single company by ID"
)
def get_company(request, company_id: UUID):
    """
    Get a company by ID.
    
    **Parameters:**
    - company_id: UUID of the company
    
    **Returns:** Company details
    """
    company = get_object_or_404(Company, id=company_id)
    return company


@router.post(
    "/",
    response={201: CompanyOut, 400: ErrorResponse},
    summary="Create company",
    description="Create a new company (requires authentication)"
)
def create_company(request, payload: CompanyCreate):
    """
    Create a new company.
    
    **Authentication:** Required
    
    **Parameters:**
    - payload: Company data
    
    **Returns:** Created company
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    company = Company.objects.create(**payload.dict())
    return 201, company


@router.put(
    "/{company_id}",
    response={200: CompanyOut, 404: ErrorResponse, 400: ErrorResponse},
    summary="Update company",
    description="Update an existing company (requires authentication)"
)
def update_company(request, company_id: UUID, payload: CompanyUpdate):
    """
    Update a company.
    
    **Authentication:** Required
    
    **Parameters:**
    - company_id: UUID of the company
    - payload: Updated company data
    
    **Returns:** Updated company
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    company = get_object_or_404(Company, id=company_id)
    
    # Update only provided fields
    for key, value in payload.dict(exclude_unset=True).items():
        setattr(company, key, value)
    
    company.save()
    return company


@router.patch(
    "/{company_id}",
    response={200: CompanyOut, 404: ErrorResponse, 400: ErrorResponse},
    summary="Partial update company",
    description="Partially update an existing company (requires authentication)"
)
def partial_update_company(request, company_id: UUID, payload: CompanyUpdate):
    """
    Partially update a company.
    
    **Authentication:** Required
    
    **Parameters:**
    - company_id: UUID of the company
    - payload: Fields to update
    
    **Returns:** Updated company
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    company = get_object_or_404(Company, id=company_id)
    
    # Update only provided fields
    for key, value in payload.dict(exclude_unset=True).items():
        setattr(company, key, value)
    
    company.save()
    return company


@router.delete(
    "/{company_id}",
    response={204: None, 404: ErrorResponse},
    summary="Delete company",
    description="Delete a company (requires authentication)"
)
def delete_company(request, company_id: UUID):
    """
    Delete a company.
    
    **Authentication:** Required
    
    **Parameters:**
    - company_id: UUID of the company
    
    **Returns:** No content (204)
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    company = get_object_or_404(Company, id=company_id)
    company.delete()
    return 204, None


@router.get(
    "/{company_id}/parks",
    response={200: List[dict], 404: ErrorResponse},
    summary="Get company parks",
    description="Get all parks operated by a company"
)
def get_company_parks(request, company_id: UUID):
    """
    Get parks operated by a company.
    
    **Parameters:**
    - company_id: UUID of the company
    
    **Returns:** List of parks
    """
    company = get_object_or_404(Company, id=company_id)
    parks = company.operated_parks.all().values('id', 'name', 'slug', 'status', 'park_type')
    return list(parks)


@router.get(
    "/{company_id}/rides",
    response={200: List[dict], 404: ErrorResponse},
    summary="Get company rides",
    description="Get all rides manufactured by a company"
)
def get_company_rides(request, company_id: UUID):
    """
    Get rides manufactured by a company.
    
    **Parameters:**
    - company_id: UUID of the company
    
    **Returns:** List of rides
    """
    company = get_object_or_404(Company, id=company_id)
    rides = company.manufactured_rides.all().values('id', 'name', 'slug', 'status', 'ride_category')
    return list(rides)
