<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreResumeRequest;
use App\Jobs\AnalyzeResume;
use App\Models\ResumeReport;
use App\Services\Analytics\EngagementLogger;
use App\Services\Settings\SettingsService;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class ResumeController extends Controller
{
    public function __construct(private readonly SettingsService $settings) {}

    public function show(Request $request): View
    {
        return view('resume.show', [
            'resumeReport' => $request->user()->resumeReport,
        ]);
    }

    public function history(Request $request): View
    {
        return view('resume.history', [
            'resumeReports' => $request->user()
                ->resumeReports()
                ->latest()
                ->get(),
        ]);
    }

    public function store(StoreResumeRequest $request, EngagementLogger $engagementLogger): RedirectResponse|JsonResponse
    {
        $user = $request->user();
        $file = $request->file('resume');
        $disk = 'local';
        $storagePath = trim((string) $this->settings->get('resume.resume_storage_path', 'resumes'), '/');
        $storagePath = $storagePath === '' ? 'resumes' : $storagePath;
        $existingResumeReport = $user->resumeReport;

        $path = $file->storeAs(
            $storagePath.'/'.$user->id,
            Str::uuid().'.'.$file->getClientOriginalExtension(),
            $disk
        );

        $resumeReport = DB::transaction(function () use ($user, $file, $disk, $path): ResumeReport {
            $user->resumeReports()->update(['is_current' => false]);

            $resumeReport = $user->resumeReports()->create([
                'is_current' => true,
                'original_filename' => $file->getClientOriginalName(),
                'disk' => $disk,
                'path' => $path,
                'mime_type' => (string) $file->getMimeType(),
                'size_bytes' => $file->getSize(),
                'status' => ResumeReport::STATUS_PENDING,
                'ats_score' => null,
                'remote_readiness_score' => null,
                'extracted_skills' => null,
                'role_suggestions' => null,
                'missing_keywords' => null,
                'resume_improvements' => null,
                'analysis' => null,
                'failure_reason' => null,
                'analyzed_at' => null,
            ]);

            $user->forceFill([
                'resume_uploaded_at' => now(),
                'resume_analyzed_at' => null,
            ])->save();

            return $resumeReport;
        });

        if (
            $this->settings->isEnabled('resume.delete_old_resume_on_re_upload')
            && $existingResumeReport instanceof ResumeReport
            && $existingResumeReport->disk === $disk
            && $existingResumeReport->path
            && $existingResumeReport->path !== $path
        ) {
            Storage::disk($disk)->delete($existingResumeReport->path);
        }

        AnalyzeResume::dispatch($resumeReport);
        $engagementLogger->record(
            $user,
            'resume_uploaded',
            'Uploaded resume '.$resumeReport->original_filename.'.',
            [
                'resume_report_id' => $resumeReport->id,
                'filename' => $resumeReport->original_filename,
            ],
            $resumeReport,
        );

        if ($request->expectsJson()) {
            return response()->json([
                'message' => 'Resume uploaded. Analysis has started.',
                'status_url' => route('resume.status'),
                'report_url' => route('resume.report'),
                'resume' => $this->resumePayload($resumeReport->refresh()),
            ], 202);
        }

        return redirect()
            ->route('resume.show')
            ->with('status', 'Resume uploaded. Analysis has started.');
    }

    public function status(Request $request): JsonResponse
    {
        return response()->json([
            'resume' => $this->resumePayload($request->user()->resumeReport),
        ]);
    }

    public function report(Request $request): JsonResponse
    {
        return response()->json([
            'resume' => $this->resumePayload($request->user()->resumeReport),
        ]);
    }

    /**
     * @return array<string, mixed>|null
     */
    private function resumePayload(?ResumeReport $resumeReport): ?array
    {
        if (! $resumeReport instanceof ResumeReport) {
            return null;
        }

        return [
            'id' => $resumeReport->id,
            'filename' => $resumeReport->original_filename,
            'status' => $resumeReport->status,
            'status_label' => Str::headline($resumeReport->status),
            'ats_score' => $resumeReport->ats_score,
            'remote_readiness_score' => $resumeReport->remote_readiness_score,
            'extracted_skills' => $resumeReport->extracted_skills ?? [],
            'role_suggestions' => $resumeReport->role_suggestions ?? [],
            'missing_keywords' => $resumeReport->missing_keywords ?? [],
            'resume_improvements' => $resumeReport->resume_improvements ?? [],
            'summary' => $resumeReport->analysis['summary'] ?? null,
            'failure_reason' => $resumeReport->failure_reason,
            'analyzed_at' => $resumeReport->analyzed_at?->toIso8601String(),
            'is_completed' => $resumeReport->isCompleted(),
            'has_failed' => $resumeReport->hasFailed(),
            'profile_url' => route('profile.edit'),
        ];
    }
}
