<?php

declare(strict_types=1);

namespace Inside\DESK\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Inside\Authentication\Models\User;
use Inside\Content\Facades\ContentHelper;
use Inside\Content\Models\Contents\Alerts;
use Inside\Content\Models\Contents\Users;
use Inside\DESK\Contracts\DeskStatistics;
use Inside\DESK\Contracts\UrlSigner;
use Inside\DESK\Exports\AlertsDeskStatisticsExport;
use Inside\DESK\Exports\AlertViewsDeskStatisticsExport;
use Inside\DESK\Models\AlertStatistic;
use Inside\Permission\Facades\Permission;
use Inside\Statistics\Listeners\NotifyUserOfCompletedStatisticExport;

class AlertsDeskStatisticsController extends Controller
{
    public const TRANSPARENT_PIXEL = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';

    public function index(Request $request, DeskStatistics $deskStatistics): JsonResponse
    {
        $search = $request->query->getAlnum('query') ?: null;
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

        return response()->json($deskStatistics->getAlertsStatistics($search, $filters));
    }

    public function export(Request $request): JsonResponse
    {
        /** @var User $currentUser */
        $currentUser = Auth::user();
        $search = $request->query->getAlnum('query') ?: null;
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

        $excelPath = 'statistics/desk_alerts_'.now('Europe/Paris')->format('Y_m_d_His').'_export.xls';

        (new AlertsDeskStatisticsExport($search, $filters, $currentUser->langcode))
            ->queue($excelPath, 'protected')
            ->chain([
                new NotifyUserOfCompletedStatisticExport($request->user(), $excelPath, 'protected'),
            ])
            ->allOnQueue(get_low_priority_queue_name());


        return response()->json(['success' => true]);
    }

    public function clicked(string $alertUuid, string $userUuid, Request $request, UrlSigner $urlSigner): RedirectResponse
    {
        if (! $urlSigner->hasValidSignature($request)) {
            Log::error('Invalid signature for alert (clicked)', [
                'alert_uuid' => $alertUuid,
                'user_uuid' => $userUuid,
                'signature' => $request->get('signature'),
                'app_key' => config('app.key'),
            ]);
        }

        $user = Users::find($userUuid);
        $alert = Permission::withoutAllowedScope(fn () => Alerts::find($alertUuid));

        if ($alert instanceof Alerts && $user instanceof Users) {
            AlertStatistic::create([
                'statistic_type' => AlertStatistic::TYPE_CLICKED,
                'alert_uuid' => $alert->uuid,
                'user_uuid' => $user->uuid,
            ]);
        }

        return redirect('/');
    }

    public function viewed(string $alertUuid, string $userUuid, Request $request, UrlSigner $urlSigner): Response
    {
        if (! $urlSigner->hasValidSignature($request)) {
            Log::error('Invalid signature for alert (viewed)', [
                'alert_uuid' => $alertUuid,
                'user_uuid' => $userUuid,
                'signature' => $request->get('signature'),
                'app_key' => config('app.key'),
            ]);
        }

        $user = Users::find($userUuid);
        $alert = Permission::withoutAllowedScope(fn () => Alerts::find($alertUuid));

        if ($alert instanceof Alerts && $user instanceof Users) {
            AlertStatistic::firstOrCreate([
                'statistic_type' => AlertStatistic::TYPE_VIEWED,
                'alert_uuid' => $alert->uuid,
                'user_uuid' => $user->uuid,
            ]);
        }

        return response(base64_decode(self::TRANSPARENT_PIXEL))
            ->header('Content-Type', 'image/png');
    }

    public function views(string $alertUuid, Request $request, DeskStatistics $deskStatistics): JsonResponse
    {
        $search = $request->query->get('query') ?: null;
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

        return response()->json($deskStatistics->getAlertViews($alertUuid, $search, $filters));
    }

    public function viewsExport(string $alertUuid, Request $request): JsonResponse
    {
        /** @var User $user */
        $user = Auth::user();

        $search = $request->query->get('query') ?: null;
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

        $excelPath = 'statistics/desk_alert_views_'.now('Europe/Paris')->format('Y_m_d_His').'_export.xls';

        (new AlertViewsDeskStatisticsExport($alertUuid, $search, $filters, $user->langcode))
            ->queue($excelPath, 'protected')
            ->chain([
                new NotifyUserOfCompletedStatisticExport($request->user(), $excelPath, 'protected'),
            ])
            ->allOnQueue(get_low_priority_queue_name());


        return response()->json(['success' => true]);
    }
}
