/* 
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information 
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC. 
 */

using System.Net;

using SendGrid;
using SendGrid.Helpers.Mail;

using DXLib.Log;

namespace DXLib.Email;

/*
 * Provides static utility methods for sending an email via either local app (Apple/Google Mail) or cloud provider
 * (SendGrid). Also provides functionality for email address validation.
 */
public static class DXEmail
{
	/* Constants */

	// Send modes
	public const string LocalMode = "local";
	public const string CloudMode = "cloud";

	// Result codes
	public enum Result
	{
		Success,

		Error,
		ErrorUnsupported
	};

	// SendGrid API key
	private const string SendGridKey = "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";

	/* Methods */

	// Determines if specified result was successful
	public static bool IsSuccess( Result result )
	{
		return result == Result.Success;
	}

	// Asynchronously sends email given specified configuration
	public static async Task<Result> Send( DXEmailConfig config )
	{
		// Native app (Apple/Google Mail)
		if ( config.IsLocal )
		{
			return await SendLocal( config );
		}

		// Cloud based (SendGrid)
		return await SendCloud( config );
	}

    // Asynchronously sends email via local app (Apple/Google Mail)
    public static async Task<Result> SendLocal( DXEmailConfig config )
	{
		try
		{
			// Configure
			EmailMessage message = new()
			{
				To = null,				
				Subject = config.Subject,
				Body = config.Body
			};

			// Optionally add attachment
			if ( config.HasAttachment )
			{
				string path = Path.Combine( FileSystem.CacheDirectory, config.FileName );

				// Write file to disk (raw bytes NOT base64)
				await File.WriteAllBytesAsync( path, config.FileRaw );

				// Attach file to email
				EmailAttachment attachment = new( path, config.FileType );
				message.Attachments?.Add( attachment );
			}

			// Block for native app send (MUST fully qualify)
			await Microsoft.Maui.ApplicationModel.Communication.Email.Default.ComposeAsync( message );

			// Success
			return Result.Success;
		}
		// Email not supported
		catch ( FeatureNotSupportedException ex )
		{
			DXLog.Exception( "email.unsupported", ex );

			return Result.ErrorUnsupported;
		}
		// Other error
		catch ( Exception ex )
		{
			DXLog.Exception( "email", ex );

			return Result.Error;
		}
	}

	// Asynchronously sends email via cloud provider (SendGrid)
	public static async Task<Result> SendCloud( DXEmailConfig config )
	{
		try
		{
			// Configure SendGrid
			SendGridClient client = new( SendGridKey );
			SendGridMessage msg = new();

			// From:
			msg.SetFrom( config.FromAddress, config.FromName );

			// To: (group)
			if ( config.IsGroup )
			{
				for ( int i = 0; i < config.ToAddresses.Count; i++ )
				{
					string toAddress = config.ToAddresses[i];
					string toName = config.ToNames?[i];

					msg.AddTo( toAddress, toName );
				}
			}
			// To: (single)
			else
			{
				msg.AddTo( config.ToAddress, config.ToName );
			}

			// Configure dynamic template
			msg.SetTemplateId( config.TemplateId );
			msg.SetTemplateData( config.TemplateData );

			// Optional file attachment
			if ( config.HasAttachment )
			{
				Attachment attachment = new()
				{
					Content = config.FileData,
					Filename = config.FileName,
					Type = config.FileType,
					Disposition = "attachment"
				};

				msg.AddAttachment( attachment );
			}

			// Async send
			Response response = await client.SendEmailAsync( msg );

			HttpStatusCode status = response.StatusCode;

			// Error
			if ( status != HttpStatusCode.Accepted )
			{
				DXLog.Exception( "email.status", null, (int)status );

				return Result.Error;
			}

			// Success
			return Result.Success;
		}
		catch ( Exception ex )
		{
			DXLog.Exception( "email", ex );

			return Result.Error;
		}
	}
}

//
