syntax = "proto3";

package inventory;

import "google/protobuf/empty.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";

option csharp_namespace = "CMSMicroservice.Protobuf.Protos.Inventory";

// =============================================
// 📦 Inventory Management Service
// =============================================

service InventoryContract {
    // ========== Warehouse Management ==========
    rpc CreateWarehouse(CreateWarehouseRequest) returns (CreateWarehouseResponse) {
        option (google.api.http) = {
            post: "/api/inventory/warehouses"
            body: "*"
        };
    };
    rpc UpdateWarehouse(UpdateWarehouseRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/inventory/warehouses/{id}"
            body: "*"
        };
    };
    rpc DeleteWarehouse(DeleteWarehouseRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/inventory/warehouses/{id}"
        };
    };
    rpc GetWarehouse(GetWarehouseRequest) returns (GetWarehouseResponse) {
        option (google.api.http) = {
            get: "/api/inventory/warehouses/{id}"
        };
    };
    rpc GetAllWarehouses(GetAllWarehousesRequest) returns (GetAllWarehousesResponse) {
        option (google.api.http) = {
            get: "/api/inventory/warehouses"
        };
    };
    rpc SetDefaultWarehouse(SetDefaultWarehouseRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/inventory/warehouses/{id}/set-default"
            body: "*"
        };
    };

    // ========== Inventory Item Management ==========
    rpc GetInventoryItem(GetInventoryItemRequest) returns (GetInventoryItemResponse) {
        option (google.api.http) = {
            get: "/api/inventory/items/{id}"
        };
    };
    rpc GetInventoryByProduct(GetInventoryByProductRequest) returns (GetInventoryByProductResponse) {
        option (google.api.http) = {
            get: "/api/inventory/by-product/{product_id}"
        };
    };
    rpc GetAllInventoryItems(GetAllInventoryItemsRequest) returns (GetAllInventoryItemsResponse) {
        option (google.api.http) = {
            get: "/api/inventory/items"
        };
    };
    rpc GetLowStockItems(GetLowStockItemsRequest) returns (GetLowStockItemsResponse) {
        option (google.api.http) = {
            get: "/api/inventory/low-stock"
        };
    };
    rpc UpdateInventorySettings(UpdateInventorySettingsRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/inventory/items/{id}/settings"
            body: "*"
        };
    };

    // ========== Stock Operations ==========
    rpc AddStock(AddStockRequest) returns (AddStockResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/add"
            body: "*"
        };
    };
    rpc AdjustStock(AdjustStockRequest) returns (AdjustStockResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/adjust"
            body: "*"
        };
    };
    rpc ReserveStock(ReserveStockRequest) returns (ReserveStockResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/reserve"
            body: "*"
        };
    };
    rpc ReleaseReservation(ReleaseReservationRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/inventory/stock/release"
            body: "*"
        };
    };
    rpc ConfirmSale(ConfirmSaleRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/inventory/stock/confirm-sale"
            body: "*"
        };
    };
    rpc ProcessReturn(ProcessReturnRequest) returns (ProcessReturnResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/return"
            body: "*"
        };
    };
    rpc RecordLoss(RecordLossRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/inventory/stock/loss"
            body: "*"
        };
    };

    // ========== Bulk Operations ==========
    rpc BulkAddStock(BulkAddStockRequest) returns (BulkAddStockResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/bulk-add"
            body: "*"
        };
    };
    rpc BulkAdjustStock(BulkAdjustStockRequest) returns (BulkAdjustStockResponse) {
        option (google.api.http) = {
            post: "/api/inventory/stock/bulk-adjust"
            body: "*"
        };
    };

    // ========== Stock Movements ==========
    rpc GetStockMovements(GetStockMovementsRequest) returns (GetStockMovementsResponse) {
        option (google.api.http) = {
            get: "/api/inventory/movements"
        };
    };
    rpc GetStockMovementsByInventoryItem(GetStockMovementsByInventoryItemRequest) returns (GetStockMovementsByInventoryItemResponse) {
        option (google.api.http) = {
            get: "/api/inventory/items/{inventory_item_id}/movements"
        };
    };

    // ========== Reports ==========
    rpc GetInventorySummary(GetInventorySummaryRequest) returns (GetInventorySummaryResponse) {
        option (google.api.http) = {
            get: "/api/inventory/summary"
        };
    };
    rpc GetStockValueReport(GetStockValueReportRequest) returns (GetStockValueReportResponse) {
        option (google.api.http) = {
            get: "/api/inventory/reports/stock-value"
        };
    };
}

