from django.contrib.admin.views.decorators import staff_member_required
from django.contrib import messages
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from django.views.decorators.http import require_POST

from decimal import Decimal, InvalidOperation, ROUND_HALF_UP

from django.db import transaction
from expat_life.utils import update_property_care_plan_payable_item, create_property_care_monthly_plan_payable_item

from django.db.models import Q


from property_manager_app.models import (
    ManagedProperty,
    PropertyCarePlan,
    PropertyCarePlanServiceLine,
    PropertyServiceSelection,
    PropertyMaintenanceVisit,
    PropertyVisitPhoto,
    PropertyInspectionReport,
    PropertyInspectionReportPhoto,
)



from .forms import (
    PropertyCarePlanForm,
    PropertyMaintenanceVisitForm,
    PropertyVisitPhotoForm,
    PropertyInspectionReportForm,
    PropertyInspectionReportPhotoForm,
)


def parse_money_value(value, default=Decimal('0.00')):
    try:
        amount = Decimal(str(value or '0').strip())
    except (InvalidOperation, ValueError, TypeError):
        amount = default

    if amount < 0:
        amount = default

    return amount.quantize(
        Decimal('0.01'),
        rounding=ROUND_HALF_UP
    )

@staff_member_required
def property_care_final_plan_manage(request, pk):
    """
    Staff prepares or updates the final Property Care Plan
    for an already approved managed property.
    """

    managed_property = get_object_or_404(
        ManagedProperty.objects
        .select_related('owner', 'reviewed_by')
        .prefetch_related('service_selections__service_type'),
        pk=pk
    )

    if managed_property.review_status != 'approved':
        messages.warning(
            request,
            "A final care plan can be prepared only after the property has been approved."
        )
        return redirect(
            'myadmin:property_care_property_review_detail',
            pk=managed_property.pk
        )

    care_plan, created = PropertyCarePlan.objects.get_or_create(
        property=managed_property,
        defaults={
            'provisional_estimate_snapshot_usd': managed_property.estimated_monthly_total_usd,
            'created_by': request.user,
            'updated_by': request.user,
        }
    )

    selections = (
        managed_property.service_selections
        .select_related('service_type')
        .all()
    )

    existing_lines = {
        line.service_type_id: line
        for line in care_plan.service_lines.select_related(
            'service_type',
            'source_selection',
        )
    }

    if request.method == 'POST':
        form = PropertyCarePlanForm(
            request.POST,
            instance=care_plan
        )

        if form.is_valid():
            included_selection_ids = set(
                request.POST.getlist('included_service_selection_ids')
            )

            with transaction.atomic():
                plan = form.save(commit=False)

                if plan.created_by is None:
                    plan.created_by = request.user

                plan.updated_by = request.user

                if plan.provisional_estimate_snapshot_usd is None:
                    plan.provisional_estimate_snapshot_usd = managed_property.estimated_monthly_total_usd

                plan.save()

                final_monthly_total = Decimal('0.00')
                current_selection_ids = []

                for index, selection in enumerate(selections, start=1):
                    current_selection_ids.append(selection.id)

                    service = selection.service_type

                    is_included = str(selection.id) in included_selection_ids

                    final_frequency = request.POST.get(
                        f'final_frequency_{selection.id}',
                        selection.frequency
                    )

                    valid_frequency_values = dict(
                        PropertyServiceSelection.FREQUENCY_CHOICES
                    )

                    if final_frequency not in valid_frequency_values:
                        final_frequency = selection.frequency

                    try:
                        final_visits_per_month = int(
                            request.POST.get(
                                f'final_visits_per_month_{selection.id}',
                                selection.requested_visits_per_month
                            )
                        )
                    except (TypeError, ValueError):
                        final_visits_per_month = selection.requested_visits_per_month or 0

                    if final_visits_per_month < 0:
                        final_visits_per_month = 0

                    if final_visits_per_month > 31:
                        final_visits_per_month = 31

                    final_monthly_amount = parse_money_value(
                        request.POST.get(
                            f'final_monthly_amount_{selection.id}',
                            selection.estimated_monthly_amount_usd or '0.00'
                        )
                    )

                    line_note = request.POST.get(
                        f'line_note_{selection.id}',
                        ''
                    ).strip()

                    exclusion_reason = request.POST.get(
                        f'exclusion_reason_{selection.id}',
                        ''
                    ).strip()

                    service_line, _ = PropertyCarePlanServiceLine.objects.get_or_create(
                        plan=plan,
                        service_type=service,
                        defaults={
                            'source_selection': selection,
                            'display_order': index,
                        }
                    )

                    service_line.source_selection = selection
                    service_line.is_included = is_included
                    service_line.final_frequency = final_frequency
                    service_line.final_visits_per_month = final_visits_per_month
                    service_line.display_order = index
                    service_line.line_note = line_note
                    service_line.exclusion_reason = exclusion_reason

                    if is_included:
                        service_line.final_monthly_amount_usd = final_monthly_amount
                        final_monthly_total += final_monthly_amount
                    else:
                        service_line.final_monthly_amount_usd = Decimal('0.00')

                    service_line.save()

                # While the plan is still draft, remove stale lines
                # for selections that no longer exist.
                if plan.plan_status == 'draft':
                    plan.service_lines.exclude(
                        source_selection_id__in=current_selection_ids
                    ).delete()

                plan.final_monthly_fee_usd = final_monthly_total.quantize(
                    Decimal('0.01'),
                    rounding=ROUND_HALF_UP
                )

                plan.save(
                    update_fields=[
                        'final_monthly_fee_usd',
                        'updated_by',
                        'updated_at',
                    ]
                )

            messages.success(
                request,
                "The final care plan draft has been saved successfully."
            )

            return redirect(
                'myadmin:property_care_final_plan_manage',
                pk=managed_property.pk
            )

        else:
            messages.error(
                request,
                "Please correct the errors below and try again."
            )

    else:
        form = PropertyCarePlanForm(
            instance=care_plan
        )

    service_rows = []

    for selection in selections:
        existing_line = existing_lines.get(selection.service_type_id)

        service_rows.append({
            'selection': selection,
            'service': selection.service_type,
            'line': existing_line,
            'is_included': (
                existing_line.is_included
                if existing_line
                else selection.selection_status != 'not_included'
            ),
            'default_final_amount': (
                existing_line.final_monthly_amount_usd
                if existing_line
                else (
                    selection.final_monthly_amount_usd
                    or selection.estimated_monthly_amount_usd
                    or Decimal('0.00')
                )
            ),
        })

    return render(
        request,
        'myadmin/property_care_final_plan_manage.html',
        {
            'property': managed_property,
            'care_plan': care_plan,
            'form': form,
            'service_rows': service_rows,
            'frequency_choices': PropertyServiceSelection.FREQUENCY_CHOICES,
        }
    )

