using CMSMicroservice.Application.WarehouseCQ.Commands.CreateWarehouse;
using CMSMicroservice.Application.WarehouseCQ.Commands.UpdateWarehouse;
using CMSMicroservice.Application.WarehouseCQ.Commands.DeleteWarehouse;
using CMSMicroservice.Application.WarehouseCQ.Commands.SetDefaultWarehouse;
using CMSMicroservice.Application.WarehouseCQ.Queries.GetWarehouse;
using CMSMicroservice.Application.WarehouseCQ.Queries.GetAllWarehouses;
using CMSMicroservice.Application.InventoryItemCQ.Commands.UpdateInventoryItem;
using CMSMicroservice.Application.InventoryItemCQ.Commands.UpdateInventoryQuantity;
using CMSMicroservice.Application.InventoryItemCQ.Commands.ReserveInventory;
using CMSMicroservice.Application.InventoryItemCQ.Commands.ReleaseReservedInventory;
using CMSMicroservice.Application.InventoryItemCQ.Commands.ReduceInventory;
using CMSMicroservice.Application.InventoryItemCQ.Commands.IncreaseInventory;
using CMSMicroservice.Application.InventoryItemCQ.Queries.GetInventoryItem;
using CMSMicroservice.Application.InventoryItemCQ.Queries.GetInventoryByProduct;
using CMSMicroservice.Application.InventoryItemCQ.Queries.GetAllInventoryItems;
using CMSMicroservice.Application.InventoryItemCQ.Queries.GetLowStockItems;
using CMSMicroservice.Application.StockMovementCQ.Commands.CreateStockMovement;
using CMSMicroservice.Application.StockMovementCQ.Queries.GetStockMovements;
using CMSMicroservice.Application.StockMovementCQ.Queries.GetStockMovementsByInventoryItem;
using CMSMicroservice.Protobuf.Protos.Inventory;
using CMSMicroservice.Domain.Enums;
using Google.Protobuf.WellKnownTypes;
using Mapster;
using DomainStockMovementType = CMSMicroservice.Domain.Enums.StockMovementType;
using ProtoStockMovementType = CMSMicroservice.Protobuf.Protos.Inventory.StockMovementType;
using DomainProductType = CMSMicroservice.Domain.Enums.ProductType;
using ProtoProductType = CMSMicroservice.Protobuf.Protos.Inventory.ProductType;

namespace CMSMicroservice.WebApi.Common.Mappings;

