<?php

namespace App\Http\Controllers\Member;

use App\Http\Controllers\Controller;
use App\Http\Requests\Member\RateSolutionRequest;
use App\Http\Requests\Member\StoreSolutionRequest;
use App\Models\Cases;
use App\Models\MemberSolution;
use App\Services\Member\CaseService;
use App\Services\Member\MemberSolutionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

// ══════════════════════════════════════════════════════════════════
//  InPractice — Member\CaseController
//  Location: app/Http/Controllers/Member/CaseController.php
//
//  Thin controller — follows the Project Bible strictly.
//  Every method: receive → call service → return response.
//  Zero business logic here.
// ══════════════════════════════════════════════════════════════════

class CaseController extends Controller
{
    public function __construct(
        private readonly CaseService            $caseService,
        private readonly MemberSolutionService  $solutionService,
    ) {}

    /**
     * Case library — filterable, paginated.
     * GET /app/cases
     */
    public function index(Request $request): Response
    {
        $data = $this->caseService->index(
            $request->user(),
            $request->only(['hub_id', 'topic_slug', 'difficulty', 'layer', 'sector_id'])
        );

        return Inertia::render('Member/Cases/Index', $data);
    }

    /**
     * Single case reading experience.
     * GET /app/cases/{case}
     *
     * abort_if: case must be published — members cannot access drafts.
     */
    public function show(Cases $case): Response
    {
        abort_if($case->status !== 'published', 404);

        $data = $this->caseService->show(auth()->user(), $case);

        // Merge solution data into the same Inertia response
        $solutionData = $this->solutionService->getSolutions($case, auth()->user());

        return Inertia::render('Member/Cases/Show', array_merge($data, $solutionData));
    }

    /**
     * Reveal solution — PATCH, returns JSON for Vue to update without page reload.
     * PATCH /app/cases/{case}/reveal
     */
    public function reveal(Request $request, Cases $case): JsonResponse|RedirectResponse
    {
        abort_if($case->status !== 'published', 404);

        $progress = $this->caseService->reveal($request->user(), $case);

        // Inertia visits must get a valid Inertia/redirect response (not bare JSON).
        if ($request->header('X-Inertia')) {
            return back();
        }

        return response()->json([
            'solution_revealed' => (bool) $progress->solution_revealed,
        ]);
    }

    /**
     * Mark complete — PATCH, returns JSON for Vue to update without page reload.
     * PATCH /app/cases/{case}/complete
     */
    public function complete(Cases $case): JsonResponse
    {
        abort_if($case->status !== 'published', 404);

        $progress = $this->caseService->complete(auth()->user(), $case);

        return response()->json([
            'status'       => $progress->status,
            'completed_at' => $progress->completed_at?->toDateTimeString(),
        ]);
    }

    /**
     * Progress page — all cases with read status.
     * GET /app/cases/progress
     */
    public function progress(Request $request): Response
    {
        $data = $this->caseService->progress(
            $request->user(),
            $request->only(['hub_id'])
        );

        return Inertia::render('Member/Cases/Progress', $data);
    }

    // ══════════════════════════════════════════════════════════
    //  MEMBER SOLUTIONS
    // ══════════════════════════════════════════════════════════

    /**
     * Store member solution.
     * POST /app/cases/{case}/solutions
     */
    public function storeSolution(StoreSolutionRequest $request, Cases $case): JsonResponse
    {
        abort_if($case->status !== 'published', 404);

        $solution = $this->solutionService->store(
            $request->user(),
            $case,
            $request->validated()['content']
        );

        return response()->json([
            'solution' => $this->formatSolutionForResponse($solution, $request->user()),
        ], 201);
    }

    /**
     * Update member solution.
     * PATCH /app/cases/{case}/solutions/{solution}
     */
    public function updateSolution(
        StoreSolutionRequest $request,
        Cases $case,
        MemberSolution $solution
    ): JsonResponse {
        abort_if($case->status !== 'published', 404);

        $updated = $this->solutionService->update(
            $request->user(),
            $solution,
            $request->validated()['content']
        );

        return response()->json([
            'solution' => $this->formatSolutionForResponse($updated, $request->user()),
        ]);
    }

    /**
     * Get rating count before delete — so Vue can show the alert.
     * GET /app/cases/{case}/solutions/{solution}/rating-count
     */
    public function solutionRatingCount(Cases $case, MemberSolution $solution): JsonResponse
    {
        $count = $this->solutionService->getRatingCountForDelete($solution, auth()->user());

        return response()->json(['ratings_count' => $count]);
    }

    /**
     * Delete member solution (and all its ratings).
     * DELETE /app/cases/{case}/solutions/{solution}
     */
    public function deleteSolution(Cases $case, MemberSolution $solution): JsonResponse
    {
        $this->solutionService->delete(auth()->user(), $solution);

        return response()->json(['deleted' => true]);
    }

    /**
     * Rate a member solution (1–5).
     * PATCH /app/cases/{case}/solutions/{solution}/rate
     */
    public function rateSolution(
        RateSolutionRequest $request,
        Cases $case,
        MemberSolution $solution
    ): JsonResponse {
        $result = $this->solutionService->rateSolution(
            $request->user(),
            $solution,
            $request->validated()['rating']
        );

        return response()->json($result);
    }

    /**
     * Rate the InPractice solution (1–5).
     * PATCH /app/cases/{case}/rate
     */
    public function rateCase(RateSolutionRequest $request, Cases $case): JsonResponse
    {
        abort_if($case->status !== 'published', 404);

        $result = $this->solutionService->rateCase(
            $request->user(),
            $case,
            $request->validated()['rating']
        );

        return response()->json($result);
    }

    // ── Private helper ────────────────────────────────────────

    private function formatSolutionForResponse(MemberSolution $solution, $user): array
    {
        $solution->load('user:id,nickname,profession,highly_rated_solutions_count');

        return [
            'id'            => $solution->id,
            'content'       => $solution->content,
            'avg_rating'    => round($solution->avg_rating, 1),
            'ratings_count' => $solution->ratings_count,
            'is_mine'       => true,
            'my_rating'     => null,
            'created_at'    => $solution->created_at->diffForHumans(),
            'updated_at'    => $solution->updated_at->diffForHumans(),
            'was_edited'    => false,
            'author' => [
                'nickname'   => $solution->user->nickname,
                'profession' => $solution->user->profession,
                'badge'      => $solution->badge,
            ],
        ];
    }
}