from rest_framework import permissions

from accounts.models import TransporterProfile, TransporterDriverLink, UserRole


class IsShipper(permissions.BasePermission):
    """Only allow users with role SHIPPER."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            return request.user.role.role == UserRole.Role.SHIPPER
        except UserRole.DoesNotExist:
            return False


class IsShipperVerified(permissions.BasePermission):
    """Shipper and KYC verified (for actions like creating shipments)."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            if request.user.role.role != UserRole.Role.SHIPPER:
                return False
            return request.user.shipper_profile.kyc_verified
        except (UserRole.DoesNotExist, AttributeError):
            return False


class IsTransporter(permissions.BasePermission):
    """Only allow users with role TRANSPORTER (e.g. for driver POD submit)."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            return request.user.role.role == UserRole.Role.TRANSPORTER
        except UserRole.DoesNotExist:
            return False


class IsTransporterVerified(permissions.BasePermission):
    """Transporter with documents_verified=True (for bidding, trip assignment)."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            if request.user.role.role != UserRole.Role.TRANSPORTER:
                return False
            return request.user.transporter_profile.documents_verified
        except (UserRole.DoesNotExist, AttributeError):
            return False


class IsPlatformAdmin(permissions.BasePermission):
    """Allow Django staff/superuser or role ADMIN."""

    def has_permission(self, request, view):
        user = request.user
        if not user or not user.is_authenticated:
            return False
        if user.is_staff or user.is_superuser:
            return True
        try:
            return user.role.role == UserRole.Role.ADMIN
        except UserRole.DoesNotExist:
            return False


class IsFleetOwnerTransporter(permissions.BasePermission):
    """Transporter role and account_type=FLEET_OWNER."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            if request.user.role.role != UserRole.Role.TRANSPORTER:
                return False
            return request.user.transporter_profile.account_type == TransporterProfile.AccountType.FLEET_OWNER
        except (UserRole.DoesNotExist, AttributeError):
            return False


class IsFleetDriverTransporter(permissions.BasePermission):
    """Transporter role, fleet-driver account type (or legacy DRIVER + link), active fleet link."""

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            if request.user.role.role != UserRole.Role.TRANSPORTER:
                return False
            profile = request.user.transporter_profile
        except (UserRole.DoesNotExist, AttributeError):
            return False

        if not TransporterDriverLink.objects.filter(driver=request.user, is_active=True).exists():
            return False
        return profile.account_type in (
            TransporterProfile.AccountType.TRANSPORTER_DRIVER,
            TransporterProfile.AccountType.DRIVER,
        )


class IsIndividualDriverTransporter(permissions.BasePermission):
    """
    Transporter role and account_type=DRIVER, but not linked as a fleet driver.
    Useful to keep the existing \"individual driver\" flow distinct from fleet drivers.
    """

    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        try:
            if request.user.role.role != UserRole.Role.TRANSPORTER:
                return False
            if request.user.transporter_profile.account_type != TransporterProfile.AccountType.DRIVER:
                return False
        except (UserRole.DoesNotExist, AttributeError):
            return False

        return not TransporterDriverLink.objects.filter(driver=request.user, is_active=True).exists()
