from django.http import HttpResponse
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from icalendar import Calendar, Event, vText, vCalAddress
from datetime import datetime, timedelta
from django.db.models import Prefetch
from adventures.models import Location, Visit

class IcsCalendarGeneratorViewSet(viewsets.ViewSet):
    permission_classes = [IsAuthenticated]

    @action(detail=False, methods=['get'])
    def generate(self, request):
        locations = (
            Location.objects.filter(user=request.user)
            .prefetch_related(
                Prefetch(
                    'visits',
                    queryset=Visit.objects.only('id', 'start_date', 'end_date')
                )
            )
            .only('id', 'name', 'description', 'location', 'link')
        )

        user = request.user
        name = f"{user.first_name} {user.last_name}"

        cal = Calendar()
        cal.add('prodid', '-//My Adventure Calendar//example.com//')
        cal.add('version', '2.0')

        for location in locations:
            visits = list(location.visits.all())
            if not visits:
                continue

            for visit in visits:
                start_value = getattr(visit, 'start_date', None)
                if not start_value:
                    continue

                # Normalize start date
                if isinstance(start_value, str):
                    try:
                        start_dt = datetime.fromisoformat(start_value.replace('Z', '+00:00'))
                    except ValueError:
                        continue
                else:
                    start_dt = start_value

                start_date = start_dt.date() if hasattr(start_dt, 'date') else start_dt

                # Normalize end date (inclusive of final day)
                end_value = getattr(visit, 'end_date', None) or start_dt
                if isinstance(end_value, str):
                    try:
                        end_dt = datetime.fromisoformat(end_value.replace('Z', '+00:00'))
                    except ValueError:
                        end_dt = start_dt
                else:
                    end_dt = end_value

                end_date = end_dt.date() if hasattr(end_dt, 'date') else end_dt
                end_date = end_date + timedelta(days=1)

                event = Event()
                event.add('summary', location.name)
                event.add('dtstart', start_date)
                event.add('dtend', end_date)
                event.add('dtstamp', datetime.now())
                event.add('transp', 'TRANSPARENT')
                event.add('class', 'PUBLIC')
                event.add('created', datetime.now())
                event.add('last-modified', datetime.now())
                event.add('description', getattr(location, 'description', '') or '')

                if getattr(location, 'location', None):
                    event.add('location', location.location)

                if getattr(location, 'link', None):
                    event.add('url', location.link)

                organizer = vCalAddress(f'MAILTO:{user.email}')
                organizer.params['cn'] = vText(name)
                event.add('organizer', organizer)

                cal.add_component(event)

        response = HttpResponse(cal.to_ical(), content_type='text/calendar')
        response['Content-Disposition'] = 'attachment; filename=adventures.ics'
        return response