@staff_member_required
@require_POST
def property_care_final_plan_finalize(request, pk):
    """
    Finalizes the approved monthly care plan.
    Finalization also updates the original property service selections
    with approved/not-included status and final amounts.
    """

    managed_property = get_object_or_404(
        ManagedProperty,
        pk=pk,
        review_status='approved'
    )

    care_plan = get_object_or_404(
        PropertyCarePlan.objects.prefetch_related(
            'service_lines__source_selection'
        ),
        property=managed_property
    )

    if care_plan.plan_status == 'finalized':
        messages.info(
            request,
            "This care plan has already been finalized."
        )
        return redirect(
            'myadmin:property_care_final_plan_manage',
            pk=managed_property.pk
        )

    included_lines = care_plan.service_lines.filter(
        is_included=True
    )

    if not care_plan.start_date:
        messages.error(
            request,
            "Please set an approved plan start date before finalizing."
        )
        return redirect(
            'myadmin:property_care_final_plan_manage',
            pk=managed_property.pk
        )

    if not included_lines.exists():
        messages.error(
            request,
            "Please include at least one service before finalizing the plan."
        )
        return redirect(
            'myadmin:property_care_final_plan_manage',
            pk=managed_property.pk
        )

    with transaction.atomic():
        care_plan.plan_status = 'finalized'
        care_plan.finalized_at = timezone.now()
        care_plan.finalized_by = request.user
        care_plan.updated_by = request.user

        care_plan.save(
            update_fields=[
                'plan_status',
                'finalized_at',
                'finalized_by',
                'updated_by',
                'updated_at',
            ]
        )

        for line in care_plan.service_lines.select_related('source_selection'):
            selection = line.source_selection

            if not selection:
                continue

            if line.is_included:
                selection.selection_status = 'approved'
                selection.final_monthly_amount_usd = line.final_monthly_amount_usd
                selection.staff_note = line.line_note
            else:
                selection.selection_status = 'not_included'
                selection.final_monthly_amount_usd = None
                selection.staff_note = line.exclusion_reason

            selection.save(
                update_fields=[
                    'selection_status',
                    'final_monthly_amount_usd',
                    'staff_note',
                    'updated_at',
                ]
            )

        def create_payable_after_commit():
            finalized_plan = PropertyCarePlan.objects.select_related(
                'property',
                'property__owner',
                'property__owner__user',
            ).get(pk=care_plan.pk)

            create_property_care_monthly_plan_payable_item(finalized_plan)

        transaction.on_commit(create_payable_after_commit)

    messages.success(
        request,
        "The final Property Care Plan has been finalized successfully."
    )

    return redirect(
        'myadmin:property_care_final_plan_manage',
        pk=managed_property.pk
    )