// =============================================
// Enums
// =============================================

enum ProductType {
    PRODUCT_TYPE_UNSPECIFIED = 0;
    REGULAR_PRODUCT = 1;
    DISCOUNT_PRODUCT = 2;
}

enum StockMovementType {
    MOVEMENT_TYPE_UNSPECIFIED = 0;
    INITIAL_STOCK = 1;
    RESTOCK = 2;
    RETURN = 3;
    SALE = 10;
    ADJUSTMENT_INCREASE = 20;
    ADJUSTMENT_DECREASE = 21;
    RESERVED = 30;
    RELEASED = 31;
    LOSS = 40;
    DAMAGED = 41;
    EXPIRED = 42;
    TRANSFER_OUT = 50;
    TRANSFER_IN = 51;
}

// =============================================
// Warehouse Messages
// =============================================

message WarehouseDto {
    int64 id = 1;
    string name = 2;
    string code = 3;
    string address = 4;
    bool is_default = 5;
    bool is_active = 6;
    google.protobuf.Timestamp created = 7;
    google.protobuf.Timestamp last_modified = 8;
}

message CreateWarehouseRequest {
    string name = 1;
    string code = 2;
    string address = 3;
    bool is_default = 4;
}

message CreateWarehouseResponse {
    int64 id = 1;
}

message UpdateWarehouseRequest {
    int64 id = 1;
    string name = 2;
    string code = 3;
    string address = 4;
    bool is_active = 5;
}

message DeleteWarehouseRequest {
    int64 id = 1;
}

message GetWarehouseRequest {
    int64 id = 1;
}

message GetWarehouseResponse {
    WarehouseDto warehouse = 1;
}

message GetAllWarehousesRequest {
    google.protobuf.BoolValue is_active = 1;
    int32 page = 2;
    int32 page_size = 3;
}

message GetAllWarehousesResponse {
    repeated WarehouseDto warehouses = 1;
    int32 total_count = 2;
}

message SetDefaultWarehouseRequest {
    int64 id = 1;
}

// =============================================
// Inventory Item Messages
// =============================================

message InventoryItemDto {
    int64 id = 1;
    google.protobuf.Int64Value product_id = 2;
    google.protobuf.Int64Value discount_product_id = 3;
    ProductType product_type = 4;
    int32 quantity = 5;
    int32 reserved_quantity = 6;
    int32 available_quantity = 7;
    int32 low_stock_threshold = 8;
    int32 reorder_point = 9;
    int32 max_stock_level = 10;
    google.protobuf.Timestamp last_restocked_at = 11;
    google.protobuf.Timestamp last_sold_at = 12;
    int64 warehouse_id = 13;
    string warehouse_name = 14;
    string product_title = 15;
    int64 product_price = 16;
    google.protobuf.Timestamp created = 17;
    // آیا موجودی کم است (موجودی قابل فروش کمتر از حد هشدار)
    bool is_low_stock = 18;
}

message GetInventoryItemRequest {
    int64 id = 1;
}

message GetInventoryItemResponse {
    InventoryItemDto item = 1;
}

message GetInventoryByProductRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
}

message GetInventoryByProductResponse {
    InventoryItemDto item = 1;
}

message GetAllInventoryItemsRequest {
    google.protobuf.Int64Value warehouse_id = 1;
    ProductType product_type = 2;
    string search = 3;
    int32 page = 4;
    int32 page_size = 5;
    string sort_by = 6;
    bool sort_desc = 7;
}

message GetAllInventoryItemsResponse {
    repeated InventoryItemDto items = 1;
    int32 total_count = 2;
}

message GetLowStockItemsRequest {
    google.protobuf.Int64Value warehouse_id = 1;
    ProductType product_type = 2;
    int32 page = 3;
    int32 page_size = 4;
}

message GetLowStockItemsResponse {
    repeated InventoryItemDto items = 1;
    int32 total_count = 2;
}

message UpdateInventorySettingsRequest {
    int64 id = 1;
    int32 low_stock_threshold = 2;
    int32 reorder_point = 3;
    int32 max_stock_level = 4;
}

// =============================================
// Stock Operation Messages
// =============================================

message AddStockRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    string reference_number = 4;
    string note = 5;
    google.protobuf.Int64Value warehouse_id = 6;
}

