package Slim::Plugin::AudioScrobbler::Settings;

# Logitech Media Server Copyright 2001-2024 Logitech.
# Lyrion Music Server Copyright 2024 Lyrion Community.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2.

use strict;
use base qw(Slim::Web::Settings);

use Digest::MD5 qw(md5_hex);

use Slim::Utils::Log;
use Slim::Utils::Prefs;

use Slim::Plugin::AudioScrobbler::API::LastFM;
use Slim::Plugin::AudioScrobbler::API::ListenBrainz;

my $prefs = preferences('plugin.audioscrobbler');
my $log   = logger('plugin.audioscrobbler');

sub name {
	return Slim::Web::HTTP::CSRF->protectName('PLUGIN_AUDIOSCROBBLER_MODULE_NAME');
}

sub page {
	return Slim::Web::HTTP::CSRF->protectURI('plugins/AudioScrobbler/settings/basic.html');
}

sub prefs {
	return ( $prefs, qw(accounts enable_scrobbling include_radio ignoreTitles ignoreGenres ignoreArtists ignoreAlbums) );
}

sub handler {
	my ($class, $client, $params, $callback, @args) = @_;

	if ( $params->{saveSettings} ) {

		# Save existing accounts
		$params->{pref_accounts} = $prefs->get('accounts') || [];

		# delete accounts
		if ( my $delete = $params->{delete} ) {
			if ( !ref $delete ) {
				$delete = [ $delete ];
			}

			my $newlist = [];
			ACCOUNT:
			for my $account ( @{ $params->{pref_accounts} } ) {
				for my $todelete ( @{$delete} ) {
					if ( $todelete eq $account->{username} || (!$account->{username} && $todelete eq $account->{api_url}) ) {
						main::DEBUGLOG && $log->debug( "Deleting account $todelete" );
						next ACCOUNT;
					}
				}

				push @{$newlist}, $account;
			}

			$params->{pref_accounts} = $newlist;
		}

		my $service = $params->{pref_api_type} || 'lastfm';
		my $serviceHandler;

		# Last.fm Password (MD5)
		if ( $params->{pref_password} && $service eq 'lastfm' ) {
			$params->{pref_password} = md5_hex( $params->{pref_password} );

			$serviceHandler = 'Slim::Plugin::AudioScrobbler::API::LastFM';
		}
		elsif ( $params->{pref_password} && $service eq 'listenbrainz' ) {
			# ListenBrainz API key
			$params->{pref_password} = $params->{pref_password};

			$serviceHandler = 'Slim::Plugin::AudioScrobbler::API::ListenBrainz';
		}

		# If the user added a username/password, we need to verify their info
		if ($serviceHandler) {
			eval "require $serviceHandler";
			if ($@) {
				$log->error("Failed to load service handler $serviceHandler: $@");
			}
			else {
				$serviceHandler->validate( {
					username => $params->{pref_username},
					password => $params->{pref_password},
					api_type => $params->{pref_api_type},
					api_url  => $params->{pref_api_url},
					cb       => sub {
						my $msg = shift;

						push @{ $params->{pref_accounts} }, {
							username    => $params->{pref_username} || $params->{pref_api_url},
							password    => $params->{pref_password},
							api_type    => $params->{pref_api_type},
							api_url     => $params->{pref_api_url},
						};

						if ( main::DEBUGLOG && $log->is_debug ) {
							$log->debug( "Saving Audioscrobbler accounts: " . Data::Dump::dump( $params->{pref_accounts} ) );
						}

						my $body = $class->SUPER::handler( $client, $params );

						if ( $params->{AJAX} ) {
							$params->{warning} = $msg;
							$params->{validated}->{valid} = 1;
						}
						else {
							$params->{warning} .= $msg . '<br/>';
						}

						$callback->( $client, $params, $body, @args );
					},
					ecb      => sub {
						# Callback for any errors
						my $error = shift;

						if ( main::DEBUGLOG && $log->is_debug ) {
							$log->debug( "Error saving Audioscrobbler account: " . Data::Dump::dump( $error ) );
						}

						if ( $params->{AJAX} ) {
							$params->{warning} = $error;
							$params->{validated}->{valid} = 0;
						}
						else {
							$params->{warning} .= $error . '<br/>';
						}

						delete $params->{pref_username};
						delete $params->{pref_password};
						delete $params->{pref_api_url};
						delete $params->{pref_api_type};

						my $body = $class->SUPER::handler( $client, $params );
						$callback->( $client, $params, $body, @args );
					},
				} );

				return;
			}
		}
	}

	return $class->SUPER::handler( $client, $params );
}

1;