@staff_member_required
def myadmin_home(request):
    submitted_property_count = ManagedProperty.objects.filter(
        review_status='submitted'
    ).count()

    approved_property_count = ManagedProperty.objects.filter(
        review_status='approved'
    ).count()

    rejected_property_count = ManagedProperty.objects.filter(
        review_status='rejected'
    ).count()

    return render(
        request,
        'myadmin/myadmin_home.html',
        {
            'submitted_property_count': submitted_property_count,
            'approved_property_count': approved_property_count,
            'rejected_property_count': rejected_property_count,
        }
    )

@staff_member_required
def property_care_property_review_list(request):
    """
    Staff review queue for Property Care managed properties.
    Supports filtering by review status.
    """

    status = request.GET.get('status', 'submitted')

    valid_statuses = {
        'submitted',
        'approved',
        'rejected',
        'draft',
        'all',
    }

    if status not in valid_statuses:
        status = 'submitted'

    properties = (
        ManagedProperty.objects
        .select_related('owner', 'reviewed_by')
        .prefetch_related('images')
        .all()
    )

    if status != 'all':
        properties = properties.filter(review_status=status)

    properties = properties.order_by('-submitted_for_review_at', '-created_at')

    counts = {
        'submitted': ManagedProperty.objects.filter(review_status='submitted').count(),
        'approved': ManagedProperty.objects.filter(review_status='approved').count(),
        'rejected': ManagedProperty.objects.filter(review_status='rejected').count(),
        'draft': ManagedProperty.objects.filter(review_status='draft').count(),
        'all': ManagedProperty.objects.count(),
    }

    return render(
        request,
        'myadmin/property_care_property_review_list.html',
        {
            'properties': properties,
            'current_status': status,
            'counts': counts,
        }
    )

@staff_member_required
def property_care_property_review_detail(request, pk):
    """
    Staff review detail page for a single managed property.
    """

    managed_property = get_object_or_404(
        ManagedProperty.objects
        .select_related('owner', 'reviewed_by')
        .prefetch_related('images'),
        pk=pk
    )

    images = managed_property.images.all()

    return render(
        request,
        'myadmin/property_care_property_review_detail.html',
        {
            'property': managed_property,
            'images': images,
        }
    )

@staff_member_required
@require_POST
def property_care_property_approve(request, pk):
    """
    Staff approves a Property Care managed property.
    """

    managed_property = get_object_or_404(
        ManagedProperty,
        pk=pk
    )

    review_note = request.POST.get('review_note', '').strip()

    managed_property.is_submitted_for_review = True
    managed_property.is_approved = True
    managed_property.review_status = 'approved'
    managed_property.reviewed_at = timezone.now()
    managed_property.reviewed_by = request.user
    managed_property.staff_review_note = review_note

    managed_property.save(
        update_fields=[
            'is_submitted_for_review',
            'is_approved',
            'review_status',
            'reviewed_at',
            'reviewed_by',
            'staff_review_note',
        ]
    )

    messages.success(
        request,
        f'"{managed_property.property_name}" has been approved successfully.'
    )

    return redirect(
        'myadmin:property_care_property_review_detail',
        pk=managed_property.pk
    )