message AddStockResponse {
    int64 inventory_item_id = 1;
    int32 new_quantity = 2;
}

message AdjustStockRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 new_quantity = 3;
    string reason = 4;
    string reference_number = 5;
}

message AdjustStockResponse {
    int32 previous_quantity = 1;
    int32 new_quantity = 2;
    int32 difference = 3;
}

message ReserveStockRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    google.protobuf.Int64Value order_id = 4;
    google.protobuf.Int64Value discount_order_id = 5;
}

message ReserveStockResponse {
    bool success = 1;
    string message = 2;
    int32 available_quantity = 3;
}

message ReleaseReservationRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    google.protobuf.Int64Value order_id = 4;
    google.protobuf.Int64Value discount_order_id = 5;
}

message ConfirmSaleRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    google.protobuf.Int64Value order_id = 4;
    google.protobuf.Int64Value discount_order_id = 5;
    bool from_reservation = 6;
}

message ProcessReturnRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    google.protobuf.Int64Value order_id = 4;
    google.protobuf.Int64Value discount_order_id = 5;
    string reason = 6;
}

message ProcessReturnResponse {
    int32 new_quantity = 1;
}

message RecordLossRequest {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
    StockMovementType loss_type = 4;  // LOSS, DAMAGED, or EXPIRED
    string reason = 5;
    string reference_number = 6;
}

// =============================================
// Bulk Operation Messages
// =============================================

message BulkStockItem {
    int64 product_id = 1;
    ProductType product_type = 2;
    int32 quantity = 3;
}

message BulkAddStockRequest {
    repeated BulkStockItem items = 1;
    string reference_number = 2;
    string note = 3;
    google.protobuf.Int64Value warehouse_id = 4;
}

message BulkAddStockResponse {
    int32 success_count = 1;
    int32 failed_count = 2;
    repeated string errors = 3;
}

message BulkAdjustStockRequest {
    repeated BulkStockItem items = 1;
    string reason = 2;
    string reference_number = 3;
}

message BulkAdjustStockResponse {
    int32 success_count = 1;
    int32 failed_count = 2;
    repeated string errors = 3;
}

// =============================================
// Stock Movement Messages
// =============================================

message StockMovementDto {
    int64 id = 1;
    int64 inventory_item_id = 2;
    StockMovementType movement_type = 3;
    int32 quantity = 4;
    int32 quantity_before = 5;
    int32 quantity_after = 6;
    google.protobuf.Int64Value order_id = 7;
    google.protobuf.Int64Value discount_order_id = 8;
    string reference_number = 9;
    string note = 10;
    google.protobuf.Int64Value performed_by_user_id = 11;
    google.protobuf.Timestamp created = 12;
    string product_title = 13;
}

message GetStockMovementsRequest {
    google.protobuf.Int64Value inventory_item_id = 1;
    google.protobuf.Int64Value product_id = 2;
    ProductType product_type = 3;
    StockMovementType movement_type = 4;
    google.protobuf.Timestamp from_date = 5;
    google.protobuf.Timestamp to_date = 6;
    int32 page = 7;
    int32 page_size = 8;
}

message GetStockMovementsResponse {
    repeated StockMovementDto movements = 1;
    int32 total_count = 2;
}

message GetStockMovementsByInventoryItemRequest {
    int64 inventory_item_id = 1;
    int32 page = 2;
    int32 page_size = 3;
}

message GetStockMovementsByInventoryItemResponse {
    repeated StockMovementDto movements = 1;
    int32 total_count = 2;
}

// =============================================
// Report Messages
// =============================================

message GetInventorySummaryRequest {
    google.protobuf.Int64Value warehouse_id = 1;
}

message GetInventorySummaryResponse {
    int32 total_products = 1;
    int32 total_discount_products = 2;
    int32 total_quantity = 3;
    int32 total_reserved = 4;
    int32 low_stock_count = 5;
    int32 out_of_stock_count = 6;
    int64 total_stock_value = 7;
}

message GetStockValueReportRequest {
    google.protobuf.Int64Value warehouse_id = 1;
    ProductType product_type = 2;
}

message StockValueItem {
    int64 product_id = 1;
    string product_title = 2;
    ProductType product_type = 3;
    int32 quantity = 4;
    int64 unit_price = 5;
    int64 total_value = 6;
}

message GetStockValueReportResponse {
    repeated StockValueItem items = 1;
    int64 total_value = 2;
    int32 total_items = 3;
}
