"""
Company API views for ThrillWiki API v1.

This module implements CRUD endpoints for company management:
- List / Create: GET /companies/  POST /companies/
- Retrieve / Update / Delete: GET /companies/{id}/  PATCH/PUT/DELETE
"""

from django.db.models import Q
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import permissions, status
from rest_framework.exceptions import NotFound
from rest_framework.pagination import PageNumberPagination
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.api.v1.serializers.companies import (
    CompanyCreateInputSerializer,
    CompanyDetailOutputSerializer,
    CompanyUpdateInputSerializer,
)

try:
    from apps.rides.models.company import Company

    MODELS_AVAILABLE = True
except ImportError:
    Company = None
    MODELS_AVAILABLE = False


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = "page_size"
    max_page_size = 100


class CompanyListCreateAPIView(APIView):
    """List and create companies."""

    permission_classes = [permissions.AllowAny]

    @extend_schema(
        summary="List all companies",
        description="List companies with optional search and role filtering.",
        parameters=[
            OpenApiParameter(name="search", location=OpenApiParameter.QUERY, type=OpenApiTypes.STR),
            OpenApiParameter(name="role", location=OpenApiParameter.QUERY, type=OpenApiTypes.STR),
            OpenApiParameter(name="page", location=OpenApiParameter.QUERY, type=OpenApiTypes.INT),
            OpenApiParameter(name="page_size", location=OpenApiParameter.QUERY, type=OpenApiTypes.INT),
        ],
        responses={200: CompanyDetailOutputSerializer(many=True)},
        tags=["Companies"],
    )
    def get(self, request: Request) -> Response:
        if not MODELS_AVAILABLE:
            return Response(
                {"detail": "Company models not available"},
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )

        qs = Company.objects.all().order_by("name")

        # Search filter
        search = request.query_params.get("search", "")
        if search:
            qs = qs.filter(Q(name__icontains=search) | Q(description__icontains=search))

        # Role filter
        role = request.query_params.get("role", "")
        if role:
            qs = qs.filter(roles__contains=[role])

        paginator = StandardResultsSetPagination()
        page = paginator.paginate_queryset(qs, request)
        serializer = CompanyDetailOutputSerializer(page, many=True)
        return paginator.get_paginated_response(serializer.data)

    @extend_schema(
        summary="Create a new company",
        description="Create a new company with the given details.",
        request=CompanyCreateInputSerializer,
        responses={201: CompanyDetailOutputSerializer()},
        tags=["Companies"],
    )
    def post(self, request: Request) -> Response:
        if not MODELS_AVAILABLE:
            return Response(
                {"detail": "Company models not available"},
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )

        serializer_in = CompanyCreateInputSerializer(data=request.data)
        serializer_in.is_valid(raise_exception=True)
        validated = serializer_in.validated_data

        company = Company.objects.create(
            name=validated["name"],
            roles=validated["roles"],
            description=validated.get("description", ""),
            website=validated.get("website", ""),
            founded_date=validated.get("founded_date"),
        )

        serializer = CompanyDetailOutputSerializer(company)
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class CompanyDetailAPIView(APIView):
    """Retrieve, update, and delete a company."""

    permission_classes = [permissions.AllowAny]

    def _get_company_or_404(self, pk: int) -> "Company":
        if not MODELS_AVAILABLE:
            raise NotFound("Company models not available")
        try:
            return Company.objects.get(pk=pk)
        except Company.DoesNotExist:
            raise NotFound("Company not found") from None

    @extend_schema(
        summary="Retrieve a company",
        description="Get detailed information about a specific company.",
        responses={200: CompanyDetailOutputSerializer()},
        tags=["Companies"],
    )
    def get(self, request: Request, pk: int) -> Response:
        company = self._get_company_or_404(pk)
        serializer = CompanyDetailOutputSerializer(company)
        return Response(serializer.data)

    @extend_schema(
        summary="Update a company",
        description="Update a company (partial update supported).",
        request=CompanyUpdateInputSerializer,
        responses={200: CompanyDetailOutputSerializer()},
        tags=["Companies"],
    )
    def patch(self, request: Request, pk: int) -> Response:
        company = self._get_company_or_404(pk)
        serializer_in = CompanyUpdateInputSerializer(data=request.data, partial=True)
        serializer_in.is_valid(raise_exception=True)

        for field, value in serializer_in.validated_data.items():
            setattr(company, field, value)
        company.save()

        serializer = CompanyDetailOutputSerializer(company)
        return Response(serializer.data)

    def put(self, request: Request, pk: int) -> Response:
        return self.patch(request, pk)

    @extend_schema(
        summary="Delete a company",
        description="Delete a company.",
        responses={204: None},
        tags=["Companies"],
    )
    def delete(self, request: Request, pk: int) -> Response:
        company = self._get_company_or_404(pk)
        company.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