@staff_member_required
@require_POST
def property_care_property_reject(request, pk):
    """
    Staff rejects a Property Care managed property.
    A rejection note is required.
    """

    managed_property = get_object_or_404(
        ManagedProperty,
        pk=pk
    )

    review_note = request.POST.get('review_note', '').strip()

    if not review_note:
        messages.error(
            request,
            "Please provide a rejection note before rejecting the property."
        )

        return redirect(
            'myadmin:property_care_property_review_detail',
            pk=managed_property.pk
        )

    managed_property.is_submitted_for_review = True
    managed_property.is_approved = False
    managed_property.review_status = 'rejected'
    managed_property.reviewed_at = timezone.now()
    managed_property.reviewed_by = request.user
    managed_property.staff_review_note = review_note

    managed_property.save(
        update_fields=[
            'is_submitted_for_review',
            'is_approved',
            'review_status',
            'reviewed_at',
            'reviewed_by',
            'staff_review_note',
        ]
    )

    messages.warning(
        request,
        f'"{managed_property.property_name}" has been rejected and marked for correction.'
    )

    return redirect(
        'myadmin:property_care_property_review_detail',
        pk=managed_property.pk
    )

@staff_member_required
def property_care_visit_list(request):
    """
    MyAdmin staff view:
    Shows all Property Care maintenance visits with useful filters.
    """

    visits = (
        PropertyMaintenanceVisit.objects
        .select_related(
            'managed_property',
            'managed_property__owner',
            'care_plan',
            'related_service_type',
            'visited_by',
            'created_by',
        )
        .all()
    )

    search_query = request.GET.get('q', '').strip()
    visit_status = request.GET.get('status', '').strip()
    visit_type = request.GET.get('type', '').strip()

    if search_query:
        visits = visits.filter(
            Q(visit_title__icontains=search_query)
            | Q(managed_property__property_name__icontains=search_query)
            | Q(managed_property__owner__full_name__icontains=search_query)
            | Q(managed_property__owner__email__icontains=search_query)
            | Q(visit_summary__icontains=search_query)
            | Q(owner_visible_note__icontains=search_query)
        )

    if visit_status:
        visits = visits.filter(
            visit_status=visit_status
        )

    if visit_type:
        visits = visits.filter(
            visit_type=visit_type
        )

    total_visits = PropertyMaintenanceVisit.objects.count()
    scheduled_visits = PropertyMaintenanceVisit.objects.filter(
        visit_status='scheduled'
    ).count()
    in_progress_visits = PropertyMaintenanceVisit.objects.filter(
        visit_status='in_progress'
    ).count()
    completed_visits = PropertyMaintenanceVisit.objects.filter(
        visit_status='completed'
    ).count()

    context = {
        'visits': visits,
        'search_query': search_query,
        'selected_status': visit_status,
        'selected_type': visit_type,

        'visit_status_choices': PropertyMaintenanceVisit.VISIT_STATUS_CHOICES,
        'visit_type_choices': PropertyMaintenanceVisit.VISIT_TYPE_CHOICES,

        'total_visits': total_visits,
        'scheduled_visits': scheduled_visits,
        'in_progress_visits': in_progress_visits,
        'completed_visits': completed_visits,
    }

    return render(
        request,
        'myadmin/property_care_visit_list.html',
        context
    )

@staff_member_required
def property_care_visit_create(request, property_id):
    """
    MyAdmin staff view:
    Creates a maintenance visit for a specific managed property.
    """

    managed_property = get_object_or_404(
        ManagedProperty.objects.select_related(
            'owner'
        ),
        pk=property_id
    )

    if request.method == 'POST':
        form = PropertyMaintenanceVisitForm(
            request.POST,
            managed_property=managed_property
        )

        if form.is_valid():
            visit = form.save(commit=False)
            visit.managed_property = managed_property
            visit.created_by = request.user
            visit.save()

            messages.success(
                request,
                "Maintenance visit has been created successfully."
            )

            return redirect(
                'myadmin:property_care_visit_detail',
                pk=visit.pk
            )

        messages.error(
            request,
            "Please correct the errors below and try again."
        )

    else:
        form = PropertyMaintenanceVisitForm(
            managed_property=managed_property
        )

    context = {
        'managed_property': managed_property,
        'form': form,
    }

    return render(
        request,
        'myadmin/property_care_visit_create.html',
        context
    )

