<?php

namespace App\Exceptions;

use App\Exceptions\NotFoundResolver;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * The list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }

    public function render($request, Throwable $e)
    {
        if (
            ! config('app.debug')
            && ! $request->expectsJson()
            && $e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException
        ) {
            try {
                $context = $this->resolveContext($request);
                $this->prepareForContext($context);
                $resolver = $this->container->make(NotFoundResolver::class);
                $payload  = $resolver->resolve($e, $context);

                return response()->view("errors.{$context}.404", $payload, 404);
            } catch (\Throwable $renderError) {
                report($renderError);
                // fall through to parent
            }
        }

        return parent::render($request, $e);
    }

    /**
     * Render an exception into an HTTP response.
     * When APP_DEBUG=true, let Ignition handle it (detailed error page).
     * When APP_DEBUG=false, show standalone error pages that don't depend on layouts.
     */
    protected function renderHttpException(HttpExceptionInterface $e)
    {
        if (config('app.debug')) {
            return parent::convertExceptionToResponse($e);
        }

        if ($e->getStatusCode() !== 404) {
            return parent::renderHttpException($e);
        }

        try {
            $request  = request();
            $context  = $this->resolveContext($request);
            $this->prepareForContext($context);
            $resolver = $this->container->make(NotFoundResolver::class);
            $payload  = $resolver->resolve($e, $context);

            return response()->view("errors.{$context}.404", $payload, 404);
        } catch (\Throwable $renderError) {
            report($renderError);
            return parent::renderHttpException($e);
        }
    }

    /**
     * When rendering a context-specific 404 outside the normal middleware
     * stack (no route matched → ShareErrorsFromSession + auth middleware
     * never ran), the layout still expects $errors and the right default
     * auth guard. This sets both up so the admin layout doesn't blow up.
     */
    private function prepareForContext(string $context): void
    {
        if ($context === 'admin') {
            \Illuminate\Support\Facades\Auth::shouldUse('admin');
        }

        // PRC-838 — store/clientarea 404 theme layout'u header'da dil/currency
        // switcher için $storeLanguages/$storeCurrencies vb. bekler. Bunları
        // normalde SetStoreLocaleFromVisitor middleware View::share eder; route
        // eşleşmeyen 404'te o middleware çalışmadığından switcher boş kalıyordu.
        // Locale'i resolver'dan set edip aynı paylaşımı elle tetikliyoruz.
        if ($context === 'store' || $context === 'clientarea') {
            try {
                $locale = $this->container->make(\App\Services\Store\StorePreferenceResolver::class)->currentLanguage();
                if ($locale) {
                    app()->setLocale($locale);
                }
                $this->container->make(\App\Http\Middleware\SetStoreLocaleFromVisitor::class)
                    ->shareLocaleDataWithViews();
            } catch (\Throwable $e) {
                // switcher verisi paylaşılamazsa layout ?? [] fallback'ine düşer
                report($e);
            }
        }

        $factory = $this->container->make(\Illuminate\Contracts\View\Factory::class);
        if (! $factory->shared('errors')) {
            $factory->share('errors', new \Illuminate\Support\ViewErrorBag());
        }
    }

    private function resolveContext(\Illuminate\Http\Request $request): string
    {
        // PRC-838 — bağlam URL YÜZEYİNE göre çözülür, hangi guard'ın oturumu
        // açık olduğuna göre DEĞİL. Aksi halde admin girişli bir kullanıcı bir
        // store URL'inde 404 alınca admin 404 şablonunu görüyordu (guard check
        // TRUE, ama route eşleşmediği için routeIs false). Prefix'ler:
        // admin=/admin/*, clientarea=/clientarea/*, gerisi=store.
        if ($request->routeIs('admin.*') || $request->is('admin', 'admin/*')) {
            return 'admin';
        }
        if ($request->routeIs('store.auth.*') || $request->is('clientarea', 'clientarea/*')) {
            return 'clientarea';
        }
        return 'store';
    }
}
