// NOTE: Стартовый стаб. Финальные .proto генерируются/поддерживаются вместе с реализацией
// в `services/public-api/api/grpc/`. Эта папка — синхронизированная копия для документации.
//
// См.:
// - 30-services/public-api/README.md
// - ADR-0015 (multi-protocol public API)

syntax = "proto3";

package tracium.public.v1;

option go_package = "github.com/tracium/tracium/gen/go/tracium/public/v1;publicv1";

import "google/protobuf/timestamp.proto";

// =================== common ===================

message Freshness {
  enum Status {
    STATUS_UNSPECIFIED = 0;
    FRESH = 1;
    STALE = 2;
    INCOMPLETE = 3;
    EMPTY = 4;
  }
  Status status = 1;
  google.protobuf.Timestamp observed_at = 2;
  google.protobuf.Timestamp stale_since = 3;
  google.protobuf.Timestamp refresh_eta = 4;
}

message Cursor { string token = 1; }

// =================== catalog ===================

service Catalog {
  rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse);
  rpc GetProduct(GetProductRequest) returns (Product);
  rpc StreamProducts(StreamProductsRequest) returns (stream Product);
}

message Product {
  string id = 1;
  string manufacturer = 2;
  string mpn = 3;
  string identity_profile_id = 4;
  map<string, string> characteristics = 5;
  string lifecycle_status = 6; // new|active|deprecated|discontinued
  string replaced_by = 7;
  Freshness freshness = 8;
}

message SearchProductsRequest {
  string q = 1;
  string identity_profile_id = 2;
  string manufacturer = 3;
  int32 limit = 4;
  Cursor cursor = 5;
}

message SearchProductsResponse {
  repeated Product items = 1;
  Cursor next_cursor = 2;
  Freshness freshness = 3;
}

message GetProductRequest { string id = 1; }

message StreamProductsRequest {
  string identity_profile_id = 1;
  int32 batch_size = 2;
}

// =================== offers ===================

service Offers {
  rpc GetOffers(GetOffersRequest) returns (GetOffersResponse);
}

message Offer {
  string id = 1;
  string supplier_id = 2;
  string supplier_sku = 3;
  string match_confidence = 4; // exact|strong|probable|weak|unmatched
  SupplyChainTrace supply_chain_trace = 5;
  Freshness freshness = 6;
}

message SupplyChainTrace {
  string observed_via_supplier_ref = 1;
  string api_provider_ref = 2;
  string sales_agent_ref = 3;
  repeated string warehouse_operator_refs = 4;
  string distributor_ref = 5;
  string manufacturer_ref = 6;
  int32 chain_depth = 7;
}

message GetOffersRequest { string canonical_id = 1; }
message GetOffersResponse { repeated Offer items = 1; }

// =================== pricing ===================

service Pricing {
  rpc CalculatePrice(CalculatePriceRequest) returns (PricingResponse);
  rpc BulkCalculatePrice(stream CalculatePriceRequest) returns (stream PricingResponse);
}

message CalculatePriceRequest {
  string offer_id = 1;
  int32 quantity = 2;
  string delivery_zone = 3;
  google.protobuf.Timestamp date = 4;
}

message ObservationSource {
  enum Type {
    TYPE_UNSPECIFIED = 0;
    CUSTOMER_CREDENTIAL = 1;
    GROUP_SHARED = 2;
    SYSTEM_CREDENTIAL = 3;
  }
  Type type = 1;
  string credential_label = 2;
  google.protobuf.Timestamp observed_at = 3;
  string fallback_reason = 4;
}

message PricingBreakdownLine {
  string rule_id = 1;
  string label = 2;
  double amount = 3;
}

message PricingResponse {
  double final_price = 1;
  string currency = 2;
  ObservationSource observation_source = 3;
  repeated PricingBreakdownLine breakdown = 4;
  string pricing_mode = 5; // fixed|on_request|unknown
  Freshness freshness = 6;
}

// =================== estimate ===================

service Estimate {
  rpc BuildEstimate(BuildEstimateRequest) returns (EstimateResponse);
  rpc WatchEstimate(WatchEstimateRequest) returns (stream EstimateResponse);
}

message BuildEstimateRequest {
  string source_format = 1; // xlsx|csv|text|json
  repeated EstimateLineInput lines = 2;
  string optimization_mode = 3; // min_price|min_suppliers|min_lead_time|single_manufacturer
}

message EstimateLineInput {
  string raw_text = 1;
  double quantity = 2;
  string unit = 3;
  double expected_price = 4;
}

message WatchEstimateRequest { string estimate_id = 1; }

message EstimateResponse {
  string id = 1;
  int32 version = 2;
  string status = 3; // parsing|optimizing|ready|error
  double total_price = 4;
  string currency = 5;
}

// =================== enrichment ===================

service Enrichment {
  rpc RequestEnrichment(EnrichmentJobRequest) returns (EnrichmentJob);
  rpc WatchJob(WatchJobRequest) returns (stream EnrichmentJob);
}

message EnrichmentJobRequest {
  string type = 1; // discovery|refresh_observation|refresh_characteristics|rebuild_supply_chain
  map<string, string> target = 2;
  string priority = 3; // high|normal|low
}

message WatchJobRequest { string job_id = 1; }

message EnrichmentJob {
  string id = 1;
  string type = 2;
  string status = 3; // queued|started|completed|failed
  float progress = 4;
  google.protobuf.Timestamp created_at = 5;
  google.protobuf.Timestamp finished_at = 6;
}
