from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db.models import Sum
from .models import Crop, Variety, Plan, RiceTransplantPlan
from .serializers import (
    CropSerializer,
    VarietySerializer,
    PlanSerializer,
    RiceTransplantPlanSerializer,
    RiceTransplantPlanWriteSerializer,
)
from .services import update_plan_with_variety_tracking
from apps.fields.models import Field


class CropViewSet(viewsets.ModelViewSet):
    queryset = Crop.objects.all()
    serializer_class = CropSerializer


class VarietyViewSet(viewsets.ModelViewSet):
    queryset = Variety.objects.select_related('seed_material', 'crop').all()
    serializer_class = VarietySerializer


class PlanViewSet(viewsets.ModelViewSet):
    queryset = Plan.objects.select_related('crop', 'variety', 'field').prefetch_related(
        'variety_changes',
        'variety_changes__old_variety',
        'variety_changes__new_variety',
    )
    serializer_class = PlanSerializer

    def get_queryset(self):
        queryset = self.queryset
        year = self.request.query_params.get('year')
        if year:
            queryset = queryset.filter(year=year)
        return queryset

    @action(detail=False, methods=['get'])
    def summary(self, request):
        year = request.query_params.get('year')
        if not year:
            return Response({'error': 'year parameter is required'}, status=status.HTTP_400_BAD_REQUEST)

        plans = Plan.objects.filter(year=year)
        total_area = plans.aggregate(total=Sum('field__area_tan'))['total'] or 0

        by_crop = {}
        for plan in plans:
            crop_name = plan.crop.name
            if crop_name not in by_crop:
                by_crop[crop_name] = {
                    'crop': crop_name,
                    'count': 0,
                    'area': 0
                }
            by_crop[crop_name]['count'] += 1
            by_crop[crop_name]['area'] += float(plan.field.area_tan)

        total_fields = Field.objects.count()
        assigned_field_ids = plans.values_list('field_id', flat=True).distinct()
        assigned_count = assigned_field_ids.count()
        unassigned_count = total_fields - assigned_count

        return Response({
            'year': int(year),
            'total_fields': total_fields,
            'assigned_fields': assigned_count,
            'unassigned_fields': unassigned_count,
            'total_plans': plans.count(),
            'total_area': float(total_area),
            'by_crop': list(by_crop.values())
        })

    @action(detail=False, methods=['post'])
    def copy_from_previous_year(self, request):
        from_year = request.data.get('from_year')
        to_year = request.data.get('to_year')

        if not from_year or not to_year:
            return Response({'error': 'from_year and to_year are required'}, status=status.HTTP_400_BAD_REQUEST)

        previous_plans = Plan.objects.filter(year=from_year)
        new_plans = []

        for plan in previous_plans:
            new_plans.append(Plan(
                field=plan.field,
                year=to_year,
                crop=plan.crop,
                variety=plan.variety,
                notes=plan.notes
            ))

        Plan.objects.bulk_create(new_plans, ignore_conflicts=True)

        return Response({'message': f'Copied {len(new_plans)} plans from {from_year} to {to_year}'})

    @action(detail=False, methods=['post'])
    def bulk_update(self, request):
        """複数圃場の作付け計画を一括更新"""
        field_ids = request.data.get('field_ids', [])
        year = request.data.get('year')
        crop_id = request.data.get('crop')
        variety_id = request.data.get('variety')

        if not field_ids or not year or not crop_id:
            return Response({'error': 'field_ids, year, crop are required'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            crop = Crop.objects.get(id=crop_id)
        except Crop.DoesNotExist:
            return Response({'error': 'Crop not found'}, status=status.HTTP_400_BAD_REQUEST)

        variety = None
        if variety_id:
            try:
                variety = Variety.objects.get(id=variety_id)
            except Variety.DoesNotExist:
                pass

        updated = 0
        created = 0
        for field_id in field_ids:
            plan = Plan.objects.filter(field_id=field_id, year=year).first()
            if plan is None:
                Plan.objects.create(
                    field_id=field_id,
                    year=year,
                    crop=crop,
                    variety=variety,
                )
                created += 1
                continue

            update_plan_with_variety_tracking(
                plan,
                crop=crop,
                variety=variety,
            )
            updated += 1

        return Response({'created': created, 'updated': updated, 'total': created + updated})

    @action(detail=False, methods=['get'])
    def get_crops_with_varieties(self, request):
        crops = Crop.objects.prefetch_related('varieties__seed_material').all()
        return Response(CropSerializer(crops, many=True).data)


class RiceTransplantPlanViewSet(viewsets.ModelViewSet):
    queryset = RiceTransplantPlan.objects.select_related(
        'variety',
        'variety__crop',
        'variety__seed_material',
    ).prefetch_related(
        'variety__seed_material__stock_transactions',
        'entries',
        'entries__field',
    )

    def get_queryset(self):
        queryset = self.queryset
        year = self.request.query_params.get('year')
        if year:
            queryset = queryset.filter(year=year)
        return queryset

    def get_serializer_class(self):
        if self.action in ['create', 'update', 'partial_update']:
            return RiceTransplantPlanWriteSerializer
        return RiceTransplantPlanSerializer

    @action(detail=False, methods=['get'])
    def candidate_fields(self, request):
        year = request.query_params.get('year')
        variety_id = request.query_params.get('variety_id')
        if not year or not variety_id:
            return Response(
                {'error': 'year と variety_id が必要です'},
                status=status.HTTP_400_BAD_REQUEST,
            )

        field_ids = Plan.objects.filter(
            year=year,
            variety_id=variety_id,
        ).values_list('field_id', flat=True)
        fields = Field.objects.filter(id__in=field_ids).order_by('display_order', 'id')
        data = [
            {
                'id': field.id,
                'name': field.name,
                'area_tan': str(field.area_tan),
                'area_m2': field.area_m2,
                'group_name': field.group_name,
            }
            for field in fields
        ]
        return Response(data)
