using System;
using System.Collections.Generic;
using System.Windows;

namespace MainShell.Common
{
    /// <summary>
    /// Localization resource helper.
    /// </summary>
    public static class LanguageResourceHelper
    {
        private static readonly IReadOnlyDictionary<MessageKey, string> ResourceKeyMap =
            new Dictionary<MessageKey, string>
            {
                { MessageKey.TitleInfo, "Msg_Title_Info" },
                { MessageKey.TitleWarning, "Msg_Title_Warning" },
                { MessageKey.TitleError, "Msg_Title_Error" },
                { MessageKey.TitleConfirm, "Msg_Title_Confirm" },

                { MessageKey.VisionCameraNotFound, "Msg_Vision_CameraNotFound" },
                { MessageKey.VisionCameraNotOpen, "Msg_Vision_CameraNotOpen" },
                { MessageKey.VisionCameraNotGrabbing, "Msg_Vision_CameraNotGrabbing" },
                { MessageKey.VisionCaptureTimeout, "Msg_Vision_CaptureTimeout" },
                { MessageKey.VisionNoFrameReturned, "Msg_Vision_NoFrameReturned" },
                { MessageKey.VisionSoftTriggerFailed, "Msg_Vision_SoftTriggerFailed" },
                { MessageKey.VisionDriverError, "Msg_Vision_DriverError" },
                { MessageKey.VisionImageIsNull, "Msg_Vision_ImageIsNull" },
                { MessageKey.VisionRequestInvalid, "Msg_Vision_RequestInvalid" },
                { MessageKey.VisionTimeoutInvalid, "Msg_Vision_TimeoutInvalid" },
                { MessageKey.VisionOperationCancelled, "Msg_Vision_OperationCancelled" },
                { MessageKey.VisionTemplatePathEmpty, "Msg_Vision_TemplatePathEmpty" },
                { MessageKey.VisionTemplateRoiInvalid, "Msg_Vision_TemplateRoiInvalid" },
                { MessageKey.VisionTemplateMinScoreInvalid, "Msg_Vision_TemplateMinScoreInvalid" },
                { MessageKey.VisionTemplateAlgorithmNotImplemented, "Msg_Vision_TemplateAlgorithmNotImplemented" },
                { MessageKey.VisionTemplateMatchFailed, "Msg_Vision_TemplateMatchFailed" },
                { MessageKey.VisionCommonAlgorithmNotSupported, "Msg_Vision_CommonAlgorithmNotSupported" },
                { MessageKey.VisionCommonAlgorithmExecutionFailed, "Msg_Vision_CommonAlgorithmExecutionFailed" },
                { MessageKey.VisionChipMapSortInputInvalid, "Msg_Vision_ChipMapSortInputInvalid" },

                { MessageKey.CommonUnknownError, "Msg_Common_UnknownError" },
                { MessageKey.CommonOperationSucceeded, "Msg_Common_OperationSucceeded" },
                { MessageKey.CommonOperationFailed, "Msg_Common_OperationFailed" },
                { MessageKey.CommonSaveSucceeded, "Msg_Common_SaveSucceeded" },
                { MessageKey.CommonSaveFailed, "Msg_Common_SaveFailed" },
                { MessageKey.AxisSoftLimitSaveConfirm, "Msg_AxisSoftLimit_SaveConfirm" },
                { MessageKey.AxisSoftLimitSaveFailedWithReason, "Msg_AxisSoftLimit_SaveFailedWithReason" },
                { MessageKey.AxisSoftLimitLoadFailedWithReason, "Msg_AxisSoftLimit_LoadFailedWithReason" },
                { MessageKey.AxisSoftLimitRangeInvalid, "Msg_AxisSoftLimit_RangeInvalid" },
                { MessageKey.AxisSoftLimitApplySucceeded, "Msg_AxisSoftLimit_ApplySucceeded" },
                { MessageKey.AxisSoftLimitApplyFailedWithReason, "Msg_AxisSoftLimit_ApplyFailedWithReason" },
                { MessageKey.AxisSoftLimitApplyAllSucceeded, "Msg_AxisSoftLimit_ApplyAllSucceeded" },
                { MessageKey.AxisSoftLimitApplyAllFailedWithReason, "Msg_AxisSoftLimit_ApplyAllFailedWithReason" },
                { MessageKey.AxisSoftLimitNoAxisData, "Msg_AxisSoftLimit_NoAxisData" },
                { MessageKey.AxisSoftLimitSelectedAxisRequired, "Msg_AxisSoftLimit_SelectedAxisRequired" },
                { MessageKey.CommonDeleteConfirm, "Msg_Common_DeleteConfirm" },
                { MessageKey.CommonExitConfirm, "Msg_Common_ExitConfirm" },

                { MessageKey.DeviceNotInitialized, "Msg_Device_NotInitialized" },
                { MessageKey.DeviceBusy, "Msg_Device_Busy" },
                { MessageKey.DeviceDisconnected, "Msg_Device_Disconnected" },
                { MessageKey.DeviceHomeRequired, "Msg_Device_HomeRequired" },

                { MessageKey.ParamInvalid, "Msg_Param_Invalid" },
                { MessageKey.ParamEmpty, "Msg_Param_Empty" },
                { MessageKey.ParamOutOfRange, "Msg_Param_OutOfRange" },

                { MessageKey.StartProcessConfirm, "Msg_Process_StartConfirm" },
                { MessageKey.StartProcessFailed, "Msg_Process_StartFailed" },
                { MessageKey.StopProcessConfirm, "Msg_Process_StopConfirm" },
                { MessageKey.StopProcessFailed, "Msg_Process_StopFailed" },

                { MessageKey.ProcessFailed, "Msg_Process_Failed" },
                { MessageKey.ProcessFailedWithReason, "Msg_Process_FailedWithReason" },
                { MessageKey.ProcessStepFailedWithReason, "Msg_Process_StepFailedWithReason" },
                { MessageKey.ProcessSubstratePositionFailedWithReason, "Msg_Process_SubstratePositionFailedWithReason" },
                { MessageKey.ProcessSubstratePositionRecipeNotLoaded, "Msg_Process_SubstratePositionRecipeNotLoaded" },
                { MessageKey.ProcessSubstratePositionMarkParameterMissing, "Msg_Process_SubstratePositionMarkParameterMissing" },
                { MessageKey.ProcessSubstratePositionNoEnabledMarks, "Msg_Process_SubstratePositionNoEnabledMarks" },
                { MessageKey.ProcessSubstratePositionAlignmentFailedWithReason, "Msg_Process_SubstratePositionAlignmentFailedWithReason" },
                { MessageKey.ProcessDiePositionFailedWithReason, "Msg_Process_DiePositionFailedWithReason" },
                { MessageKey.ProcessDiePositionRecipeNotLoaded, "Msg_Process_DiePositionRecipeNotLoaded" },
                { MessageKey.ProcessDiePositionCoordinateGenerationMissing, "Msg_Process_DiePositionCoordinateGenerationMissing" },
                { MessageKey.ProcessDiePositionWaferInfoMissing, "Msg_Process_DiePositionWaferInfoMissing" },
                { MessageKey.ProcessSubstrateHeightMeasureFailedWithReason, "Msg_Process_SubstrateHeightMeasureFailedWithReason" },
                { MessageKey.ProcessSubstrateHeightMeasureRecipeNotLoaded, "Msg_Process_SubstrateHeightMeasureRecipeNotLoaded" },
                { MessageKey.ProcessSubstrateHeightMeasureSettingMissing, "Msg_Process_SubstrateHeightMeasureSettingMissing" },
                { MessageKey.ProcessSubstrateHeightMeasureNoPoints, "Msg_Process_SubstrateHeightMeasureNoPoints" },
                { MessageKey.ProcessSubstrateHeightMeasurePointPositionInvalid, "Msg_Process_SubstrateHeightMeasurePointPositionInvalid" },
                { MessageKey.NeedleCalibrationLoadFailed, "Msg_NeedleCalibration_LoadFailed" },
                { MessageKey.NeedleCalibrationTouchCountMustGreaterThanZero, "Msg_NeedleCalibration_TouchCountMustGreaterThanZero" },
                { MessageKey.NeedleCalibrationCompleted, "Msg_NeedleCalibration_Completed" },
                { MessageKey.NeedleCalibrationStopped, "Msg_NeedleCalibration_Stopped" },
                { MessageKey.NeedleCalibrationCanceled, "Msg_NeedleCalibration_Canceled" },
                { MessageKey.OriginCalibOpenVisionTemplateFailed, "Msg_OriginCalib_OpenVisionTemplateFailed" },
                { MessageKey.OriginCalibAxisNotFound, "Msg_OriginCalib_AxisNotFound" },
                { MessageKey.OriginCalibReadPositionFailed, "Msg_OriginCalib_ReadPositionFailed" },
                { MessageKey.OriginCalibMoveFailed, "Msg_OriginCalib_MoveFailed" },
                { MessageKey.OriginCalibDeleteAxisFailed, "Msg_OriginCalib_DeleteAxisFailed" },
                { MessageKey.OriginCalibDeleteAxisDuringCalibration, "Msg_OriginCalib_DeleteAxisDuringCalibration" },
                { MessageKey.OriginCalibCalibrationCanceled, "Msg_OriginCalib_CalibrationCanceled" },
                { MessageKey.OriginCalibCalibrationFailed, "Msg_OriginCalib_CalibrationFailed" },
                { MessageKey.OriginCalibConfigSaved, "Msg_OriginCalib_ConfigSaved" },
                { MessageKey.OriginCalibConfigSaveFailed, "Msg_OriginCalib_ConfigSaveFailed" },
                { MessageKey.OriginCalibNoCalibratedModules, "Msg_OriginCalib_NoCalibratedModules" },
                { MessageKey.OriginCalibControllerWriteCompleted, "Msg_OriginCalib_ControllerWriteCompleted" },
                { MessageKey.OriginCalibControllerWriteNotReady, "Msg_OriginCalib_ControllerWriteNotReady" },
                { MessageKey.OriginCalibControllerWritePartialSuccess, "Msg_OriginCalib_ControllerWritePartialSuccess" },
                { MessageKey.OriginCalibControllerWriteNotImplemented, "Msg_OriginCalib_ControllerWriteNotImplemented" },
                { MessageKey.PidNoProfileSelected, "Msg_Pid_NoProfileSelected" },
                { MessageKey.PidNoFilteringParameterSelected, "Msg_Pid_NoFilteringParameterSelected" },
                { MessageKey.PidReadSucceeded, "Msg_Pid_ReadSucceeded" },
                { MessageKey.PidReadFailed, "Msg_Pid_ReadFailed" },
                { MessageKey.PidWriteSucceeded, "Msg_Pid_WriteSucceeded" },
                { MessageKey.PidWriteFailed, "Msg_Pid_WriteFailed" },

                { MessageKey.DieRecheckSelectedPointRequired, "Msg_DieRecheck_SelectedPointRequired" },
                { MessageKey.DieRecheckMoveDeviceUnavailable, "Msg_DieRecheck_MoveDeviceUnavailable" },
                { MessageKey.DieRecheckStatusOk, "Msg_DieRecheck_StatusOk" },
                { MessageKey.DieRecheckStatusMissingBond, "Msg_DieRecheck_StatusMissingBond" },
                { MessageKey.DieRecheckStatusXExceeded, "Msg_DieRecheck_StatusXExceeded" },
                { MessageKey.DieRecheckStatusYExceeded, "Msg_DieRecheck_StatusYExceeded" }
            };

        public static string GetString(MessageKey messageKey)
        {
            return GetString(messageKey, messageKey.ToString());
        }

        public static string GetString(MessageKey messageKey, string fallback)
        {
            if (messageKey == MessageKey.None)
            {
                return fallback ?? string.Empty;
            }

            if (!ResourceKeyMap.TryGetValue(messageKey, out var resourceKey))
            {
                return fallback ?? messageKey.ToString();
            }

            var application = Application.Current;
            if (application == null)
            {
                return fallback ?? resourceKey;
            }

            var resource = application.TryFindResource(resourceKey);
            if (resource is string text && !string.IsNullOrWhiteSpace(text))
            {
                return text;
            }

            return fallback ?? resourceKey;
        }

        public static string Format(MessageKey messageKey, params object[] args)
        {
            var format = GetString(messageKey);
            return args == null || args.Length == 0
                ? format
                : string.Format(format, args);
        }
    }
}