<?php

declare(strict_types=1);

namespace TechnoArtisan\FilamentCms\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
use TechnoArtisan\FilamentCms\Enums\ContactRequest as ContactRequestEnum;
use TechnoArtisan\FilamentCms\Http\Requests\ContactRequest as FormContactRequest;
use TechnoArtisan\FilamentCms\Models\ContactRequest;
use TechnoArtisan\FilamentCms\Models\ContactRequestError;
use TechnoArtisan\FilamentCms\Services\TrackUserPageViews;
use Throwable;

use function redirect;
use function url;

class ContactController extends Controller
{
    public function __construct(private readonly TrackUserPageViews $trackUserPageViews)
    {
    }

    public function store(FormContactRequest $request): RedirectResponse
    {
        $this->trackUserPageViews->process($request);

        $validated                = $request->validated();
        $validatedData['request'] = ContactRequestEnum::from($validated['request']);

        try {
            ContactRequest::create(
                array_merge(
                    $validated,
                    [
                        'ip'           => $this->getRealIpAddr($request),
                        'user_agent'   => $request->userAgent(),
                        'session_id'   => $request->session()->getId(),
                        'session_data' => $request->session()->get('utd'),
                    ]
                )
            );

            $result = 'success';
        } catch (Throwable $exception) {
            try {
                ContactRequestError::create([
                    'session_id'     => $request->session()->getId(),
                    'exception'      => [
                        'message' => $exception->getMessage(),
                        'code'    => $exception->getCode(),
                        'file'    => $exception->getFile(),
                        'trace'   => $exception->getTrace(),
                    ],
                    'request'        => [
                        'get'    => $request->query(),
                        'post'   => $request->post(),
                        'server' => $request->server(),
                    ],
                    'session'        => $request->session(),
                    'validated_data' => $validatedData ?? null,
                ]);
            } catch (Throwable $exception) {
                try {
                    Log::error(
                        $exception->getMessage() . ' [' . $exception->getCode() . ']: ' . $exception->getFile()
                    );
                } catch (Throwable $exception) {
                } // no more options left to catch an error
            }
            $result = 'error';
        }

        return redirect()->intended(url()->current())->with($result, fcms__('content-contact.' . $result));
    }

    private function getRealIpAddr(FormContactRequest $request): string
    {
        return $request->server('HTTP_CLIENT_IP')
            ?? $request->server("HTTP_CF_CONNECTING_IP") # when behind cloudflare
            ?? $request->server('HTTP_X_FORWARDED')
            ?? $request->server('HTTP_X_FORWARDED_FOR')
            ?? $request->server('HTTP_FORWARDED')
            ?? $request->server('HTTP_FORWARDED_FOR')
            ?? $request->server('REMOTE_ADDR')
            ?? '0.0.0.0';
    }
}
