<?php

/**
 * SPDX-License-Identifier: MIT
 * Copyright (c) 2017-2018 Tobias Reich
 * Copyright (c) 2018-2026 LycheeOrg.
 */

namespace App\Providers;

use App\Events\AlbumDeleted;
use App\Events\AlbumRouteCacheUpdated;
use App\Events\AlbumSaved;
use App\Events\Metrics\AlbumDownload;
use App\Events\Metrics\AlbumShared;
use App\Events\Metrics\AlbumVisit;
use App\Events\Metrics\PhotoDownload;
use App\Events\Metrics\PhotoFavourite;
use App\Events\Metrics\PhotoShared;
use App\Events\Metrics\PhotoVisit;
use App\Events\OrderCompleted;
use App\Events\PhotoAdded;
use App\Events\PhotoDeleted;
use App\Events\PhotoMoved;
use App\Events\PhotoSaved;
use App\Events\PhotoWillBeDeleted;
use App\Events\TaggedRouteCacheUpdated;
use App\Listeners\AlbumCacheCleaner;
use App\Listeners\CacheListener;
use App\Listeners\LogQueryTimeout;
use App\Listeners\MetricsListener;
use App\Listeners\OrderCompletedListener;
use App\Listeners\RecomputeAlbumSizeOnAlbumChange;
use App\Listeners\RecomputeAlbumSizeOnPhotoMutation;
use App\Listeners\RecomputeAlbumStatsOnAlbumChange;
use App\Listeners\RecomputeAlbumStatsOnPhotoChange;
use App\Listeners\TaggedRouteCacheCleaner;
use App\Listeners\WebhookListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Cache\Events\CacheHit;
use Illuminate\Cache\Events\CacheMissed;
use Illuminate\Cache\Events\KeyForgotten;
use Illuminate\Cache\Events\KeyWritten;
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use SocialiteProviders\Amazon\AmazonExtendSocialite;
use SocialiteProviders\Apple\AppleExtendSocialite;
use SocialiteProviders\Authelia\AutheliaExtendSocialite;
use SocialiteProviders\Authentik\AuthentikExtendSocialite;
use SocialiteProviders\Facebook\FacebookExtendSocialite;
use SocialiteProviders\GitHub\GitHubExtendSocialite;
use SocialiteProviders\Google\GoogleExtendSocialite;
use SocialiteProviders\Keycloak\KeycloakExtendSocialite;
use SocialiteProviders\Manager\SocialiteWasCalled;
use SocialiteProviders\Microsoft\MicrosoftExtendSocialite;
use SocialiteProviders\Nextcloud\NextcloudExtendSocialite;

class EventServiceProvider extends ServiceProvider
{
	/**
	 * The event listener mappings for the application.
	 *
	 * @var array<string,array<int,string>>
	 */
	protected $listen = [
		Registered::class => [
			// SendEmailVerificationNotification::class,
		],
		SocialiteWasCalled::class => [
			AmazonExtendSocialite::class . '@handle',
			AppleExtendSocialite::class . '@handle',
			AutheliaExtendSocialite::class . '@handle',
			AuthentikExtendSocialite::class . '@handle',
			FacebookExtendSocialite::class . '@handle',
			GitHubExtendSocialite::class . '@handle',
			GoogleExtendSocialite::class . '@handle',
			// Mastodon is provided directly.
			MicrosoftExtendSocialite::class . '@handle',
			NextcloudExtendSocialite::class . '@handle',
			KeycloakExtendSocialite::class . '@handle',
		],
	];

	/**
	 * Register any events for your application.
	 *
	 * @return void
	 */
	public function boot(): void
	{
		Event::listen(CacheHit::class, CacheListener::class . '@handle');
		Event::listen(CacheMissed::class, CacheListener::class . '@handle');
		Event::listen(KeyForgotten::class, CacheListener::class . '@handle');
		Event::listen(KeyWritten::class, CacheListener::class . '@handle');

		Event::listen(AlbumRouteCacheUpdated::class, AlbumCacheCleaner::class . '@handle');
		Event::listen(TaggedRouteCacheUpdated::class, TaggedRouteCacheCleaner::class . '@handle');

		// Log slow/timeout SQL queries when DB_LOG_SQL is enabled
		// @codeCoverageIgnoreStart
		if (config('database.db_log_sql', false) === true) {
			Event::listen(QueryExecuted::class, LogQueryTimeout::class . '@handle');
		}
		// @codeCoverageIgnoreEnd

		Event::listen(AlbumDownload::class, MetricsListener::class . '@handle');
		Event::listen(AlbumShared::class, MetricsListener::class . '@handle');
		Event::listen(AlbumVisit::class, MetricsListener::class . '@handle');
		Event::listen(PhotoDownload::class, MetricsListener::class . '@handle');
		Event::listen(PhotoFavourite::class, MetricsListener::class . '@handle');
		Event::listen(PhotoShared::class, MetricsListener::class . '@handle');
		Event::listen(PhotoVisit::class, MetricsListener::class . '@handle');

		Event::listen(OrderCompleted::class, OrderCompletedListener::class . '@handle');

		Event::listen(PhotoSaved::class, RecomputeAlbumStatsOnPhotoChange::class . '@handlePhotoSaved');
		Event::listen(PhotoDeleted::class, RecomputeAlbumStatsOnPhotoChange::class . '@handlePhotoDeleted');
		Event::listen(AlbumSaved::class, RecomputeAlbumStatsOnAlbumChange::class . '@handleAlbumSaved');
		Event::listen(AlbumDeleted::class, RecomputeAlbumStatsOnAlbumChange::class . '@handleAlbumDeleted');

		Event::listen(PhotoSaved::class, RecomputeAlbumSizeOnPhotoMutation::class . '@handlePhotoSaved');
		Event::listen(PhotoDeleted::class, RecomputeAlbumSizeOnPhotoMutation::class . '@handlePhotoDeleted');
		Event::listen(AlbumSaved::class, RecomputeAlbumSizeOnAlbumChange::class . '@handleAlbumSaved');
		Event::listen(AlbumDeleted::class, RecomputeAlbumSizeOnAlbumChange::class . '@handleAlbumDeleted');

		// Webhook dispatch for photo lifecycle events
		Event::listen(PhotoAdded::class, WebhookListener::class . '@handlePhotoAdded');
		Event::listen(PhotoMoved::class, WebhookListener::class . '@handlePhotoMoved');
		Event::listen(PhotoWillBeDeleted::class, WebhookListener::class . '@handlePhotoWillBeDeleted');
	}
}
