using MainShell.Common;
using MainShell.Hardware;
using MainShell.Log;
using MainShell.PageCalib.OriginCalib.Model;
using MainShell.PageCalib.OriginCalib.Service;
using Stylet;
using System;
using System.Threading.Tasks;
using System.Windows;

namespace MainShell.PageCalib.OriginCalib.ViewModel
{
    public class AvoidanceAxisViewModel : PropertyChangedBase
    {
        private readonly HardwareManager _hardware;
        private readonly OriginCalibrationMotionService _motionService;
        private readonly AvoidanceAxisItem _item;
        private readonly Action<AvoidanceAxisViewModel> _removeCallback;
        private bool _canTeach = true;

        private const string DialogCaption = "原点标定";

        public AvoidanceAxisItem Item => _item;

        public string AxisName
        {
            get { return _item.AxisName; }
            set { _item.AxisName = value; NotifyOfPropertyChange(nameof(AxisName)); }
        }

        public double Position
        {
            get { return _item.Position; }
            set { _item.Position = value; NotifyOfPropertyChange(nameof(Position)); }
        }

        public bool CanTeach
        {
            get { return _canTeach; }
            set { SetAndNotify(ref _canTeach, value); }
        }

        public AvoidanceAxisViewModel(AvoidanceAxisItem item, HardwareManager hardware, OriginCalibrationMotionService motionService, Action<AvoidanceAxisViewModel> removeCallback)
        {
            _item = item ?? throw new ArgumentNullException(nameof(item));
            _hardware = hardware ?? throw new ArgumentNullException(nameof(hardware));
            _motionService = motionService ?? throw new ArgumentNullException(nameof(motionService));
            _removeCallback = removeCallback;
        }

        public void TeachPosition()
        {
            try
            {
                if (_hardware.AxesDic != null && _hardware.AxesDic.ContainsKey(AxisName))
                {
                    Position = Math.Round(_hardware.AxesDic[AxisName].State.ActualPos, 3);
                    string.Format("原点标定避让轴“{0}”示教位置成功：{1}", AxisName, Position).LogInfo();
                }
                else
                {
                    string.Format("原点标定示教避让位置时未找到轴“{0}”。", AxisName).LogSysError();
                    LocalizedMessageBox.ShowFormat(MessageKey.OriginCalibAxisNotFound, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning, AxisName);
                }
            }
            catch (Exception ex)
            {
                string.Format("原点标定读取轴“{0}”位置失败：{1}", AxisName, ex.Message).LogSysError();
                LocalizedMessageBox.ShowFormat(MessageKey.OriginCalibReadPositionFailed, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message);
            }
        }

        public async Task MoveToPosition()
        {
            try
            {
                if (_hardware.AxesDic != null && _hardware.AxesDic.ContainsKey(AxisName))
                {
                    await _motionService.MoveAxisAsync(AxisName, Position);
                }
                else
                {
                    string.Format("原点标定移动避让轴时未找到轴“{0}”。", AxisName).LogSysError();
                    LocalizedMessageBox.ShowFormat(MessageKey.OriginCalibAxisNotFound, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning, AxisName);
                }
            }
            catch (Exception ex)
            {
                string.Format("原点标定移动避让轴“{0}”失败：{1}", AxisName, ex.Message).LogSysError();
                LocalizedMessageBox.ShowFormat(MessageKey.OriginCalibMoveFailed, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message);
            }
        }

        public void Remove()
        {
            try
            {
                if (_removeCallback != null)
                {
                    string.Format("原点标定正在删除避让轴“{0}”。", AxisName).LogInfo();
                    _removeCallback(this);
                }
            }
            catch (Exception ex)
            {
                string.Format("原点标定删除避让轴“{0}”失败：{1}", AxisName, ex.Message).LogSysError();
                LocalizedMessageBox.ShowFormat(MessageKey.OriginCalibDeleteAxisFailed, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message);
            }
        }
    }
}