using ClawdDotNet.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClawdDotNet.Desktop.ViewModels;

public sealed partial class ToolSettingsViewModel : ViewModelBase
{
    public string ToolName { get; }
    public object? SettingsObject { get; }

    // FTP
    [ObservableProperty] private string _ftpHost = "";
    [ObservableProperty] private int _ftpPort = 21;
    [ObservableProperty] private string _ftpUsername = "";
    [ObservableProperty] private string _ftpPassword = "";
    [ObservableProperty] private string _ftpRootPath = "./data/";

    // Mail
    [ObservableProperty] private string _mailUsername = "";
    [ObservableProperty] private string _mailPassword = "";
    [ObservableProperty] private string _mailImapHost = "";
    [ObservableProperty] private int _mailImapPort = 993;
    [ObservableProperty] private string _mailSmtpHost = "";
    [ObservableProperty] private int _mailSmtpPort = 587;
    [ObservableProperty] private string _mailAllowedRecipients = "";

    // Database
    [ObservableProperty] private DatabaseType _dbType = DatabaseType.MySql;
    [ObservableProperty] private string _dbConnectionString = "";
    [ObservableProperty] private DatabaseAccessLevel _dbAccessLevel = DatabaseAccessLevel.ReadOnly;
    [ObservableProperty] private string _dbAllowedTables = "";

    // Telegram
    [ObservableProperty] private string _telegramBotToken = "";
    [ObservableProperty] private string _telegramDefaultChatId = "";
    [ObservableProperty] private string _telegramAllowedChatIds = "";

    // DirectAPI
    [ObservableProperty] private string _directApiDefaultProvider = "twelvedata";
    [ObservableProperty] private int _directApiCacheTtlSeconds = 60;
    [ObservableProperty] private string _directApiTwelveDataKey = "";
    [ObservableProperty] private string _directApiAlphaVantageKey = "";

    // WebFetch
    [ObservableProperty] private string _webFetchAllowedDomains = "";
    [ObservableProperty] private int _webFetchMaxResponseKb = 512;
    [ObservableProperty] private string _webFetchUserAgent = "ClawdDotNet-Agent/1.0";

    // SocialMediaManager
    [ObservableProperty] private string _smmXApiKey = "";
    [ObservableProperty] private string _smmXWatchAccounts = "";
    [ObservableProperty] private string _smmRedditWatchSubreddits = "";
    [ObservableProperty] private int _smmRedditPostLimit = 15;
    [ObservableProperty] private string _smmOpenRouterApiKey = "";
    [ObservableProperty] private string _smmSttModel = "openai/whisper-1";
    [ObservableProperty] private string _smmYoutubeChannels = "";

    // FileRW
    [ObservableProperty] private string _fileRwPersonalAllowedExtensions = ".txt,.json,.md,.html,.js,.css";
    [ObservableProperty] private FileRWAccessLevel _fileRwSharedAccessLevel = FileRWAccessLevel.Denied;
    [ObservableProperty] private string _fileRwSharedAllowedExtensions = ".txt,.json,.md";
    [ObservableProperty] private string _fileRwProtectedPaths = "stocks/";

    public List<DatabaseType> DbTypes { get; } = [DatabaseType.MySql, DatabaseType.Postgres, DatabaseType.MsSql, DatabaseType.MongoDb];
    public List<DatabaseAccessLevel> DbAccessLevels { get; } = [DatabaseAccessLevel.ReadOnly, DatabaseAccessLevel.ReadWrite, DatabaseAccessLevel.Admin];
    public List<FileRWAccessLevel> FileRwAccessLevels { get; } = [FileRWAccessLevel.Denied, FileRWAccessLevel.Read, FileRWAccessLevel.ReadWrite, FileRWAccessLevel.Admin];

    public Dictionary<string, object?>? Result { get; private set; }
    public event Action? CloseRequested;

    public ToolSettingsViewModel() : this("FTP", new()) { }

