from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import ( 
    CompanyCalendar, ContentCalendar,
    DailyReport, OfficeExpense, Activity
)
from .serializers import  ( 
    CompanyContentCalendarSerializer, ContentCalendarSerializer,
    DailyReportSerializer, OfficeExpenseSerializer, ActivitySerializer
)


class CompanyContentCalendarListView(APIView):
    def get(self, request):
        companies = CompanyCalendar.objects.prefetch_related('content_calendars').all()
        serializer = CompanyContentCalendarSerializer(companies, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = CompanyContentCalendarSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CompanyContentCalendarDetailView(APIView):
    def get_object(self, pk):
        try:
            return CompanyCalendar.objects.prefetch_related('content_calendars').get(pk=pk)
        except CompanyCalendar.DoesNotExist:
            return None
    
    def get(self, request, pk):
        company = self.get_object(pk)
        if company is None:
            return Response({'error': 'Company calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CompanyContentCalendarSerializer(company)
        return Response(serializer.data)
    
    def put(self, request, pk):
        company = self.get_object(pk)
        if company is None:
            return Response({'error': 'Company calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CompanyContentCalendarSerializer(company, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def patch(self, request, pk):
        company = self.get_object(pk)
        if company is None:
            return Response({'error': 'Company calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = CompanyContentCalendarSerializer(company, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        company = self.get_object(pk)
        if company is None:
            return Response({'error': 'Company calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        company.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    

class ContentCalendarCreateView(APIView):
    def post(self, request):
        serializer = ContentCalendarSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def get(self, request):
        content_calendars = ContentCalendar.objects.all()
        serializer = ContentCalendarSerializer(content_calendars, many=True)
        return Response(serializer.data)


class ContentCalendarDetailView(APIView):
    def get_object(self, pk):
        try:
            return ContentCalendar.objects.get(pk=pk)
        except ContentCalendar.DoesNotExist:
            return None
    
    def get(self, request, pk):
        content_calendar = self.get_object(pk)
        if content_calendar is None:
            return Response({'error': 'Content calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ContentCalendarSerializer(content_calendar)
        return Response(serializer.data)
    
    def put(self, request, pk):
        content_calendar = self.get_object(pk)
        if content_calendar is None:
            return Response({'error': 'Content calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ContentCalendarSerializer(content_calendar, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def patch(self, request, pk):
        content_calendar = self.get_object(pk)
        if content_calendar is None:
            return Response({'error': 'Content calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ContentCalendarSerializer(content_calendar, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        content_calendar = self.get_object(pk)
        if content_calendar is None:
            return Response({'error': 'Content calendar not found'}, status=status.HTTP_404_NOT_FOUND)
        content_calendar.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    

class DailyReportListView(APIView):
    def get(self, request):
        daily_reports = DailyReport.objects.all()
        
        # Filter by single date if provided (backward compatibility)
        date_filter = request.query_params.get('date')
        if date_filter:
            daily_reports = daily_reports.filter(date=date_filter)
        
        # Filter by date range if provided
        start_date = request.query_params.get('start_date')
        end_date = request.query_params.get('end_date')
        
        if start_date:
            daily_reports = daily_reports.filter(date__gte=start_date)
        
        if end_date:
            daily_reports = daily_reports.filter(date__lte=end_date)

        # Filter by profile if provided (expects UUID string)
        profile_id = request.query_params.get('profile_id')
        if profile_id:
            daily_reports = daily_reports.filter(profiles__id=profile_id)
        
        # Add pagination support
        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get('page_size', 1000))
        
        start_index = (page - 1) * page_size
        end_index = start_index + page_size
        
        total_count = daily_reports.count()
        daily_reports = daily_reports[start_index:end_index]
        
        serializer = DailyReportSerializer(daily_reports, many=True)
        
        # Return paginated response
        return Response({
            'results': serializer.data,
            'count': total_count,
            'next': end_index < total_count,
            'previous': page > 1
        })

    def post(self, request):
        serializer = DailyReportSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class DailyReportDetailView(APIView):
    def get_object(self, pk):
        try:
            return DailyReport.objects.get(pk=pk)
        except DailyReport.DoesNotExist:
            return None
    
    def get(self, request, pk):
        daily_report = self.get_object(pk)
        if daily_report is None:
            return Response({'error': 'Daily report not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = DailyReportSerializer(daily_report)
        return Response(serializer.data)
    
    def put(self, request, pk):
        daily_report = self.get_object(pk)
        if daily_report is None:
            return Response({'error': 'Daily report not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = DailyReportSerializer(daily_report, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def patch(self, request, pk):
        daily_report = self.get_object(pk)
        if daily_report is None:
            return Response({'error': 'Daily report not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = DailyReportSerializer(daily_report, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        daily_report = self.get_object(pk)
        if daily_report is None:
            return Response({'error': 'Daily report not found'}, status=status.HTTP_404_NOT_FOUND)
        daily_report.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

# Fetch daily report by profile
class DailyReportByProfileView(APIView):
    def get(self, request, uuid):
        daily_reports = DailyReport.objects.filter(profiles__id=uuid)
        serializer = DailyReportSerializer(daily_reports, many=True)
        return Response(serializer.data)
    

class OfficeExpenseListView(APIView):
    def get(self, request):
        office_expenses = OfficeExpense.objects.all()
        serializer = OfficeExpenseSerializer(office_expenses, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = OfficeExpenseSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class OfficeExpenseDetailView(APIView):
    def get_object(self, pk):
        try:
            return OfficeExpense.objects.get(pk=pk)
        except OfficeExpense.DoesNotExist:
            return None
    
    def get(self, request, pk):
        office_expense = self.get_object(pk)
        if office_expense is None:
            return Response({'error': 'Office expense not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = OfficeExpenseSerializer(office_expense)
        return Response(serializer.data)
    
    def put(self, request, pk):
        office_expense = self.get_object(pk)
        if office_expense is None:
            return Response({'error': 'Office expense not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = OfficeExpenseSerializer(office_expense, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def patch(self, request, pk):
        office_expense = self.get_object(pk)
        if office_expense is None:
            return Response({'error': 'Office expense not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = OfficeExpenseSerializer(office_expense, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        office_expense = self.get_object(pk)
        if office_expense is None:
            return Response({'error': 'Office expense not found'}, status=status.HTTP_404_NOT_FOUND)
        office_expense.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class ActivityListView(APIView):
    def get(self, request):
        activities = Activity.objects.all()
        serializer = ActivitySerializer(activities, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = ActivitySerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ActivityDetailView(APIView):
    def get_object(self, pk):
        try:
            return Activity.objects.get(pk=pk)
        except Activity.DoesNotExist:
            return None
    
    def get(self, request, pk):
        activity = self.get_object(pk)
        if activity is None:
            return Response({'error': 'Activity not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ActivitySerializer(activity)
        return Response(serializer.data)
    
    def put(self, request, pk):
        activity = self.get_object(pk)
        if activity is None:
            return Response({'error': 'Activity not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ActivitySerializer(activity, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def patch(self, request, pk):
        activity = self.get_object(pk)
        if activity is None:
            return Response({'error': 'Activity not found'}, status=status.HTTP_404_NOT_FOUND)
        serializer = ActivitySerializer(activity, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        activity = self.get_object(pk)
        if activity is None:
            return Response({'error': 'Activity not found'}, status=status.HTTP_404_NOT_FOUND)
        activity.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