public class InventoryProfile : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        // ==================== Warehouse Mappings ====================
        
        // CreateWarehouse: Proto -> Command
        config.NewConfig<CreateWarehouseRequest, CreateWarehouseCommand>()
            .Map(dest => dest.Name, src => src.Name)
            .Map(dest => dest.Code, src => src.Code)
            .Map(dest => dest.Address, src => src.Address)
            .Map(dest => dest.IsDefault, src => src.IsDefault)
            .Map(dest => dest.IsActive, src => true); // Proto ندارد

        // CreateWarehouse: ResponseDto -> Proto Response
        config.NewConfig<CreateWarehouseResponseDto, CreateWarehouseResponse>()
            .Map(dest => dest.Id, src => src.Id);

        // UpdateWarehouse: Proto -> Command
        config.NewConfig<UpdateWarehouseRequest, UpdateWarehouseCommand>()
            .Map(dest => dest.Id, src => src.Id)
            .Map(dest => dest.Name, src => src.Name)
            .Map(dest => dest.Code, src => src.Code)
            .Map(dest => dest.Address, src => src.Address)
            .Map(dest => dest.IsActive, src => src.IsActive);

        // DeleteWarehouse: Proto -> Command
        config.NewConfig<DeleteWarehouseRequest, DeleteWarehouseCommand>()
            .Map(dest => dest.Id, src => src.Id);

        // SetDefaultWarehouse: Proto -> Command
        config.NewConfig<SetDefaultWarehouseRequest, SetDefaultWarehouseCommand>()
            .Map(dest => dest.Id, src => src.Id);

        // GetWarehouse Query: Proto -> Query
        config.NewConfig<GetWarehouseRequest, GetWarehouseQuery>()
            .MapWith(src => new GetWarehouseQuery(src.Id));

        // GetWarehouse Response: ResponseDto -> Proto (با WarehouseDto)
        config.NewConfig<GetWarehouseResponseDto, GetWarehouseResponse>()
            .Map(dest => dest.Warehouse, src => new WarehouseDto
            {
                Id = src.Id,
                Name = src.Name,
                Code = src.Code,
                Address = src.Address ?? string.Empty,
                IsDefault = src.IsDefault,
                IsActive = src.IsActive,
                Created = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                LastModified = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc))
            });

        // GetAllWarehouses Query: Proto -> Query
        config.NewConfig<GetAllWarehousesRequest, GetAllWarehousesQuery>()
            .MapWith(src => new GetAllWarehousesQuery());

        // GetAllWarehouses Response: ResponseDto -> Proto
        config.NewConfig<GetAllWarehousesResponseDto, GetAllWarehousesResponse>()
            .Map(dest => dest.TotalCount, src => src.TotalCount)
            .AfterMapping((src, dest) =>
            {
                dest.Warehouses.Clear();
                foreach (var warehouse in src.Warehouses)
                {
                    dest.Warehouses.Add(new WarehouseDto
                    {
                        Id = warehouse.Id,
                        Name = warehouse.Name,
                        Code = warehouse.Code,
                        Address = warehouse.Address ?? string.Empty,
                        IsDefault = warehouse.IsDefault,
                        IsActive = warehouse.IsActive,
                        Created = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)),
                        LastModified = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc))
                    });
                }
            });

        // ==================== Inventory Item Query Mappings ====================

        // GetInventoryItem: Proto -> Query
        config.NewConfig<GetInventoryItemRequest, GetInventoryItemQuery>()
            .MapWith(src => new GetInventoryItemQuery(src.Id));

        // GetInventoryItem Response: ResponseDto -> Proto (با InventoryItemDto)
        config.NewConfig<GetInventoryItemResponseDto, GetInventoryItemResponse>()
            .Map(dest => dest.Item, src => MapToInventoryItemDto(src));

        // GetInventoryByProduct: Proto -> Query
        config.NewConfig<GetInventoryByProductRequest, GetInventoryByProductQuery>()
            .Map(dest => dest.ProductId, src => src.ProductId)
            .Map(dest => dest.ProductType, src => MapToDomainProductType(src.ProductType));

        // GetInventoryByProduct Response: ResponseDto -> Proto
        config.NewConfig<GetInventoryByProductResponseDto, GetInventoryByProductResponse>()
            .Map(dest => dest.Item, src => MapToInventoryItemDto(src));

        // GetAllInventoryItems: Proto -> Query
        config.NewConfig<GetAllInventoryItemsRequest, GetAllInventoryItemsQuery>()
            .Map(dest => dest.WarehouseId, src => src.WarehouseId != null ? (long?)src.WarehouseId.Value : null)
            .Map(dest => dest.ProductType, src => src.ProductType != ProtoProductType.Unspecified 
                ? (DomainProductType?)MapToDomainProductType(src.ProductType) : null)
            .Map(dest => dest.SearchTerm, src => src.Search)
            .Map(dest => dest.Skip, src => src.Page > 0 ? (src.Page - 1) * src.PageSize : 0)
            .Map(dest => dest.Take, src => src.PageSize > 0 ? src.PageSize : 50);

        // GetAllInventoryItems Response: ResponseDto -> Proto
        config.NewConfig<GetAllInventoryItemsResponseDto, GetAllInventoryItemsResponse>()
            .Map(dest => dest.TotalCount, src => src.TotalCount)
            .AfterMapping((src, dest) =>
            {
                dest.Items.Clear();
                foreach (var item in src.Items)
                {
                    dest.Items.Add(MapListItemToInventoryItemDto(item));
                }
            });

        // GetLowStockItems: Proto -> Query
        config.NewConfig<GetLowStockItemsRequest, GetLowStockItemsQuery>()
            .Map(dest => dest.WarehouseId, src => src.WarehouseId != null ? (long?)src.WarehouseId.Value : null)
            .Map(dest => dest.Count, src => src.PageSize > 0 ? src.PageSize : 50);

        // GetLowStockItems Response: ResponseDto -> Proto
        config.NewConfig<GetLowStockItemsResponseDto, GetLowStockItemsResponse>()
            .Map(dest => dest.TotalCount, src => src.TotalCount)
            .AfterMapping((src, dest) =>
            {
                dest.Items.Clear();
                foreach (var item in src.Items)
                {
                    dest.Items.Add(MapLowStockItemToInventoryItemDto(item));
                }
            });

        // UpdateInventorySettings: Proto -> UpdateInventoryItemCommand
        config.NewConfig<UpdateInventorySettingsRequest, UpdateInventoryItemCommand>()
            .Map(dest => dest.Id, src => src.Id)
            .Map(dest => dest.MinimumStock, src => (int?)src.LowStockThreshold)
            .Map(dest => dest.MaximumStock, src => (int?)src.MaxStockLevel)
            .Map(dest => dest.ReorderPoint, src => (int?)src.ReorderPoint);

        // ==================== Stock Operation Mappings ====================

        // AddStock: Proto -> IncreaseInventoryCommand
        // نکته: این نیاز به lookup در Service داره چون Proto از ProductId استفاده میکنه
        config.NewConfig<AddStockRequest, IncreaseInventoryCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.ReferenceNumber, src => src.ReferenceNumber)
            .Map(dest => dest.Note, src => src.Note);
        // Id باید در Service تنظیم بشه

        // AdjustStock: Proto -> UpdateInventoryQuantityCommand
        config.NewConfig<AdjustStockRequest, UpdateInventoryQuantityCommand>()
            .Map(dest => dest.NewQuantity, src => src.NewQuantity)
            .Map(dest => dest.Note, src => src.Reason)
            .Map(dest => dest.ReferenceNumber, src => src.ReferenceNumber);
        // Id باید در Service تنظیم بشه

        // ReserveStock: Proto -> ReserveInventoryCommand
        config.NewConfig<ReserveStockRequest, ReserveInventoryCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.OrderId, src => src.OrderId != null ? (long?)src.OrderId.Value : null)
            .Map(dest => dest.DiscountOrderId, src => src.DiscountOrderId != null ? (long?)src.DiscountOrderId.Value : null);
        // Id باید در Service تنظیم بشه

        // ReleaseReservation: Proto -> ReleaseReservedInventoryCommand
        config.NewConfig<ReleaseReservationRequest, ReleaseReservedInventoryCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.OrderId, src => src.OrderId != null ? (long?)src.OrderId.Value : null)
            .Map(dest => dest.DiscountOrderId, src => src.DiscountOrderId != null ? (long?)src.DiscountOrderId.Value : null);
        // Id باید در Service تنظیم بشه

        // ConfirmSale: Proto -> ReduceInventoryCommand
        config.NewConfig<ConfirmSaleRequest, ReduceInventoryCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.OrderId, src => src.OrderId != null ? (long?)src.OrderId.Value : null)
            .Map(dest => dest.DiscountOrderId, src => src.DiscountOrderId != null ? (long?)src.DiscountOrderId.Value : null)
            .Map(dest => dest.FromReserved, src => src.FromReservation);
        // Id باید در Service تنظیم بشه

        // ProcessReturn: Proto -> IncreaseInventoryCommand
        config.NewConfig<ProcessReturnRequest, IncreaseInventoryCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.Note, src => src.Reason);
        // Id باید در Service تنظیم بشه

        // RecordLoss: Proto -> CreateStockMovementCommand
        config.NewConfig<RecordLossRequest, CreateStockMovementCommand>()
            .Map(dest => dest.Quantity, src => src.Quantity)
            .Map(dest => dest.MovementType, src => MapToDomainStockMovementType(src.LossType))
            .Map(dest => dest.Note, src => src.Reason)
            .Map(dest => dest.ReferenceNumber, src => src.ReferenceNumber);
        // InventoryItemId باید در Service تنظیم بشه

        // ==================== Stock Movement Query Mappings ====================

        // GetStockMovements: Proto -> Query
        config.NewConfig<GetStockMovementsRequest, GetStockMovementsQuery>()
            .Map(dest => dest.InventoryItemId, src => src.InventoryItemId != null ? (long?)src.InventoryItemId.Value : null)
            .Map(dest => dest.ProductId, src => src.ProductId != null ? (long?)src.ProductId.Value : null)
            .Map(dest => dest.ProductType, src => src.ProductType != ProtoProductType.Unspecified 
                ? (DomainProductType?)MapToDomainProductType(src.ProductType) : null)
            .Map(dest => dest.MovementType, src => src.MovementType != ProtoStockMovementType.MovementTypeUnspecified 
                ? (DomainStockMovementType?)MapToDomainStockMovementType(src.MovementType) : null)
            .Map(dest => dest.StartDate, src => src.FromDate != null ? (DateTime?)src.FromDate.ToDateTime() : null)
            .Map(dest => dest.EndDate, src => src.ToDate != null ? (DateTime?)src.ToDate.ToDateTime() : null)
            .Map(dest => dest.Skip, src => src.Page > 0 ? (src.Page - 1) * src.PageSize : 0)
            .Map(dest => dest.Take, src => src.PageSize > 0 ? src.PageSize : 50);

        // GetStockMovements Response: ResponseDto -> Proto
        config.NewConfig<GetStockMovementsResponseDto, GetStockMovementsResponse>()
            .Map(dest => dest.TotalCount, src => src.TotalCount)
            .AfterMapping((src, dest) =>
            {
                dest.Movements.Clear();
                foreach (var movement in src.Movements)
                {
                    dest.Movements.Add(MapToStockMovementDto(movement));
                }
            });

        // GetStockMovementsByInventoryItem: Proto -> Query
        config.NewConfig<GetStockMovementsByInventoryItemRequest, GetStockMovementsByInventoryItemQuery>()
            .Map(dest => dest.InventoryItemId, src => src.InventoryItemId)
            .Map(dest => dest.Skip, src => src.Page > 0 ? (src.Page - 1) * src.PageSize : 0)
            .Map(dest => dest.Take, src => src.PageSize > 0 ? src.PageSize : 50);

        // GetStockMovementsByInventoryItem Response: ResponseDto -> Proto
        config.NewConfig<GetStockMovementsByInventoryItemResponseDto, GetStockMovementsByInventoryItemResponse>()
            .Map(dest => dest.TotalCount, src => src.TotalCount)
            .AfterMapping((src, dest) =>
            {
                dest.Movements.Clear();
                foreach (var movement in src.Movements)
                {
                    dest.Movements.Add(MapHistoryToStockMovementDto(movement));
                }
            });
    }

    // ==================== Helper Methods ====================

    private static InventoryItemDto MapToInventoryItemDto(GetInventoryItemResponseDto src)
    {
        return new InventoryItemDto
        {
            Id = src.Id,
            ProductId = src.ProductId,
            DiscountProductId = src.DiscountProductId,
            ProductType = MapToProtoProductType(src.ProductType),
            Quantity = src.Quantity,
            ReservedQuantity = src.ReservedQuantity,
            AvailableQuantity = src.AvailableQuantity,
            LowStockThreshold = src.LowStockThreshold,
            ReorderPoint = 0, // Entity ندارد
            MaxStockLevel = src.MaxStockLevel,
            LastRestockedAt = src.LastRestockedAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastRestockedAt.Value, DateTimeKind.Utc)) 
                : null,
            LastSoldAt = src.LastSoldAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastSoldAt.Value, DateTimeKind.Utc)) 
                : null,
            WarehouseId = src.WarehouseId,
            WarehouseName = src.WarehouseName ?? string.Empty,
            ProductTitle = src.ProductTitle ?? string.Empty,
            ProductPrice = src.ProductPrice.HasValue ? (long)src.ProductPrice.Value : 0,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(src.Created, DateTimeKind.Utc))
        };
    }

    private static InventoryItemDto MapToInventoryItemDto(GetInventoryByProductResponseDto src)
    {
        return new InventoryItemDto
        {
            Id = src.Id,
            ProductId = src.ProductId,
            DiscountProductId = src.DiscountProductId,
            ProductType = MapToProtoProductType(src.ProductType),
            Quantity = src.Quantity,
            ReservedQuantity = src.ReservedQuantity,
            AvailableQuantity = src.AvailableQuantity,
            LowStockThreshold = src.LowStockThreshold,
            ReorderPoint = 0,
            MaxStockLevel = src.MaxStockLevel,
            LastRestockedAt = src.LastRestockedAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastRestockedAt.Value, DateTimeKind.Utc)) 
                : null,
            LastSoldAt = src.LastSoldAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastSoldAt.Value, DateTimeKind.Utc)) 
                : null,
            WarehouseId = src.WarehouseId,
            WarehouseName = src.WarehouseName ?? string.Empty,
            ProductTitle = src.ProductTitle ?? string.Empty,
            ProductPrice = src.ProductPrice.HasValue ? (long)src.ProductPrice.Value : 0,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(src.Created, DateTimeKind.Utc))
        };
    }

    private static InventoryItemDto MapListItemToInventoryItemDto(InventoryItemListDto src)
    {
        return new InventoryItemDto
        {
            Id = src.Id,
            ProductId = src.ProductId,
            DiscountProductId = src.DiscountProductId,
            ProductType = MapToProtoProductType(src.ProductType),
            Quantity = src.Quantity,
            ReservedQuantity = src.ReservedQuantity,
            AvailableQuantity = src.AvailableQuantity,
            LowStockThreshold = src.LowStockThreshold,
            ReorderPoint = 0,
            MaxStockLevel = src.MaxStockLevel,
            LastRestockedAt = src.LastRestockedAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastRestockedAt.Value, DateTimeKind.Utc)) 
                : null,
            LastSoldAt = src.LastSoldAt.HasValue 
                ? Timestamp.FromDateTime(DateTime.SpecifyKind(src.LastSoldAt.Value, DateTimeKind.Utc)) 
                : null,
            WarehouseId = src.WarehouseId,
            WarehouseName = src.WarehouseName ?? string.Empty,
            ProductTitle = src.ProductTitle ?? string.Empty,
            ProductPrice = src.ProductPrice.HasValue ? (long)src.ProductPrice.Value : 0,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(src.Created, DateTimeKind.Utc))
        };
    }

    private static InventoryItemDto MapLowStockItemToInventoryItemDto(LowStockItemDto src)
    {
        return new InventoryItemDto
        {
            Id = src.Id,
            ProductId = src.ProductId,
            DiscountProductId = src.DiscountProductId,
            ProductType = MapToProtoProductType(src.ProductType),
            Quantity = src.Quantity,
            ReservedQuantity = src.ReservedQuantity,
            AvailableQuantity = src.AvailableQuantity,
            LowStockThreshold = src.LowStockThreshold,
            ReorderPoint = 0,
            MaxStockLevel = 0,
            LastRestockedAt = null,
            LastSoldAt = null,
            WarehouseId = src.WarehouseId,
            WarehouseName = src.WarehouseName ?? string.Empty,
            ProductTitle = src.ProductTitle ?? string.Empty,
            ProductPrice = 0,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc))
        };
    }

    private static StockMovementDto MapToStockMovementDto(StockMovementListDto src)
    {
        return new StockMovementDto
        {
            Id = src.Id,
            InventoryItemId = src.InventoryItemId,
            MovementType = MapToProtoStockMovementType(src.MovementType),
            Quantity = src.Quantity,
            QuantityBefore = src.QuantityBefore,
            QuantityAfter = src.QuantityAfter,
            OrderId = src.OrderId,
            DiscountOrderId = src.DiscountOrderId,
            ReferenceNumber = src.ReferenceNumber ?? string.Empty,
            Note = src.Note ?? string.Empty,
            PerformedByUserId = src.PerformedByUserId,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(src.Created, DateTimeKind.Utc)),
            ProductTitle = src.ProductTitle ?? string.Empty
        };
    }

    private static StockMovementDto MapHistoryToStockMovementDto(StockMovementHistoryDto src)
    {
        return new StockMovementDto
        {
            Id = src.Id,
            InventoryItemId = 0, // Not available in history DTO
            MovementType = MapToProtoStockMovementType(src.MovementType),
            Quantity = src.Quantity,
            QuantityBefore = src.QuantityBefore,
            QuantityAfter = src.QuantityAfter,
            OrderId = src.OrderId,
            DiscountOrderId = src.DiscountOrderId,
            ReferenceNumber = src.ReferenceNumber ?? string.Empty,
            Note = src.Note ?? string.Empty,
            PerformedByUserId = src.PerformedByUserId,
            Created = Timestamp.FromDateTime(DateTime.SpecifyKind(src.Created, DateTimeKind.Utc)),
            ProductTitle = string.Empty
        };
    }

    // ==================== Enum Mapping Methods ====================

    private static DomainProductType MapToDomainProductType(ProtoProductType protoType)
    {
        return protoType switch
        {
            ProtoProductType.RegularProduct => DomainProductType.RegularProduct,
            ProtoProductType.DiscountProduct => DomainProductType.DiscountProduct,
            _ => DomainProductType.RegularProduct
        };
    }

    private static ProtoProductType MapToProtoProductType(DomainProductType domainType)
    {
        return domainType switch
        {
            DomainProductType.RegularProduct => ProtoProductType.RegularProduct,
            DomainProductType.DiscountProduct => ProtoProductType.DiscountProduct,
            _ => ProtoProductType.Unspecified
        };
    }

    private static DomainStockMovementType MapToDomainStockMovementType(ProtoStockMovementType protoType)
    {
        return protoType switch
        {
            ProtoStockMovementType.InitialStock => DomainStockMovementType.InitialStock,
            ProtoStockMovementType.Restock => DomainStockMovementType.Restock,
            ProtoStockMovementType.Return => DomainStockMovementType.Return,
            ProtoStockMovementType.Sale => DomainStockMovementType.Sale,
            ProtoStockMovementType.AdjustmentIncrease => DomainStockMovementType.AdjustmentPlus,
            ProtoStockMovementType.AdjustmentDecrease => DomainStockMovementType.AdjustmentMinus,
            ProtoStockMovementType.Reserved => DomainStockMovementType.Reserved,
            ProtoStockMovementType.Released => DomainStockMovementType.Released,
            ProtoStockMovementType.Loss => DomainStockMovementType.Lost,
            ProtoStockMovementType.Damaged => DomainStockMovementType.Damaged,
            ProtoStockMovementType.Expired => DomainStockMovementType.Damaged, // Domain ندارد Expired
            ProtoStockMovementType.TransferOut => DomainStockMovementType.TransferOut,
            ProtoStockMovementType.TransferIn => DomainStockMovementType.TransferIn,
            _ => DomainStockMovementType.AdjustmentPlus
        };
    }

    private static ProtoStockMovementType MapToProtoStockMovementType(DomainStockMovementType domainType)
    {
        return domainType switch
        {
            DomainStockMovementType.InitialStock => ProtoStockMovementType.InitialStock,
            DomainStockMovementType.Restock => ProtoStockMovementType.Restock,
            DomainStockMovementType.Return => ProtoStockMovementType.Return,
            DomainStockMovementType.Sale => ProtoStockMovementType.Sale,
            DomainStockMovementType.AdjustmentPlus => ProtoStockMovementType.AdjustmentIncrease,
            DomainStockMovementType.AdjustmentMinus => ProtoStockMovementType.AdjustmentDecrease,
            DomainStockMovementType.Reserved => ProtoStockMovementType.Reserved,
            DomainStockMovementType.Released => ProtoStockMovementType.Released,
            DomainStockMovementType.Lost => ProtoStockMovementType.Loss,
            DomainStockMovementType.Damaged => ProtoStockMovementType.Damaged,
            DomainStockMovementType.TransferOut => ProtoStockMovementType.TransferOut,
            DomainStockMovementType.TransferIn => ProtoStockMovementType.TransferIn,
            _ => ProtoStockMovementType.MovementTypeUnspecified
        };
    }
}