@staff_member_required
def property_care_visit_detail(request, pk):
    """
    MyAdmin staff view:
    Detailed page for one Property Care maintenance visit.
    """

    visit = get_object_or_404(
        PropertyMaintenanceVisit.objects.select_related(
            'managed_property',
            'managed_property__owner',
            'care_plan',
            'related_service_type',
            'visited_by',
            'created_by',
        ).prefetch_related(
            'photos'
        ),
        pk=pk
    )

    photos = visit.photos.select_related(
        'uploaded_by'
    ).all()

    total_photos = photos.count()
    owner_visible_photos = photos.filter(
        is_owner_visible=True
    ).count()
    issue_photos = photos.filter(
        photo_type='issue'
    ).count()

    # =========================================================
    # Inspection report connected to this visit, if one exists
    # =========================================================
    inspection_report = PropertyInspectionReport.objects.filter(
        visit=visit
    ).first()

    context = {
        'visit': visit,
        'property': visit.managed_property,
        'photos': photos,

        'total_photos': total_photos,
        'owner_visible_photos': owner_visible_photos,
        'issue_photos': issue_photos,

        'inspection_report': inspection_report,
    }

    return render(
        request,
        'myadmin/property_care_visit_detail.html',
        context
    )

@staff_member_required
def property_care_visit_update(request, pk):
    """
    MyAdmin staff view:
    Updates an existing Property Care maintenance visit.
    """

    visit = get_object_or_404(
        PropertyMaintenanceVisit.objects.select_related(
            'managed_property',
            'managed_property__owner',
            'care_plan',
            'related_service_type',
            'visited_by',
            'created_by',
        ),
        pk=pk
    )

    managed_property = visit.managed_property

    if request.method == 'POST':
        form = PropertyMaintenanceVisitForm(
            request.POST,
            instance=visit,
            managed_property=managed_property
        )

        if form.is_valid():
            updated_visit = form.save(commit=False)

            # Keep original property and creator unchanged
            updated_visit.managed_property = managed_property

            # created_by should not be overwritten during edit
            updated_visit.save()

            messages.success(
                request,
                "Maintenance visit updated successfully."
            )

            return redirect(
                'myadmin:property_care_visit_detail',
                pk=updated_visit.pk
            )

        messages.error(
            request,
            "Please correct the errors below and try again."
        )

    else:
        form = PropertyMaintenanceVisitForm(
            instance=visit,
            managed_property=managed_property
        )

    context = {
        'visit': visit,
        'managed_property': managed_property,
        'form': form,
        'is_update': True,
    }

    return render(
        request,
        'myadmin/property_care_visit_update.html',
        context
    )

@staff_member_required
def property_care_visit_photo_upload(request, pk):
    """
    MyAdmin staff view:
    Uploads a photo for a Property Care maintenance visit.
    """

    visit = get_object_or_404(
        PropertyMaintenanceVisit.objects.select_related(
            'managed_property',
            'managed_property__owner',
        ),
        pk=pk
    )

    if request.method == 'POST':
        form = PropertyVisitPhotoForm(
            request.POST,
            request.FILES
        )

        if form.is_valid():
            photo = form.save(commit=False)
            photo.visit = visit
            photo.uploaded_by = request.user
            photo.save()

            messages.success(
                request,
                "Visit photo uploaded successfully."
            )

            return redirect(
                'myadmin:property_care_visit_detail',
                pk=visit.pk
            )

        messages.error(
            request,
            "Please correct the photo upload errors below."
        )

    else:
        form = PropertyVisitPhotoForm()

    context = {
        'visit': visit,
        'property': visit.managed_property,
        'form': form,
    }

    return render(
        request,
        'myadmin/property_care_visit_photo_upload.html',
        context
    )

@staff_member_required
@require_POST
def property_care_visit_photo_delete(request, pk, photo_id):
    """
    MyAdmin staff action:
    Deletes a visit photo from a maintenance visit.
    """

    visit = get_object_or_404(
        PropertyMaintenanceVisit,
        pk=pk
    )

    photo = get_object_or_404(
        PropertyVisitPhoto,
        pk=photo_id,
        visit=visit
    )

    photo.delete()

    messages.success(
        request,
        "Visit photo deleted successfully."
    )

    return redirect(
        'myadmin:property_care_visit_detail',
        pk=visit.pk
    )

