from django.contrib import admin, messages
from django.contrib.admin.views.decorators import staff_member_required
from django.core.exceptions import SuspiciousFileOperation
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import path, reverse
from django.utils.decorators import method_decorator
from django.views import View

from claims.forms import AssistantInputForm, RefineDraftForm, ReviewDraftForm
from claims.models import ClaimDraft
from claims.services.ai_assistant import AIAssistantError
from claims.services.article_fetcher import ArticleFetchError
from claims.services.draft_processor import process_claim_draft
from claims.services.draft_publisher import DraftPublishError, publish_draft


def _get_user_draft(request, draft_id):
    if request.user.is_superuser:
        return get_object_or_404(ClaimDraft, pk=draft_id)
    return get_object_or_404(ClaimDraft, pk=draft_id, created_by=request.user)


@method_decorator(staff_member_required, name='dispatch')
class AssistantView(View):
    template_name = 'admin/claims/assistant.html'

    def get(self, request):
        form = AssistantInputForm()
        drafts = ClaimDraft.objects.filter(created_by=request.user).order_by('-created_at')[:10]
        return render(request, self.template_name, {
            **admin.site.each_context(request),
            'form': form,
            'recent_drafts': drafts,
            'title': 'Fakten-Assistent',
            'opts': ClaimDraft._meta,
        })

    def post(self, request):
        form = AssistantInputForm(request.POST, request.FILES)
        if not form.is_valid():
            return render(request, self.template_name, {
                **admin.site.each_context(request),
                'form': form,
                'recent_drafts': ClaimDraft.objects.filter(created_by=request.user)[:10],
                'title': 'Fakten-Assistent',
                'opts': ClaimDraft._meta,
            })

        draft = ClaimDraft.objects.create(
            created_by=request.user,
            article_url=form.cleaned_data.get('article_url') or '',
            user_notes=form.cleaned_data.get('user_notes') or '',
            uploaded_file=form.cleaned_data.get('uploaded_file'),
        )

        try:
            process_claim_draft(draft)
        except (ArticleFetchError, AIAssistantError):
            return redirect('admin:claims_claimdraft_review', draft.pk)

        messages.success(request, 'Entwurf wurde erstellt. Bitte vor der Veröffentlichung prüfen.')
        return redirect('admin:claims_claimdraft_review', draft.pk)


@method_decorator(staff_member_required, name='dispatch')
class ReviewDraftView(View):
    template_name = 'admin/claims/review_draft.html'

    def get(self, request, draft_id):
        draft = _get_user_draft(request, draft_id)
        return render(request, self.template_name, {
            **admin.site.each_context(request),
            'draft': draft,
            'form': ReviewDraftForm(instance=draft),
            'refine_form': RefineDraftForm(),
            'title': f'Entwurf prüfen: {draft.title or draft.pk}',
            'opts': ClaimDraft._meta,
        })

    def post(self, request, draft_id):
        draft = _get_user_draft(request, draft_id)
        action = request.POST.get('action')

        if action == 'refine':
            refine_form = RefineDraftForm(request.POST)
            if refine_form.is_valid():
                try:
                    process_claim_draft(draft, refinement=refine_form.cleaned_data['refinement'])
                    messages.success(request, 'Entwurf wurde überarbeitet.')
                except (ArticleFetchError, AIAssistantError) as exc:
                    messages.error(request, str(exc))
            return redirect('admin:claims_claimdraft_review', draft.pk)

        if action == 'reject':
            draft.status = ClaimDraft.DraftStatus.REJECTED
            draft.save(update_fields=['status', 'updated_at'])
            messages.info(request, 'Entwurf wurde verworfen.')
            return redirect('admin:claims_claimdraft_assistant')

        form = ReviewDraftForm(request.POST, instance=draft)
        if not form.is_valid():
            return render(request, self.template_name, {
                **admin.site.each_context(request),
                'draft': draft,
                'form': form,
                'refine_form': RefineDraftForm(),
                'title': f'Entwurf prüfen: {draft.title or draft.pk}',
                'opts': ClaimDraft._meta,
            })

        draft = form.save()

        if action == 'save':
            draft.status = ClaimDraft.DraftStatus.REVIEW
            draft.save(update_fields=['status', 'updated_at'])
            messages.success(request, 'Änderungen gespeichert.')
            return redirect('admin:claims_claimdraft_review', draft.pk)

        if action == 'publish':
            try:
                claim = publish_draft(draft)
            except DraftPublishError as exc:
                messages.error(request, str(exc))
                return redirect('admin:claims_claimdraft_review', draft.pk)
            except SuspiciousFileOperation as exc:
                messages.error(request, f'Datei konnte nicht gespeichert werden: {exc}')
                return redirect('admin:claims_claimdraft_review', draft.pk)

            messages.success(
                request,
                f'Behauptung „{claim.title}" wurde veröffentlicht.',
            )
            return redirect(reverse('admin:claims_claim_change', args=[claim.pk]))

        return redirect('admin:claims_claimdraft_review', draft.pk)
