<?php

namespace App\Http\Controllers\Api\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Photobooth\PhotoboothSendUploaderDownloadRequest;
use App\Http\Resources\Tenant\PhotoboothStatusResource;
use App\Mail\PhotoboothUploaderDownload;
use App\Models\Event;
use App\Models\PhotoboothSetting;
use App\Services\Photobooth\PhotoboothProvisioner;
use App\Support\LocaleConfig;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\ValidationException;

class PhotoboothController extends Controller
{
    public function __construct(private readonly PhotoboothProvisioner $provisioner) {}

    public function show(Request $request, Event $event): PhotoboothStatusResource
    {
        $this->assertEventBelongsToTenant($request, $event);

        return $this->resource($event);
    }

    public function enable(Request $request, Event $event): JsonResponse
    {
        $this->assertEventBelongsToTenant($request, $event);

        $event->loadMissing('tenant');
        $mode = $this->resolveMode($request);
        $updated = $mode === 'sparkbooth'
            ? $this->provisioner->enableSparkbooth($event)
            : $this->provisioner->enable($event);

        return response()->json([
            'message' => __('Photobooth-Zugang aktiviert.'),
            'data' => $this->resource($updated),
        ]);
    }

    public function rotate(Request $request, Event $event): JsonResponse
    {
        $this->assertEventBelongsToTenant($request, $event);

        $event->loadMissing('tenant');
        $mode = $this->resolveMode($request);
        $updated = $mode === 'sparkbooth'
            ? $this->provisioner->rotateSparkbooth($event)
            : $this->provisioner->rotate($event);

        return response()->json([
            'message' => __('Zugangsdaten neu generiert.'),
            'data' => $this->resource($updated),
        ]);
    }

    public function disable(Request $request, Event $event): JsonResponse
    {
        $this->assertEventBelongsToTenant($request, $event);

        $event->loadMissing('tenant');
        $mode = $this->resolveMode($request);
        $updated = $mode === 'sparkbooth'
            ? $this->provisioner->disableSparkbooth($event)
            : $this->provisioner->disable($event);

        return response()->json([
            'message' => __('Photobooth-Zugang deaktiviert.'),
            'data' => $this->resource($updated),
        ]);
    }

    public function sendUploaderDownloadEmail(PhotoboothSendUploaderDownloadRequest $request, Event $event): JsonResponse
    {
        $this->assertEventBelongsToTenant($request, $event);

        $user = $request->user();

        if (! $user || ! $user->email) {
            throw ValidationException::withMessages([
                'email' => __('No email address is configured for this account.'),
            ]);
        }

        $locale = LocaleConfig::canonicalize($user->preferred_locale ?: app()->getLocale());
        $eventName = $this->resolveEventName($event, $locale);
        $recipientName = $user->fullName ?? $user->name ?? $user->email;

        $mail = (new PhotoboothUploaderDownload(
                recipientName: $recipientName,
                eventName: $eventName,
                links: [
                    'windows' => url('/downloads/PhotoboothUploader-win-x64.exe'),
                    'macos' => url('/downloads/PhotoboothUploader-macos-x64'),
                    'linux' => url('/downloads/PhotoboothUploader-linux-x64'),
                ],
            ))->locale($locale);

        Mail::to($user->email)->queue($mail);

        return response()->json([
            'message' => __('Download links sent via email.'),
        ]);
    }

    protected function resource(Event $event): PhotoboothStatusResource
    {
        return PhotoboothStatusResource::make([
            'event' => $event->fresh('photoboothSetting'),
            'settings' => PhotoboothSetting::current(),
        ]);
    }

    protected function assertEventBelongsToTenant(Request $request, Event $event): void
    {
        $tenantId = (int) $request->attributes->get('tenant_id');

        if ($tenantId !== (int) $event->tenant_id) {
            abort(403, 'Event gehört nicht zu diesem Tenant.');
        }
    }

    protected function resolveMode(Request $request): string
    {
        $mode = strtolower((string) $request->input('mode', $request->input('type', 'ftp')));

        return in_array($mode, ['sparkbooth', 'ftp'], true) ? $mode : 'ftp';
    }

    protected function resolveEventName(Event $event, ?string $locale = null): string
    {
        $name = $event->name;

        if (is_string($name) && trim($name) !== '') {
            return $name;
        }

        if (is_array($name)) {
            $locale = $locale ?: app()->getLocale();
            $localized = $name[$locale] ?? null;

            if (is_string($localized) && trim($localized) !== '') {
                return $localized;
            }

            foreach ($name as $value) {
                if (is_string($value) && trim($value) !== '') {
                    return $value;
                }
            }
        }

        return $event->slug ?: __('emails.photobooth_uploader.event_fallback');
    }
}