@staff_member_required
def property_care_inspection_report_create(request, visit_id):
    """
    MyAdmin staff view:
    Creates a formal inspection report from a specific maintenance visit.
    """

    visit = get_object_or_404(
        PropertyMaintenanceVisit.objects.select_related(
            'managed_property',
            'managed_property__owner',
            'care_plan',
            'related_service_type',
            'visited_by',
        ),
        pk=visit_id
    )

    managed_property = visit.managed_property

    # Prevent creating more than one inspection report for the same visit
    existing_report = PropertyInspectionReport.objects.filter(
        visit=visit
    ).first()

    if existing_report:
        messages.info(
            request,
            "An inspection report already exists for this maintenance visit."
        )

        return redirect(
            'myadmin:property_care_inspection_report_detail',
            pk=existing_report.pk
        )

    if request.method == 'POST':
        form = PropertyInspectionReportForm(request.POST)

        if form.is_valid():
            report = form.save(commit=False)

            report.managed_property = managed_property
            report.visit = visit
            report.prepared_by = request.user

            report.save()

            messages.success(
                request,
                "Inspection report created successfully."
            )

            return redirect(
                'myadmin:property_care_inspection_report_detail',
                pk=report.pk
            )

        messages.error(
            request,
            "Please correct the errors below and try again."
        )

    else:
        initial_data = {
            'report_title': f"Inspection Report - {visit.visit_title}",
        }

        if visit.completed_at:
            initial_data['inspection_date'] = visit.completed_at.date()
        elif visit.scheduled_date:
            initial_data['inspection_date'] = visit.scheduled_date

        form = PropertyInspectionReportForm(
            initial=initial_data
        )

    context = {
        'visit': visit,
        'property': managed_property,
        'form': form,
    }

    return render(
        request,
        'myadmin/property_care_inspection_report_create.html',
        context
    )

@staff_member_required
def property_care_inspection_report_detail(request, pk):
    """
    MyAdmin staff view:
    Shows one formal Property Care inspection report and its curated report photos.
    """

    report = get_object_or_404(
        PropertyInspectionReport.objects.select_related(
            'managed_property',
            'managed_property__owner',
            'visit',
            'prepared_by',
            'approved_by',
        ).prefetch_related(
            'photos'
        ),
        pk=pk
    )

    photos = report.photos.select_related(
        'uploaded_by'
    ).all()

    total_photos = photos.count()

    owner_visible_photos = photos.filter(
        is_owner_visible=True
    ).count()

    issue_photos = photos.filter(
        photo_type='issue_evidence'
    ).count()

    context = {
        'report': report,
        'property': report.managed_property,
        'visit': report.visit,
        'photos': photos,

        'total_photos': total_photos,
        'owner_visible_photos': owner_visible_photos,
        'issue_photos': issue_photos,
    }

    return render(
        request,
        'myadmin/property_care_inspection_report_detail.html',
        context
    )

@staff_member_required
def property_care_inspection_report_photo_upload(request, pk):
    """
    MyAdmin staff view:
    Uploads a curated image for a formal inspection report.
    """

    report = get_object_or_404(
        PropertyInspectionReport.objects.select_related(
            'managed_property',
            'managed_property__owner',
            'visit',
        ),
        pk=pk
    )

    if request.method == 'POST':
        form = PropertyInspectionReportPhotoForm(
            request.POST,
            request.FILES
        )

        if form.is_valid():
            photo = form.save(commit=False)

            photo.report = report
            photo.uploaded_by = request.user

            photo.save()

            messages.success(
                request,
                "Inspection report photo uploaded successfully."
            )

            return redirect(
                'myadmin:property_care_inspection_report_detail',
                pk=report.pk
            )

        messages.error(
            request,
            "Please correct the photo upload errors below."
        )

    else:
        form = PropertyInspectionReportPhotoForm()

    context = {
        'report': report,
        'property': report.managed_property,
        'visit': report.visit,
        'form': form,
    }

    return render(
        request,
        'myadmin/property_care_inspection_report_photo_upload.html',
        context
    )

@staff_member_required
@require_POST
def property_care_inspection_report_photo_delete(request, pk, photo_id):
    """
    MyAdmin staff action:
    Deletes a curated inspection report photo.
    """

    report = get_object_or_404(
        PropertyInspectionReport,
        pk=pk
    )

    photo = get_object_or_404(
        PropertyInspectionReportPhoto,
        pk=photo_id,
        report=report
    )

    photo.delete()

    messages.success(
        request,
        "Inspection report photo deleted successfully."
    )

    return redirect(
        'myadmin:property_care_inspection_report_detail',
        pk=report.pk
    )

