using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using AxCopilot.Models;
using AxCopilot.Services;

namespace AxCopilot.Views;

/// <summary>
/// L5-4: 앱 세션 편집기.
/// 세션 이름, 앱 목록(경로 + 라벨 + 스냅 위치)을 편집하여 저장합니다.
/// </summary>
public partial class SessionEditorWindow : Window
{
    private readonly SettingsService _settings;
    private readonly AppSession?     _original;   // 편집 모드 원본 (새 세션이면 null)
    private readonly List<AppRowUi>  _rows = new();

    // 스냅 팝업 대상 행
    private AppRowUi? _snapTargetRow;

    // 사용 가능한 스냅 위치 목록 (키 → 표시명)
    private static readonly (string Key, string Label)[] SnapOptions =
    [
        ("full",    "전체화면"),
        ("left",    "왼쪽 절반"),
        ("right",   "오른쪽 절반"),
        ("tl",      "좌상단 1/4"),
        ("tr",      "우상단 1/4"),
        ("bl",      "좌하단 1/4"),
        ("br",      "우하단 1/4"),
        ("center",  "중앙 80%"),
        ("third-l", "좌측 1/3"),
        ("third-c", "중앙 1/3"),
        ("third-r", "우측 1/3"),
        ("two3-l",  "좌측 2/3"),
        ("two3-r",  "우측 2/3"),
        ("none",    "스냅 없음"),
    ];

    // ──────────────────────────────────────────────────────────────────────
    /// <summary>
    /// 세션 편집기를 엽니다.
    /// </summary>
    /// <param name="session">편집할 기존 세션. null이면 새로 만들기 모드.</param>
    /// <param name="settings">설정 서비스.</param>
    public SessionEditorWindow(AppSession? session, SettingsService settings)
    {
        InitializeComponent();
        _settings = settings;
        _original = session;

        BuildSnapPopup();
        LoadSession(session);
    }

    /// <summary>새 세션 모드일 때 기본 이름을 설정합니다.</summary>
    public string InitialName
    {
        set { if (_original == null) NameBox.Text = value; }
    }

    // ─── 초기화 ───────────────────────────────────────────────────────────
    private void LoadSession(AppSession? session)
    {
        if (session == null)
        {
            NameBox.Text = "새 세션";
            DescBox.Text = "";
        }
        else
        {
            NameBox.Text = session.Name;
            DescBox.Text = session.Description;
            foreach (var app in session.Apps)
                AddRow(app.Path, app.Label, app.SnapPosition, app.Arguments, app.DelayMs);
        }

        RefreshEmptyState();
    }

    private void BuildSnapPopup()
    {
        var panel = new StackPanel { Margin = new Thickness(0) };

        foreach (var (key, label) in SnapOptions)
        {
            var keyCapture = key;
            var border = new Border
            {
                CornerRadius = new CornerRadius(4),
                Padding      = new Thickness(10, 5, 10, 5),
                Cursor       = Cursors.Hand
            };

            border.MouseEnter += (_, _) =>
                border.Background = new SolidColorBrush(Color.FromArgb(0x28, 0xFF, 0xFF, 0xFF));
            border.MouseLeave += (_, _) =>
                border.Background = Brushes.Transparent;

            var stack = new StackPanel { Orientation = Orientation.Horizontal };
            stack.Children.Add(new TextBlock
            {
                Text            = keyCapture,
                FontFamily      = new FontFamily("Cascadia Code, Consolas"),
                FontSize        = 11,
                Foreground      = TryFindResource("AccentColor") as Brush ?? Brushes.DodgerBlue,
                VerticalAlignment = VerticalAlignment.Center,
                MinWidth        = 68,
            });
            stack.Children.Add(new TextBlock
            {
                Text            = label,
                FontSize        = 11,
                Foreground      = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
                VerticalAlignment = VerticalAlignment.Center,
            });
            border.Child = stack;

            border.MouseLeftButtonUp += (_, _) =>
            {
                if (_snapTargetRow != null)
                {
                    _snapTargetRow.SnapPosition = keyCapture;
                    _snapTargetRow.UpdateSnapLabel();
                }
                SnapPickerPopup.IsOpen = false;
            };

            panel.Children.Add(border);
        }

        SnapOptionsList.Content = panel;
    }

