<?php

namespace App\Http\Controllers;

use App\Models\ImportedJob;
use App\Models\JobAiAssistance;
use App\Services\Jobs\JobAiAssistantService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rule;
use RuntimeException;
use Throwable;

class JobAiAssistantController extends Controller
{
    public function store(
        Request $request,
        ImportedJob $job,
        JobAiAssistantService $assistantService
    ): JsonResponse|RedirectResponse {
        Gate::authorize('view', $job);

        $validated = $request->validate([
            'type' => [
                'required',
                'string',
                Rule::in([
                    JobAiAssistance::TYPE_COVER_LETTER,
                    JobAiAssistance::TYPE_INTERVIEW_PREP,
                    JobAiAssistance::TYPE_MATCH_EXPLANATION,
                ]),
            ],
            'regenerate' => ['nullable', 'boolean'],
        ]);

        $type = (string) $validated['type'];
        $existing = $request->user()
            ->jobAiAssistances()
            ->where('imported_job_id', $job->id)
            ->where('type', $type)
            ->first();

        if ($existing && ! (bool) ($validated['regenerate'] ?? false)) {
            return $this->response($request, $existing, 'Loaded existing AI output.');
        }

        try {
            $result = $assistantService->generate($request->user(), $job, $type);

            $assistance = $request->user()->jobAiAssistances()->updateOrCreate(
                [
                    'imported_job_id' => $job->id,
                    'type' => $type,
                ],
                [
                    'status' => JobAiAssistance::STATUS_COMPLETED,
                    'content' => $result['content'],
                    'payload' => $result['payload'],
                    'failure_reason' => null,
                    'generated_at' => now(),
                ]
            );

            return $this->response($request, $assistance, 'AI output generated.');
        } catch (RuntimeException $exception) {
            return $this->failure($request, $exception->getMessage());
        } catch (Throwable $exception) {
            report($exception);

            return $this->failure($request, 'AI generation failed. Please check OpenAI settings and try again.');
        }
    }

    private function response(Request $request, JobAiAssistance $assistance, string $message): JsonResponse|RedirectResponse
    {
        if ($request->expectsJson()) {
            return response()->json([
                'message' => $message,
                'type' => $assistance->type,
                'content' => $assistance->content,
                'payload' => $assistance->payload ?? [],
                'generated_at' => $assistance->generated_at?->toIso8601String(),
            ]);
        }

        return back()->with('status', $message);
    }

    private function failure(Request $request, string $message): JsonResponse|RedirectResponse
    {
        if ($request->expectsJson()) {
            return response()->json([
                'message' => $message,
            ], 422);
        }

        return back()->withErrors(['ai' => $message]);
    }
}
