using System.Collections;
using System.ComponentModel;
using song_of_the_day;

public class SignalIntegration
{
    public static SignalIntegration? Instance;

    public SignalIntegration(string uri, int port, string phoneNumber)
    {
        var http = new HttpClient()
        {
            BaseAddress = new Uri(uri + ":" + port)
        };
        apiClient = new song_of_the_day.swaggerClient(http);
        apiClient.BaseUrl = "";
        this.phoneNumber = phoneNumber;
    }

    private song_of_the_day.swaggerClient apiClient;

    private string phoneNumber;

    public async Task ListGroupsAsync()
    {
        try
        {
            ICollection<song_of_the_day.GroupEntry> groupEntries = await apiClient.GroupsAllAsync(this.phoneNumber);
            foreach (var group in groupEntries)
            {
                Console.WriteLine($"{group.Name} {group.Id}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception (ListGroupsAsync): " + ex.Message);
        }
    }

    public async Task SendMessageToGroupAsync(string message)
    {
        try
        {
            SendMessageV2 data = new SendMessageV2();
            data.Recipients = new List<string>();
            data.Recipients.Add(AppConfiguration.Instance.SignalGroupId);
            data.Message = message;
            data.Text_mode = SendMessageV2Text_mode.Styled;
            data.Number = AppConfiguration.Instance.HostPhoneNumber;
            var response = await apiClient.Send2Async(data);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception (SendMessageToGroupAsync): " + ex.Message);
        }
    }

    public async Task SendMessageToUserAsync(string message, string userId)
    {
        try
        {
            SendMessageV2 data = new SendMessageV2();
            data.Recipients = new List<string>();
            data.Recipients.Add(userId);
            data.Message = (AppConfiguration.Instance.UseBotTag ? "**[Proggy]**\n" : "") + message;
            data.Text_mode = SendMessageV2Text_mode.Styled;
            data.Number = AppConfiguration.Instance.HostPhoneNumber;
            var response = await apiClient.Send2Async(data);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception (SendMessageToUserAsync): " + ex.Message);
        }
    }

    public async Task IntroduceUserAsync(User user)
    {
        await this.SendMessageToUserAsync("Hi, my name is Proggy and I am your friendly neighborhood *Song of the Day* bot!", user.SignalMemberId);
        await this.SendMessageToUserAsync("You are receiving this message because you have been invited to a *Song of the Day* community group.", user.SignalMemberId);
        await this.SendMessageToUserAsync("In that community group I will pick a person at random each day at 8 AM and encourage them to share a song with the rest of the community.", user.SignalMemberId);
        if (AppConfiguration.Instance.UseBotTag)
        {
            await this.SendMessageToUserAsync("You can always see which messages are sent by me rather than the community host by the **[Proggy]** tag at the beginning of the message", user.SignalMemberId);
        }
        await this.SendMessageToUserAsync($"Not right now, but eventually you will be able to see more details about your community at {AppConfiguration.Instance.WebUIBaseURL}.", user.SignalMemberId);
        await this.SendMessageToUserAsync($"""You can navigate to {AppConfiguration.Instance.WebUIBaseURL + (AppConfiguration.Instance.WebUIBaseURL.EndsWith("/") ? "" : "/")}User/{user.UserId} to set your preferred display name for me to use.""", user.SignalMemberId);
        await this.SendMessageToUserAsync($"Now have fun and enjoy being a part of this community!", user.SignalMemberId);
    }

    public async Task<ICollection<string>> GetMemberListAsync()
    {
        try
        {
            var response = await apiClient.Groups2Async(AppConfiguration.Instance.HostPhoneNumber, AppConfiguration.Instance.SignalGroupId);
            return response.Members;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception (GetMemberListAsync): " + ex.Message);
        }
        return new List<string>();
    }

    public async Task<ListContactsResponse> GetContactAsync(string memberId)
    {
        try
        {
            var allIdentities = await apiClient.ContactsAllAsync(AppConfiguration.Instance.HostPhoneNumber);
            var identityCandidates = allIdentities.Where(u => u.Number == memberId || u.Uuid == memberId);
            var identity = identityCandidates.SingleOrDefault();
            if (identity == null)
            {
                throw new Exception($"Could not determine identity for memberId '{memberId}'!");
            }
            return identity;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception (GetContactAsync): " + ex.Message);
            return new ListContactsResponse();
        }
    }
}