    // ─── 앱 행 추가 ───────────────────────────────────────────────────────
    private void AddRow(string path = "", string label = "", string snap = "full",
                        string args = "", int delayMs = 0)
    {
        var row = new AppRowUi(path, label, snap, args, delayMs);
        _rows.Add(row);

        var rowGrid = BuildRowGrid(row);
        AppListPanel.Children.Add(rowGrid);
        RefreshEmptyState();
    }

    private Grid BuildRowGrid(AppRowUi row)
    {
        var grid = new Grid { Margin = new Thickness(14, 2, 4, 2) };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(108) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });

        // 경로 TextBox
        var pathBox = new TextBox
        {
            Text                = row.Path,
            FontSize            = 11,
            Foreground          = TryFindResource("PrimaryText") as Brush ?? Brushes.White,
            Background          = TryFindResource("LauncherBackground") as Brush ?? Brushes.Black,
            BorderBrush         = TryFindResource("BorderColor") as Brush ?? Brushes.Gray,
            BorderThickness     = new Thickness(1),
            Padding             = new Thickness(6, 4, 6, 4),
            VerticalContentAlignment = VerticalAlignment.Center,
            ToolTip             = "앱 실행 파일 경로",
            Margin              = new Thickness(0, 0, 4, 0),
        };
        pathBox.TextChanged += (_, _) => row.Path = pathBox.Text;
        Grid.SetColumn(pathBox, 0);

        // 라벨 TextBox
        var labelBox = new TextBox
        {
            Text                = row.Label,
            FontSize            = 11,
            Foreground          = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
            Background          = TryFindResource("LauncherBackground") as Brush ?? Brushes.Black,
            BorderBrush         = TryFindResource("BorderColor") as Brush ?? Brushes.Gray,
            BorderThickness     = new Thickness(1),
            Padding             = new Thickness(6, 4, 6, 4),
            VerticalContentAlignment = VerticalAlignment.Center,
            ToolTip             = "표시 이름 (선택)",
            Margin              = new Thickness(0, 0, 4, 0),
        };
        labelBox.TextChanged += (_, _) => row.Label = labelBox.Text;
        Grid.SetColumn(labelBox, 1);

        // 스냅 선택 Border (클릭 시 팝업)
        var snapBtn = new Border
        {
            CornerRadius = new CornerRadius(4),
            BorderBrush  = TryFindResource("BorderColor") as Brush ?? Brushes.Gray,
            BorderThickness = new Thickness(1),
            Padding      = new Thickness(6, 4, 6, 4),
            Cursor       = Cursors.Hand,
            Margin       = new Thickness(0, 0, 4, 0),
            ToolTip      = "스냅 위치 선택",
        };
        snapBtn.MouseEnter += (_, _) =>
            snapBtn.Background = new SolidColorBrush(Color.FromArgb(0x18, 0xFF, 0xFF, 0xFF));
        snapBtn.MouseLeave += (_, _) =>
            snapBtn.Background = Brushes.Transparent;

        var snapLabel = new TextBlock
        {
            FontFamily = new FontFamily("Cascadia Code, Consolas"),
            FontSize   = 10,
            Foreground = TryFindResource("AccentColor") as Brush ?? Brushes.DodgerBlue,
            VerticalAlignment = VerticalAlignment.Center,
            TextTrimming = TextTrimming.CharacterEllipsis,
        };
        snapBtn.Child = snapLabel;

        // AppRowUi가 라벨 TextBlock을 참조할 수 있도록 저장
        row.SnapLabelRef    = snapLabel;
        row.SnapButtonRef   = snapBtn;
        row.UpdateSnapLabel();

        snapBtn.MouseLeftButtonUp += (sender, e) =>
        {
            _snapTargetRow             = row;
            SnapPickerPopup.PlacementTarget = (FrameworkElement)sender;
            SnapPickerPopup.IsOpen     = true;
            e.Handled = true;
        };
        Grid.SetColumn(snapBtn, 2);

        // 삭제 버튼
        var delBtn = new Border
        {
            Width        = 24,
            Height       = 24,
            CornerRadius = new CornerRadius(4),
            Cursor       = Cursors.Hand,
            ToolTip      = "이 앱 제거",
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center,
        };
        delBtn.MouseEnter += (_, _) =>
            delBtn.Background = new SolidColorBrush(Color.FromArgb(0x30, 0xEF, 0x53, 0x50));
        delBtn.MouseLeave += (_, _) =>
            delBtn.Background = Brushes.Transparent;

        var delIcon = new TextBlock
        {
            Text           = "\uE74D",
            FontFamily     = new FontFamily("Segoe MDL2 Assets"),
            FontSize       = 12,
            Foreground     = new SolidColorBrush(Color.FromRgb(0xEF, 0x53, 0x50)),
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment   = VerticalAlignment.Center,
        };
        delBtn.Child = delIcon;

        delBtn.MouseLeftButtonUp += (_, _) =>
        {
            _rows.Remove(row);
            AppListPanel.Children.Remove(grid);
            RefreshEmptyState();
        };
        Grid.SetColumn(delBtn, 3);

        grid.Children.Add(pathBox);
        grid.Children.Add(labelBox);
        grid.Children.Add(snapBtn);
        grid.Children.Add(delBtn);

        return grid;
    }

    private void RefreshEmptyState()
    {
        EmptyState.Visibility = _rows.Count == 0 ? Visibility.Visible : Visibility.Collapsed;
    }

    // ─── 이벤트 핸들러 ────────────────────────────────────────────────────
    private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed) DragMove();
    }

    private void BtnClose_Click(object sender, MouseButtonEventArgs e) => Close();
    private void BtnCancel_Click(object sender, MouseButtonEventArgs e) => Close();

    private void BtnAddApp_Click(object sender, MouseButtonEventArgs e)
    {
        using var dlg = new System.Windows.Forms.OpenFileDialog
        {
            Title  = "앱 실행 파일 선택",
            Filter = "실행 파일 (*.exe)|*.exe|모든 파일 (*.*)|*.*",
        };
        if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;

        var label = Path.GetFileNameWithoutExtension(dlg.FileName);
        AddRow(dlg.FileName, label, "full");
    }

    private void BtnSave_Click(object sender, MouseButtonEventArgs e)
    {
        var name = NameBox.Text.Trim();
        if (string.IsNullOrWhiteSpace(name))
        {
            NotificationService.Notify("세션 편집기", "세션 이름을 입력하세요.");
            NameBox.Focus();
            return;
        }

        // 빈 경로 행 필터링
        var validApps = _rows
            .Where(r => !string.IsNullOrWhiteSpace(r.Path))
            .Select(r => new SessionApp
            {
                Path         = r.Path.Trim(),
                Arguments    = r.Arguments.Trim(),
                Label        = r.Label.Trim(),
                SnapPosition = r.SnapPosition,
                DelayMs      = r.DelayMs,
            }).ToList();

        var session = new AppSession
        {
            Name        = name,
            Description = DescBox.Text.Trim(),
            Apps        = validApps,
            CreatedAt   = _original?.CreatedAt ?? DateTime.Now,
        };

        // 기존 세션 교체 또는 신규 추가
        if (_original != null)
        {
            var idx = _settings.Settings.AppSessions.IndexOf(_original);
            if (idx >= 0)
                _settings.Settings.AppSessions[idx] = session;
            else
                _settings.Settings.AppSessions.Add(session);
        }
        else
        {
            // 동일 이름 세션이 있으면 교체
            var existing = _settings.Settings.AppSessions
                .FirstOrDefault(s => s.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
            if (existing != null)
                _settings.Settings.AppSessions.Remove(existing);
            _settings.Settings.AppSessions.Add(session);
        }

        _settings.Save();
        NotificationService.Notify("AX Copilot",
            $"세션 '{name}' 저장됨 ({validApps.Count}개 앱)");
        LogService.Info($"세션 저장: {name} ({validApps.Count}개 앱)");
        Close();
    }
}

// ─── 앱 행 UI 모델 ────────────────────────────────────────────────────────────
internal class AppRowUi
{
    public string Path         { get; set; }
    public string Label        { get; set; }
    public string SnapPosition { get; set; }
    public string Arguments    { get; set; }
    public int    DelayMs      { get; set; }

    // UI 참조 (라벨 갱신용)
    internal System.Windows.Controls.TextBlock? SnapLabelRef  { get; set; }
    internal System.Windows.Controls.Border?    SnapButtonRef { get; set; }

    public AppRowUi(string path, string label, string snap, string args, int delayMs)
    {
        Path         = path;
        Label        = label;
        SnapPosition = snap;
        Arguments    = args;
        DelayMs      = delayMs;
    }

    public void UpdateSnapLabel()
    {
        if (SnapLabelRef != null)
            SnapLabelRef.Text = SnapPosition;
    }
}
