using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using AxCopilot.Models;
using AxCopilot.Services;
using Microsoft.Win32;

namespace AxCopilot.Views;

public partial class ScheduleEditorWindow : Window
{
    private readonly SettingsService _settings;
    private readonly ScheduleEntry?  _editing;  // null = 새 스케줄

    private string _triggerType         = "daily";
    private string _actionType          = "app";
    private bool   _enabled             = true;
    private bool   _conditionMustRun    = true;

    // 요일 버튼 → Border 참조
    private Border[] _dayBtns = null!;

    public ScheduleEditorWindow(ScheduleEntry? entry, SettingsService settings)
    {
        InitializeComponent();
        _settings = settings;
        _editing  = entry;

        _dayBtns = new[] { BtnSun, BtnMon, BtnTue, BtnWed, BtnThu, BtnFri, BtnSat };

        Loaded += OnLoaded;
    }

    // ─── 초기화 ─────────────────────────────────────────────────────────────
    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        // 다크 테마 색상
        var dimBg  = TryFindResource("ItemBackground")  as Brush ?? new SolidColorBrush(Color.FromRgb(0x25, 0x26, 0x37));
        var accent = TryFindResource("AccentColor")      as Brush ?? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC));
        var border = TryFindResource("BorderColor")      as Brush ?? new SolidColorBrush(Color.FromRgb(0x2E, 0x2F, 0x4A));

        // 요일 버튼 기본 색
        foreach (var b in _dayBtns)
        {
            b.Background   = dimBg;
            b.BorderBrush  = border;
            b.BorderThickness = new Thickness(1);
            if (b.Child is TextBlock tb)
                tb.Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
        }

        if (_editing != null)
            LoadFromEntry(_editing);
        else
            SetTriggerUi("daily");

        SetActionUi(_actionType);
        UpdateToggleUi(_enabled);
        SetConditionModeUi(_conditionMustRun);
    }

    private void LoadFromEntry(ScheduleEntry e)
    {
        NameBox.Text    = e.Name;
        TimeBox.Text    = e.TriggerTime;
        _enabled        = e.Enabled;
        _triggerType    = e.TriggerType;
        _actionType     = e.ActionType;

        if (e.TriggerDate != null)
            DateBox.Text = e.TriggerDate;

        SetTriggerUi(e.TriggerType);

        // 요일 복원
        foreach (var b in _dayBtns)
        {
            if (int.TryParse(b.Tag?.ToString(), out var day) && e.WeekDays.Contains(day))
                SetDaySelected(b, true);
        }

        if (e.ActionType == "app")
        {
            AppPathBox.Text  = e.ActionTarget;
            AppArgsBox.Text  = e.ActionArgs ?? "";
        }
        else
        {
            NotifMsgBox.Text = e.ActionTarget;
        }

        // 조건 복원
        ConditionProcessBox.Text = e.ConditionProcess ?? "";
        _conditionMustRun        = e.ConditionProcessMustRun;
        SetConditionModeUi(_conditionMustRun);
    }

    // ─── 트리거 유형 ─────────────────────────────────────────────────────────
    private void TriggerType_Click(object sender, MouseButtonEventArgs e)
    {
        if (sender is Border b && b.Tag is string tag)
            SetTriggerUi(tag);
    }

    private void SetTriggerUi(string type)
    {
        _triggerType = type;

        var accent = TryFindResource("AccentColor")   as Brush ?? Brushes.Blue;
        var dimBg  = TryFindResource("ItemBackground") as Brush ?? Brushes.DimGray;
        var secFg  = TryFindResource("SecondaryText")  as Brush ?? Brushes.Gray;
        var white  = Brushes.White;

        // 버튼 배경·텍스트 색 초기화
        void SetBtn(Border btn, TextBlock txt, bool active)
        {
            btn.Background = active ? accent : dimBg;
            txt.Foreground = active ? white : secFg;
        }

        SetBtn(BtnDaily,    TxtDaily,    type == "daily");
        SetBtn(BtnWeekdays, TxtWeekdays, type == "weekdays");
        SetBtn(BtnWeekly,   TxtWeekly,   type == "weekly");
        SetBtn(BtnOnce,     TxtOnce,     type == "once");

        // 요일 패널 / 날짜 패널 표시
        WeekDaysPanel.Visibility = type == "weekly" ? Visibility.Visible   : Visibility.Collapsed;
        DatePanel.Visibility     = type == "once"   ? Visibility.Visible   : Visibility.Collapsed;

        // once 기본값
        if (type == "once" && string.IsNullOrWhiteSpace(DateBox.Text))
            DateBox.Text = DateTime.Now.AddDays(1).ToString("yyyy-MM-dd");
    }

    // ─── 요일 선택 ──────────────────────────────────────────────────────────
    private void WeekDay_Click(object sender, MouseButtonEventArgs e)
    {
        if (sender is not Border btn) return;
        var accent   = TryFindResource("AccentColor")   as Brush ?? Brushes.Blue;
        var dimBg    = TryFindResource("ItemBackground") as Brush ?? Brushes.DimGray;
        bool current = btn.Background == accent;
        SetDaySelected(btn, !current);
    }

    private void SetDaySelected(Border btn, bool selected)
    {
        var accent = TryFindResource("AccentColor")   as Brush ?? Brushes.Blue;
        var dimBg  = TryFindResource("ItemBackground") as Brush ?? Brushes.DimGray;
        var secFg  = TryFindResource("SecondaryText")  as Brush ?? Brushes.Gray;

        btn.Background = selected ? accent : dimBg;
        if (btn.Child is TextBlock tb)
            tb.Foreground = selected ? Brushes.White : secFg;
    }

    private List<int> GetSelectedDays()
    {
        var accent = TryFindResource("AccentColor") as Brush ?? Brushes.Blue;
        var list   = new List<int>();
        foreach (var b in _dayBtns)
        {
            if (b.Background == accent && int.TryParse(b.Tag?.ToString(), out var day))
                list.Add(day);
        }
        return list;
    }

    // ─── 액션 유형 ──────────────────────────────────────────────────────────
    private void ActionType_Click(object sender, MouseButtonEventArgs e)
    {
        if (sender is Border b && b.Tag is string tag)
            SetActionUi(tag);
    }

    private void SetActionUi(string type)
    {
        _actionType = type;

        var accent = TryFindResource("AccentColor")   as Brush ?? Brushes.Blue;
        var dimBg  = TryFindResource("ItemBackground") as Brush ?? Brushes.DimGray;
        var secFg  = TryFindResource("SecondaryText")  as Brush ?? Brushes.Gray;
        var white  = Brushes.White;

        bool isApp = type == "app";

        BtnActionApp.Background  = isApp  ? accent : dimBg;
        BtnActionNotif.Background = !isApp ? accent : dimBg;

        TxtActionApp.Foreground  = isApp  ? white : secFg;
        TxtActionNotif.Foreground = !isApp ? white : secFg;

        // 아이콘 TextBlock은 StackPanel의 첫 번째 자식
        if (BtnActionApp.Child  is StackPanel spApp  && spApp.Children.Count  > 0)
            ((TextBlock)spApp.Children[0]).Foreground  = isApp  ? white : secFg;
        if (BtnActionNotif.Child is StackPanel spNotif && spNotif.Children.Count > 0)
            ((TextBlock)spNotif.Children[0]).Foreground = !isApp ? white : secFg;

        AppPathPanel.Visibility = isApp  ? Visibility.Visible   : Visibility.Collapsed;
        NotifPanel.Visibility   = !isApp ? Visibility.Visible   : Visibility.Collapsed;
    }

    // ─── 앱 찾아보기 ─────────────────────────────────────────────────────────
    private void BtnBrowseApp_Click(object sender, MouseButtonEventArgs e)
    {
        var dlg = new OpenFileDialog
        {
            Title  = "실행 파일 선택",
            Filter = "실행 파일|*.exe;*.bat;*.cmd;*.lnk;*.ps1|모든 파일|*.*"
        };
        if (dlg.ShowDialog(this) == true)
            AppPathBox.Text = dlg.FileName;
    }

    // ─── 조건 모드 (L6-4) ───────────────────────────────────────────────────
    private void ConditionMode_Click(object sender, MouseButtonEventArgs e)
    {
        if (sender is Border b && b.Tag is string tag)
            SetConditionModeUi(tag == "run");
    }

    private void SetConditionModeUi(bool mustRun)
    {
        _conditionMustRun = mustRun;

        var accent = TryFindResource("AccentColor")    as Brush ?? Brushes.Blue;
        var dimBg  = TryFindResource("ItemBackground") as Brush ?? Brushes.DimGray;
        var secFg  = TryFindResource("SecondaryText")  as Brush ?? Brushes.Gray;

        BtnCondRun.Background    = mustRun  ? accent : dimBg;
        BtnCondNotRun.Background = !mustRun ? accent : dimBg;
        TxtCondRun.Foreground    = mustRun  ? Brushes.White : secFg;
        TxtCondNotRun.Foreground = !mustRun ? Brushes.White : secFg;
    }

    // ─── 활성화 토글 ─────────────────────────────────────────────────────────
    private void EnabledToggle_Click(object sender, MouseButtonEventArgs e)
    {
        _enabled = !_enabled;
        UpdateToggleUi(_enabled);
    }

    private void UpdateToggleUi(bool enabled)
    {
        var accent = TryFindResource("AccentColor") as Brush
                     ?? new SolidColorBrush(Color.FromRgb(0x4B, 0x5E, 0xFC));
        var off    = new SolidColorBrush(Color.FromRgb(0x3A, 0x3B, 0x5A));

        EnabledToggle.Background = enabled ? accent : off;

        // 썸 위치 애니메이션
        var da = new DoubleAnimation(
            enabled ? 1.0 : -1.0,   // 실제 HorizontalAlignment·Margin으로 처리
            TimeSpan.FromMilliseconds(150));

        EnabledThumb.HorizontalAlignment = enabled ? HorizontalAlignment.Right : HorizontalAlignment.Left;
        EnabledThumb.Margin = enabled ? new Thickness(0, 0, 2, 0) : new Thickness(2, 0, 0, 0);
    }

    // ─── 저장 ────────────────────────────────────────────────────────────────
    private void BtnSave_Click(object sender, MouseButtonEventArgs e)
    {
        var name = NameBox.Text.Trim();
        if (string.IsNullOrWhiteSpace(name))
        {
            MessageBox.Show("스케줄 이름을 입력하세요.", "저장 오류",
                MessageBoxButton.OK, MessageBoxImage.Warning);
            return;
        }

        var timeStr = TimeBox.Text.Trim();
        if (!TimeSpan.TryParseExact(timeStr, new[] { @"hh\:mm", @"h\:mm" },
                System.Globalization.CultureInfo.InvariantCulture, out _))
        {
            MessageBox.Show("실행 시각을 HH:mm 형식으로 입력하세요. (예: 09:00)",
                "저장 오류", MessageBoxButton.OK, MessageBoxImage.Warning);
            return;
        }

        if (_triggerType == "once")
        {
            var dateStr = DateBox.Text.Trim();
            if (!DateTime.TryParse(dateStr, out _))
            {
                MessageBox.Show("실행 날짜를 yyyy-MM-dd 형식으로 입력하세요.",
                    "저장 오류", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
        }

        if (_actionType == "app" && string.IsNullOrWhiteSpace(AppPathBox.Text))
        {
            MessageBox.Show("실행할 앱 경로를 입력하세요.", "저장 오류",
                MessageBoxButton.OK, MessageBoxImage.Warning);
            return;
        }

        // 기존 항목 편집 or 신규 생성
        var entry = _editing ?? new ScheduleEntry();

        entry.Name        = name;
        entry.Enabled     = _enabled;
        entry.TriggerType = _triggerType;
        entry.TriggerTime = timeStr;
        entry.WeekDays    = _triggerType == "weekly" ? GetSelectedDays() : new List<int>();
        entry.TriggerDate = _triggerType == "once"   ? DateBox.Text.Trim() : null;
        entry.ActionType  = _actionType;
        entry.ActionTarget = _actionType == "app"
            ? AppPathBox.Text.Trim()
            : NotifMsgBox.Text.Trim();
        entry.ActionArgs  = _actionType == "app" ? AppArgsBox.Text.Trim() : "";

        // 조건 저장 (L6-4)
        entry.ConditionProcess        = ConditionProcessBox.Text.Trim();
        entry.ConditionProcessMustRun = _conditionMustRun;

        var schedules = _settings.Settings.Schedules;

        if (_editing == null)
            schedules.Add(entry);
        // 편집 모드: 이미 리스트 내 참조이므로 별도 추가 불필요

        _settings.Save();
        NotificationService.Notify("AX Copilot", $"스케줄 '{entry.Name}' 저장됨");
        Close();
    }

    // ─── 윈도우 컨트롤 ──────────────────────────────────────────────────────
    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();
}
