from rest_framework import status
from rest_framework.views import APIView
from rest_framework import generics, permissions
from .models import VendorCategory, VendorCategoryServices, Vendor
from listing.models import Listing
from .serializers import VendorCategorySerializer, VendorCategoryServicesSerializer,VendorSerializer, VendorListingCountSerializer
from .serializers import SelectedProviderSerializer
from utils.helper import success_response, failed_response,generate_random_text
from rest_framework.response import Response
from .models import Vendor
from application.models import SelectedProvider
from .models import  Vendor
from application.models import Application
from utils.validation import validate_required_params, validate
from utils.logger import record
from utils.data import logger_settings

log_msg=logger_settings["msg"]

## testing CI CD
## change number 2


class VendorCategoryCRUDView(APIView):
    def get(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryCRUDView GET request started')
        try:
            if pk:
                vendor_category = VendorCategory.objects.get(pk=pk)
                serializer = VendorCategorySerializer(vendor_category)
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category retrieved successfully')
                return success_response(data=serializer.data, msg='Vendor Category retrieved successfully')
            else:
                vendor_categories = VendorCategory.objects.all()
                serializer = VendorCategorySerializer(vendor_categories, many=True)
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Categories retrieved successfully')
                return success_response(data=serializer.data, msg='Vendor Categories retrieved successfully')
        except VendorCategory.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category not found')
            return failed_response(msg='Vendor Category not found', code=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during Vendor Category retrieval')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def post(self, request, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryCRUDView POST request started')
        try:
            serializer = VendorCategorySerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category created successfully')
                return success_response(data=serializer.data, msg='Vendor Category created successfully')
            record('warn', f'{process_code}: {serializer.errors} - Validation errors during Vendor Category creation')
            return failed_response(msg=serializer.errors, code=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during Vendor Category creation')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def put(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryCRUDView PUT request started')
        try:
            if not pk:
                record('warn', f'{process_code}: Vendor Category ID is required for update')
                return failed_response(msg='Vendor Category ID is required', code=status.HTTP_400_BAD_REQUEST)
            vendor_category = VendorCategory.objects.get(pk=pk)
            serializer = VendorCategorySerializer(vendor_category, data=request.data)
            if serializer.is_valid():
                serializer.save()
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category updated successfully')
                return success_response(data=serializer.data, msg='Vendor Category updated successfully')
            record('warn', f'{process_code}: {serializer.errors} - Validation errors during Vendor Category update')
            return failed_response(msg=serializer.errors, code=status.HTTP_400_BAD_REQUEST)
        except VendorCategory.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category not found for update')
            return failed_response(msg='Vendor Category not found', code=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during Vendor Category update')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def delete(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryCRUDView DELETE request started')
        try:
            vendor_category = VendorCategory.objects.get(pk=pk)
            vendor_category.delete()
            record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category deleted successfully')
            return success_response(msg='Vendor Category deleted successfully')
        except VendorCategory.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category not found for deletion')
            return failed_response(msg='Vendor Category not found', code=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during Vendor Category deletion')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)


class VendorCategoryServicesCRUDView(APIView):
    def get(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryServicesCRUDView GET request started')
        try:
            if pk:
                vendor_service = VendorCategoryServices.objects.get(pk=pk)
                serializer = VendorCategoryServicesSerializer(vendor_service)
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category Service retrieved successfully')
                return success_response(data=serializer.data, msg='Vendor Category Service retrieved successfully')
            else:
                vendor_services = VendorCategoryServices.objects.all()
                serializer = VendorCategoryServicesSerializer(vendor_services, many=True)
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category Services retrieved successfully')
                return success_response(data=serializer.data, msg='Vendor Category Services retrieved successfully')
        except VendorCategoryServices.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category Service not found')
            return failed_response(msg='Vendor Category Service not found', code=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during retrieval')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def post(self, request, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryServicesCRUDView POST request started')
        try:
            validate_required_params(request, ['title', 'vendor_category'])
            validate('title', request.data.get('title',''), ['length:max:50'])
            serializer = VendorCategoryServicesSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category Service created successfully')
                return success_response(data=serializer.data, msg='Vendor Category Service created successfully')
            record('warn', f'{process_code}: {serializer.errors} - Validation errors during Vendor Category Service creation')
            return failed_response(msg=serializer.errors, code=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during creation')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def put(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryServicesCRUDView PUT request started')
        try:
            if not pk:
                record('warn', f'{process_code}: Vendor Category Service ID is required for update')
                return failed_response(msg='Vendor Category Service ID is required', code=status.HTTP_400_BAD_REQUEST)
            vendor_service = VendorCategoryServices.objects.get(pk=pk)
            serializer = VendorCategoryServicesSerializer(vendor_service, data=request.data)
            if serializer.is_valid():
                serializer.save()
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category Service updated successfully')
                return success_response(data=serializer.data, msg='Vendor Category Service updated successfully')
            record('warn', f'{process_code}: {serializer.errors} - Validation errors during Vendor Category Service update')
            return failed_response(msg=serializer.errors, code=status.HTTP_400_BAD_REQUEST)
        except VendorCategoryServices.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category Service not found for update')
            return failed_response(msg='Vendor Category Service not found', code=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during update')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def delete(self, request, pk=None, format=None):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - VendorCategoryServicesCRUDView DELETE request started')
        try:
            vendor_service = VendorCategoryServices.objects.get(pk=pk)
            vendor_service.delete()
            record('info', f'{process_code}: {log_msg["completed"]} - Vendor Category Service deleted successfully')
            return success_response(msg='Vendor Category Service deleted successfully')
        except VendorCategoryServices.DoesNotExist:
            record('warn', f'{process_code}: Vendor Category Service not found for deletion')
            return failed_response(msg='Vendor Category Service not found', code=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during deletion')
            return failed_response(msg='An unexpected error occurred', code=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CreateVendorView(APIView):
    def post(self, request, *args, **kwargs):
        process_code = generate_random_text(6)
        record('info', f'{process_code}: {log_msg["started"]} - CreateVendorView POST request started')
        user = request.user
        try:
            if Vendor.objects.filter(user=user).exists():
                record('warn', f'{process_code}: Vendor for this user already exists.')
                return failed_response(msg = "Vendor for this user already exists.",
                    status=status.HTTP_400_BAD_REQUEST
                )
            serializer = VendorSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save(user=user)
                record('info', f'{process_code}: {log_msg["completed"]} - Vendor created successfully')
                return success_response(serializer.data, status=status.HTTP_201_CREATED)
            record('warn', f'{process_code}: Validation errors - {serializer.errors}')
            return failed_response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            record('error', f'{process_code}: {str(e)} - Unexpected error occurred during vendor creation')
            return failed_response(
                {"error": "An unexpected error occurred"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class UpdateVendorView(generics.UpdateAPIView):
    queryset = Vendor.objects.all()
    serializer_class = VendorSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_object(self):
        return Vendor.objects.get(user=self.request.user)


class VendorListingCountView(APIView):
    def get(self, request, vendor_id):
        try:
            vendor = Vendor.objects.get(id = vendor_id)
            total_applied_listings = Listing.objects.filter(user_listing=vendor).count()
            data = {
                'vendor_id':vendor_id,
                'total_applied_listings': total_applied_listings
            }
            serializer = VendorListingCountSerializer(data)
            return success_response(serializer.data, status=status.HTTP_200_OK)
        except Vendor.DoesNotExist:
            return failed_response({
                'error': 'Vendor not found',
                'code': status.HTTP_404_NOT_FOUND
            })

class SelectedVendorsByUser(APIView):
    def get(self, request, user_id, format=None):
        try:
            applications = Application.objects.filter(user_id=user_id)
            if not applications.exists():
                return failed_response({'status':'failed', 'msg':'No applications found for the user.'}, status=status.HTTP_404_NOT_FOUND)
            selected_providers = SelectedProvider.objects.filter(application_id__in = applications)
            if not selected_providers.exists():
                return failed_response({'status':'failed', 'msg':'No vendors selected by user.'}, status=status.HTTP_404_NOT_FOUND)
            serializer = SelectedProviderSerializer(selected_providers, many=True)
            return success_response({
                'status':'success',
                'msg': 'Vendors retrieved successfully',
                'data': serializer.data
            })
        except Exception as e:
            return success_response({'status': 'failed', 'msg':f"An unexpected error occurred: {str(e)}" },status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class SearchVendorFromCategoryView(APIView):
    def get(self, request, *args, **kwargs):
        category_id = request.GET.get('category_id')
        if not category_id:
            return failed_response({'error': 'category_id parameter is required'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            category = VendorCategory.objects.get(id = category_id)
        except Vendor.DoesNotExist:
            return failed_response({'error': 'Category not found'}, status=status.HTTP_404_NOT_FOUND)
        vendors = Vendor.objects.filter(vendor_category = category)
        vendor_list = [
            {
                'id': vendor.id,
                'contact_detail': vendor.contact_detail,
                'company_registration_document': vendor.company_registration_document,
                'pan_number': vendor.pan_number,
                'vat_number': vendor.vat_number,
                'ceo_detail': vendor.ceo_detail,
            }
            for vendor in vendors
        ]
        return success_response({'vendors': vendor_list})
