using System.Linq;
using ClaudeDo.Data;
using ClaudeDo.Localization;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.ViewModels.Modals.Settings;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClaudeDo.Ui.ViewModels.Modals;

public sealed partial class SettingsModalViewModel : ViewModelBase
{
    private readonly IWorkerClient _worker;

    public GeneralSettingsTabViewModel General { get; }
    public WorktreesSettingsTabViewModel Worktrees { get; }
    public FilesSettingsTabViewModel Files { get; }
    public PrimeClaudeTabViewModel Prime { get; }
    public OnlineInboxSettingsViewModel OnlineInbox { get; }

    [ObservableProperty] private string _validationError = "";
    [ObservableProperty] private bool _isBusy;
    [ObservableProperty] private string _statusMessage = "";

    public Action? CloseAction { get; set; }

    public SettingsModalViewModel(IWorkerClient worker, PrimeClaudeTabViewModel prime,
                                  IOnlineLoginService onlineLoginService,
                                  ILocalizer localizer, AppSettings appSettings)
    {
        _worker = worker;
        General = new GeneralSettingsTabViewModel(localizer, code =>
        {
            appSettings.Language = code;
            appSettings.Save();
        });
        Worktrees = new WorktreesSettingsTabViewModel(worker);
        Files = new FilesSettingsTabViewModel(worker);
        Prime = prime;
        OnlineInbox = new OnlineInboxSettingsViewModel(worker, onlineLoginService);
    }

    public async Task LoadAsync()
    {
        IsBusy = true;
        try
        {
            var dto = await _worker.GetAppSettingsAsync();
            if (dto is not null)
            {
                General.DefaultClaudeInstructions = dto.DefaultClaudeInstructions ?? "";
                General.DefaultModel = dto.DefaultModel ?? "sonnet";
                General.DefaultMaxTurns = dto.DefaultMaxTurns;
                General.DefaultPermissionMode = dto.DefaultPermissionMode ?? "auto";
                General.MaxParallelExecutions = dto.MaxParallelExecutions;
                Worktrees.WorktreeStrategy = dto.WorktreeStrategy ?? "sibling";
                Worktrees.CentralWorktreeRoot = dto.CentralWorktreeRoot;
                Worktrees.WorktreeAutoCleanupEnabled = dto.WorktreeAutoCleanupEnabled;
                Worktrees.WorktreeAutoCleanupDays = dto.WorktreeAutoCleanupDays;
                General.ReportExcludedPaths = string.IsNullOrWhiteSpace(dto.ReportExcludedPaths)
                    ? @"C:\Private"
                    : string.Join(Environment.NewLine,
                        System.Text.Json.JsonSerializer.Deserialize<List<string>>(dto.ReportExcludedPaths) ?? new());
                General.StandupWeekday = dto.StandupWeekday is >= 0 and <= 6 ? dto.StandupWeekday : (int)DayOfWeek.Wednesday;
                Prime.DailyPrepMaxTasks = dto.DailyPrepMaxTasks < 1 ? 5 : dto.DailyPrepMaxTasks;
            }
            else StatusMessage = Loc.T("vm.settingsModal.workerOffline");

            await Prime.LoadAsync();
            await OnlineInbox.LoadAsync();
        }
        finally { IsBusy = false; }
    }

    [RelayCommand]
    private async Task Save()
    {
        var err = General.Validate() ?? Worktrees.Validate() ?? Prime.Validate();
        if (err is not null) { ValidationError = err; return; }
        ValidationError = "";

        IsBusy = true;
        try
        {
            var dto = new AppSettingsDto(
                General.DefaultClaudeInstructions ?? "",
                General.DefaultModel ?? "sonnet",
                General.DefaultMaxTurns,
                General.DefaultPermissionMode ?? "auto",
                General.MaxParallelExecutions,
                Worktrees.WorktreeStrategy ?? "sibling",
                string.IsNullOrWhiteSpace(Worktrees.CentralWorktreeRoot) ? null : Worktrees.CentralWorktreeRoot,
                Worktrees.WorktreeAutoCleanupEnabled,
                Worktrees.WorktreeAutoCleanupDays,
                System.Text.Json.JsonSerializer.Serialize(
                    General.ReportExcludedPaths
                        .Split('\n').Select(l => l.Trim().TrimEnd('\r')).Where(l => l.Length > 0).ToList()),
                General.StandupWeekday,
                Prime.DailyPrepMaxTasks);
            await _worker.UpdateAppSettingsAsync(dto);
            await Prime.SaveAsync();
            CloseAction?.Invoke();
        }
        catch (Exception ex) { StatusMessage = Loc.T("vm.settingsModal.saveFailed", ex.Message); }
        finally { IsBusy = false; }
    }

    [RelayCommand] private void Cancel() => CloseAction?.Invoke();
}
