<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Mission;
use App\Models\MissionDispute;
use App\Services\AdminAuditLogger;
use App\Services\InAppNotificationService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class MissionDisputeController extends Controller
{
    public function store(
        Request $request,
        Mission $mission,
        InAppNotificationService $notificationService,
    ): JsonResponse
    {
        $user = $request->user();

        $isParticipant = $mission->client_id === $user->id
            || $mission->liner_id === $user->id;

        abort_unless($isParticipant, 403);

        $data = $request->validate([
            'category' => ['required', 'string', 'max:100'],
            'description' => ['required', 'string', 'max:2000'],
            'against_user_id' => ['nullable', 'integer', 'exists:users,id'],
        ]);

        $dispute = MissionDispute::create([
            'mission_id' => $mission->id,
            'reporter_id' => $user->id,
            'against_user_id' => $data['against_user_id'] ?? null,
            'category' => $data['category'],
            'description' => $data['description'],
            'status' => 'open',
        ]);

        $targetUserId = $dispute->against_user_id;

        if ($targetUserId === null) {
            $targetUserId = $mission->client_id === $user->id
                ? $mission->liner_id
                : $mission->client_id;
        }

        if ($targetUserId !== null && $targetUserId !== $user->id) {
            $notificationService->notifyUser(
                $targetUserId,
                'dispute.opened',
                'Nouveau litige',
                sprintf('Un litige a ete ouvert sur la mission "%s".', $mission->title),
                [
                    'mission_id' => $mission->id,
                    'dispute_id' => $dispute->id,
                    'status' => $dispute->status,
                ],
            );
        }

        return response()->json(['data' => $dispute], 201);
    }

    public function mine(Request $request): JsonResponse
    {
        $user = $request->user();

        $disputes = MissionDispute::query()
            ->where(function ($query) use ($user): void {
                $query->where('reporter_id', $user->id)
                    ->orWhere('against_user_id', $user->id);
            })
            ->with(['mission:id,title,status', 'reporter:id,name', 'againstUser:id,name'])
            ->latest()
            ->paginate(20);

        return response()->json(['data' => $disputes]);
    }

    public function adminIndex(Request $request): JsonResponse
    {
        abort_unless($request->user()?->role === 'admin', 403);

        $query = MissionDispute::query()->with([
            'mission:id,title,status',
            'reporter:id,name,email',
            'againstUser:id,name,email',
        ]);

        if ($request->filled('status')) {
            $query->where('status', $request->string('status'));
        }

        return response()->json([
            'data' => $query->latest()->paginate(20),
        ]);
    }

    public function adminReview(
        Request $request,
        MissionDispute $missionDispute,
        AdminAuditLogger $auditLogger,
        InAppNotificationService $notificationService,
    ): JsonResponse {
        $admin = $request->user();
        abort_unless($admin?->role === 'admin', 403);

        $data = $request->validate([
            'status' => ['required', 'in:resolved,rejected'],
            'resolution_notes' => ['nullable', 'string', 'max:2000'],
        ]);

        $missionDispute->update([
            'status' => $data['status'],
            'resolution_notes' => $data['resolution_notes'] ?? null,
            'resolved_by' => $admin->id,
            'resolved_at' => now(),
        ]);

        $auditLogger->log($admin, 'dispute.review', $missionDispute, [
            'status' => $data['status'],
            'resolution_notes' => $data['resolution_notes'] ?? null,
        ]);

        $missionDispute = $missionDispute->fresh(['mission:id,title']);
        $missionTitle = $missionDispute->mission?->title ?? 'mission';

        $recipientIds = collect([
            $missionDispute->reporter_id,
            $missionDispute->against_user_id,
        ])->filter()->unique();

        foreach ($recipientIds as $recipientId) {
            $notificationService->notifyUser(
                (int) $recipientId,
                'dispute.reviewed',
                'Mise a jour litige',
                sprintf(
                    'Le litige de "%s" est maintenant: %s.',
                    $missionTitle,
                    $data['status'],
                ),
                [
                    'mission_id' => $missionDispute->mission_id,
                    'dispute_id' => $missionDispute->id,
                    'status' => $data['status'],
                ],
            );
        }

        return response()->json([
            'data' => $missionDispute->fresh(),
        ]);
    }
}
