"""Period tracking API: add, history, prediction, delete."""
import datetime
from django.utils import timezone
from rest_framework.views import APIView

from core.models import PeriodLog
from .auth_utils import ok, err
from .permissions import IsAppUser
from .serializers import PeriodLogSerializer


class PeriodAddView(APIView):
    permission_classes = [IsAppUser]

    def post(self, request):
        d = request.data
        start = d.get('startDate') or d.get('start_date')
        if not start:
            return err('startDate is required.', 400)
        log = PeriodLog.objects.create(
            user=request.app_user,
            start_date=start,
            end_date=d.get('endDate') or d.get('end_date'),
            symptoms=d.get('symptoms'),
            mood=d.get('mood'),
            flow_intensity=d.get('flowIntensity') or d.get('flow_intensity'),
            notes=d.get('notes'),
            created_at=timezone.now(),
            updated_at=timezone.now(),
        )
        return ok(PeriodLogSerializer(log).data, 'Period logged.', 201)


class PeriodHistoryView(APIView):
    permission_classes = [IsAppUser]

    def get(self, request):
        logs = PeriodLog.objects.filter(user=request.app_user).order_by('-start_date')[:24]
        return ok(PeriodLogSerializer(logs, many=True).data)


class PeriodPredictionView(APIView):
    permission_classes = [IsAppUser]

    def get(self, request):
        user = request.app_user
        last_log = PeriodLog.objects.filter(user=user).order_by('-start_date').first()
        cycle = user.cycle_length_days or 28
        base_date = (
            last_log.start_date
            if last_log
            else (user.last_period_date or datetime.date.today())
        )
        if isinstance(base_date, str):
            base_date = datetime.date.fromisoformat(base_date)

        next_period = base_date + datetime.timedelta(days=cycle)
        fertile_start = next_period - datetime.timedelta(days=18)
        fertile_end = next_period - datetime.timedelta(days=11)
        ovulation = next_period - datetime.timedelta(days=14)

        return ok({
            'nextPeriodDate': str(next_period),
            'fertileWindowStart': str(fertile_start),
            'fertileWindowEnd': str(fertile_end),
            'ovulationDate': str(ovulation),
            'cycleLengthDays': cycle,
            'lastPeriodDate': str(base_date),
        })


class PeriodDeleteView(APIView):
    permission_classes = [IsAppUser]

    def delete(self, request, pk):
        deleted, _ = PeriodLog.objects.filter(id=pk, user=request.app_user).delete()
        if not deleted:
            return err('Period log not found.', 404)
        return ok(message='Period log deleted.')
