<?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\DB;
use Illuminate\Support\Facades\Log;
use Inside\Authentication\Models\User;
use Inside\Content\Facades\ContentHelper;
use Inside\DESK\Contracts\DeskStatistics;
use Inside\DESK\Contracts\UrlSigner;
use Inside\DESK\Exports\NewslettersDeskStatisticsExport;
use Inside\DESK\Exports\NewsletterViewsDeskStatisticsExport;
use Inside\DESK\Models\NewsletterStatistic;
use Inside\Statistics\Listeners\NotifyUserOfCompletedStatisticExport;

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

    public function index(Request $request, DeskStatistics $deskStatistics): JsonResponse
    {
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

        return response()->json($deskStatistics->getNewslettersStatistics($filters));
    }

    public function export(Request $request): JsonResponse
    {
        /** @var User $user */
        $user = Auth::user();
        $filters = ContentHelper::extractFiltersInputFromRequest($request);

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

        (new NewslettersDeskStatisticsExport($filters, $user->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(int $newsletterDate, string $userUuid, Request $request, UrlSigner $urlSigner): RedirectResponse
    {
        if (! $urlSigner->hasValidSignature($request)) {
            Log::error('Invalid signature for newsletter (clicked)', [
                'newsletter_date' => $newsletterDate,
                'user_uuid' => $userUuid,
                'signature' => $request->get('signature'),
                'app_key' => config('app.key'),
            ]);
        }

        $date = date('Y-m-d H:i:s', $newsletterDate);
        if (DB::table('desk_newsletters_sent')->where('date_sent', $date)->where('user_uuid', $userUuid)->exists()) {
            NewsletterStatistic::create([
                'statistic_type' => NewsletterStatistic::TYPE_CLICKED,
                'newsletter_date' => $date,
                'user_uuid' => $userUuid,
            ]);
        }

        $redirect = $request->query('redirect');

        if (! is_string($redirect)) {
            $redirect = '';
        }

        return redirect("/$redirect");
    }

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

        $date = date('Y-m-d H:i:s', $newsletterDate);
        if (DB::table('desk_newsletters_sent')->where('date_sent', $date)->where('user_uuid', $userUuid)->exists()) {
            NewsletterStatistic::firstOrCreate([
                'statistic_type' => NewsletterStatistic::TYPE_VIEWED,
                'newsletter_date' => $date,
                'user_uuid' => $userUuid,
            ]);
        }

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

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

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

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

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

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

        (new NewsletterViewsDeskStatisticsExport($newsletterDate, $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]);
    }
}