    public ToolSettingsViewModel(string toolName, Dictionary<string, object?> config)
    {
        ToolName = toolName;
        SettingsObject = ToolSettingsFactory.CreateViewModel(toolName, config);

        switch (SettingsObject)
        {
            case FTPToolSettings ftp:
                FtpHost = ftp.Host;
                FtpPort = ftp.Port;
                FtpUsername = ftp.Username;
                FtpPassword = ftp.Password;
                FtpRootPath = ftp.RootPath;
                break;

            case MailToolSettings mail:
                MailUsername = mail.Username;
                MailPassword = mail.Password;
                MailImapHost = mail.ImapHost;
                MailImapPort = mail.ImapPort;
                MailSmtpHost = mail.SmtpHost;
                MailSmtpPort = mail.SmtpPort;
                MailAllowedRecipients = mail.AllowedRecipients;
                break;

            case DatabaseToolSettings db:
                DbType = db.Type;
                DbConnectionString = db.ConnectionString;
                DbAccessLevel = db.AccessLevel;
                DbAllowedTables = db.AllowedTables;
                break;

            case TelegramToolSettings tg:
                TelegramBotToken = tg.BotToken;
                TelegramDefaultChatId = tg.DefaultChatId;
                TelegramAllowedChatIds = tg.AllowedChatIds;
                break;

            case DirectAPIToolSettings dapi:
                DirectApiDefaultProvider = dapi.DefaultProvider;
                DirectApiCacheTtlSeconds = dapi.CacheTtlSeconds;
                DirectApiTwelveDataKey = dapi.TwelveDataKey;
                DirectApiAlphaVantageKey = dapi.AlphaVantageKey;
                break;

            case WebFetchToolSettings wf:
                WebFetchAllowedDomains = wf.AllowedDomains;
                WebFetchMaxResponseKb = wf.MaxResponseKb;
                WebFetchUserAgent = wf.UserAgent;
                break;

            case SocialMediaManagerToolSettings smm:
                SmmXApiKey = smm.XApiKey;
                SmmXWatchAccounts = smm.XWatchAccounts;
                SmmRedditWatchSubreddits = smm.RedditWatchSubreddits;
                SmmRedditPostLimit = smm.RedditPostLimit;
                SmmOpenRouterApiKey = smm.OpenRouterApiKey;
                SmmSttModel = smm.STTModel;
                SmmYoutubeChannels = smm.YoutubeChannels;
                break;

            case FileRWToolSettings frw:
                FileRwPersonalAllowedExtensions = frw.PersonalAllowedExtensions;
                FileRwSharedAccessLevel = frw.SharedAccessLevel;
                FileRwSharedAllowedExtensions = frw.SharedAllowedExtensions;
                FileRwProtectedPaths = frw.ProtectedPaths;
                break;
        }
    }

    [RelayCommand]
    private void Confirm()
    {
        switch (SettingsObject)
        {
            case FTPToolSettings ftp:
                ftp.Host = FtpHost;
                ftp.Port = FtpPort;
                ftp.Username = FtpUsername;
                ftp.Password = FtpPassword;
                ftp.RootPath = FtpRootPath;
                break;

            case MailToolSettings mail:
                mail.Username = MailUsername;
                mail.Password = MailPassword;
                mail.ImapHost = MailImapHost;
                mail.ImapPort = MailImapPort;
                mail.SmtpHost = MailSmtpHost;
                mail.SmtpPort = MailSmtpPort;
                mail.AllowedRecipients = MailAllowedRecipients;
                break;

            case DatabaseToolSettings db:
                db.Type = DbType;
                db.ConnectionString = DbConnectionString;
                db.AccessLevel = DbAccessLevel;
                db.AllowedTables = DbAllowedTables;
                break;

            case TelegramToolSettings tg:
                tg.BotToken = TelegramBotToken;
                tg.DefaultChatId = TelegramDefaultChatId;
                tg.AllowedChatIds = TelegramAllowedChatIds;
                break;

            case DirectAPIToolSettings dapi:
                dapi.DefaultProvider = DirectApiDefaultProvider;
                dapi.CacheTtlSeconds = DirectApiCacheTtlSeconds;
                dapi.TwelveDataKey = DirectApiTwelveDataKey;
                dapi.AlphaVantageKey = DirectApiAlphaVantageKey;
                break;

            case WebFetchToolSettings wf:
                wf.AllowedDomains = WebFetchAllowedDomains;
                wf.MaxResponseKb = WebFetchMaxResponseKb;
                wf.UserAgent = WebFetchUserAgent;
                break;

            case SocialMediaManagerToolSettings smm:
                smm.XApiKey = SmmXApiKey;
                smm.XWatchAccounts = SmmXWatchAccounts;
                smm.RedditWatchSubreddits = SmmRedditWatchSubreddits;
                smm.RedditPostLimit = SmmRedditPostLimit;
                smm.OpenRouterApiKey = SmmOpenRouterApiKey;
                smm.STTModel = SmmSttModel;
                smm.YoutubeChannels = SmmYoutubeChannels;
                break;

            case FileRWToolSettings frw:
                frw.PersonalAllowedExtensions = FileRwPersonalAllowedExtensions;
                frw.SharedAccessLevel = FileRwSharedAccessLevel;
                frw.SharedAllowedExtensions = FileRwSharedAllowedExtensions;
                frw.ProtectedPaths = FileRwProtectedPaths;
                break;
        }

        Result = ToolSettingsFactory.ToConfig(ToolName, SettingsObject) ?? new();
        CloseRequested?.Invoke();
    }

    [RelayCommand]
    private void Cancel()
    {
        Result = null;
        CloseRequested?.Invoke();
    }
}
