using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using AxCopilot.Services;
using Microsoft.Win32;

namespace AxCopilot.Views;

/// <summary>
/// Phase L2-3: 클립보드 이미지 미리보기 창.
/// 원본 해상도 이미지 표시 + 확대/축소 + 클립보드 복사 + 파일 저장.
/// Shift+Enter (이미지 항목 선택 시) 또는 런처 내 미리보기 액션으로 열립니다.
/// </summary>
public partial class ClipboardImagePreviewWindow : Window
{
    private readonly ClipboardEntry _entry;
    private BitmapSource? _fullImage;
    private double _zoomFactor = 1.0;

    private const double ZoomStep = 0.25;
    private const double MinZoom  = 0.05;
    private const double MaxZoom  = 8.0;

    public ClipboardImagePreviewWindow(ClipboardEntry entry)
    {
        InitializeComponent();
        _entry = entry;
        KeyDown += OnKeyDown;
        Loaded  += OnLoaded;
    }

    // ─── 초기화 ──────────────────────────────────────────────────────────

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        LoadImage();
    }

    private void LoadImage()
    {
        // 원본 해상도 이미지 우선, 없으면 썸네일 폴백
        _fullImage = ClipboardHistoryService.LoadOriginalImage(_entry.OriginalImagePath)
                     ?? _entry.Image;

        if (_fullImage == null)
        {
            SizeLabel.Text = "(이미지 없음)";
            return;
        }

        PreviewImage.Source = _fullImage;
        SizeLabel.Text = $"{_fullImage.PixelWidth} × {_fullImage.PixelHeight} px";

        // 창 레이아웃이 확정된 후 Fit 적용
        Dispatcher.InvokeAsync(FitToWindow, System.Windows.Threading.DispatcherPriority.Loaded);
    }

    // ─── 줌 제어 ─────────────────────────────────────────────────────────

    private void FitToWindow()
    {
        if (_fullImage == null) return;
        var availW = ImageScroll.ActualWidth  - 24;
        var availH = ImageScroll.ActualHeight - 24;
        if (availW <= 0 || availH <= 0) return;

        var scaleX = availW / _fullImage.PixelWidth;
        var scaleY = availH / _fullImage.PixelHeight;
        _zoomFactor = Math.Min(1.0, Math.Min(scaleX, scaleY));
        ApplyZoom();
    }

    private void ApplyZoom()
    {
        ZoomTransform.ScaleX = _zoomFactor;
        ZoomTransform.ScaleY = _zoomFactor;
        ZoomLabel.Text = $"{_zoomFactor * 100:F0}%";
    }

    // ─── 타이틀바 ────────────────────────────────────────────────────────

    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 BtnZoomIn_Click(object sender, MouseButtonEventArgs e)
    {
        _zoomFactor = Math.Min(MaxZoom, Math.Round(_zoomFactor + ZoomStep, 2));
        ApplyZoom();
    }

    private void BtnZoomOut_Click(object sender, MouseButtonEventArgs e)
    {
        _zoomFactor = Math.Max(MinZoom, Math.Round(_zoomFactor - ZoomStep, 2));
        ApplyZoom();
    }

    private void BtnActualSize_Click(object sender, MouseButtonEventArgs e)
    {
        _zoomFactor = 1.0;
        ApplyZoom();
    }

    private void BtnFitToWindow_Click(object sender, MouseButtonEventArgs e)
        => FitToWindow();

    private void BtnCopy_Click(object sender, MouseButtonEventArgs e)
        => CopyToClipboard();

    private void BtnSave_Click(object sender, MouseButtonEventArgs e)
        => SaveToFile();

    // ─── 스크롤 휠 줌 ────────────────────────────────────────────────────

    private void ImageScroll_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) return;
        e.Handled = true;

        var delta = e.Delta > 0 ? ZoomStep : -ZoomStep;
        _zoomFactor = Math.Clamp(Math.Round(_zoomFactor + delta, 2), MinZoom, MaxZoom);
        ApplyZoom();
    }

    // ─── 키보드 단축키 ───────────────────────────────────────────────────

    private void OnKeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.Escape:
                Close();
                e.Handled = true;
                break;

            case Key.Add:
            case Key.OemPlus:
                _zoomFactor = Math.Min(MaxZoom, Math.Round(_zoomFactor + ZoomStep, 2));
                ApplyZoom();
                e.Handled = true;
                break;

            case Key.Subtract:
            case Key.OemMinus:
                _zoomFactor = Math.Max(MinZoom, Math.Round(_zoomFactor - ZoomStep, 2));
                ApplyZoom();
                e.Handled = true;
                break;

            case Key.D0:
            case Key.NumPad0:
                _zoomFactor = 1.0;
                ApplyZoom();
                e.Handled = true;
                break;

            case Key.F:
                FitToWindow();
                e.Handled = true;
                break;

            case Key.C when (Keyboard.Modifiers & ModifierKeys.Control) != 0:
                CopyToClipboard();
                e.Handled = true;
                break;

            case Key.S when (Keyboard.Modifiers & ModifierKeys.Control) != 0:
                SaveToFile();
                e.Handled = true;
                break;
        }
    }

    // ─── 내부 동작 ───────────────────────────────────────────────────────

    private void CopyToClipboard()
    {
        if (_fullImage == null) return;
        try
        {
            Clipboard.SetImage(_fullImage);
            NotificationCenterService.Show("클립보드", "이미지를 클립보드에 복사했습니다.",
                NotificationType.Success);
        }
        catch (Exception ex)
        {
            NotificationCenterService.Show("복사 실패", ex.Message, NotificationType.Error);
        }
    }

    private void SaveToFile()
    {
        if (_fullImage == null) return;

        var dlg = new SaveFileDialog
        {
            Title      = "이미지 저장",
            Filter     = "PNG 이미지 (*.png)|*.png|JPEG 이미지 (*.jpg)|*.jpg|BMP 이미지 (*.bmp)|*.bmp",
            FileName   = $"clipboard_{DateTime.Now:yyyyMMdd_HHmmss}",
            DefaultExt = "png",
        };
        if (dlg.ShowDialog(this) != true) return;

        try
        {
            BitmapEncoder encoder = Path.GetExtension(dlg.FileName).ToLowerInvariant() switch
            {
                ".jpg" or ".jpeg" => new JpegBitmapEncoder { QualityLevel = 95 },
                ".bmp"            => new BmpBitmapEncoder(),
                _                 => new PngBitmapEncoder(),
            };
            encoder.Frames.Add(BitmapFrame.Create(_fullImage));
            using var fs = File.OpenWrite(dlg.FileName);
            encoder.Save(fs);

            NotificationCenterService.Show("저장 완료", Path.GetFileName(dlg.FileName),
                NotificationType.Success);
        }
        catch (Exception ex)
        {
            NotificationCenterService.Show("저장 실패", ex.Message, NotificationType.Error);
        }
    }
}
