// @ts-nocheck
// Code generated by protoc-gen-ts-server. DO NOT EDIT.
// source: worldmonitor/supply_chain/v1/service.proto

export interface GetShippingRatesRequest {
}

export interface GetShippingRatesResponse {
  indices: ShippingIndex[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface ShippingIndex {
  indexId: string;
  name: string;
  currentValue: number;
  previousValue: number;
  changePct: number;
  unit: string;
  history: ShippingRatePoint[];
  spikeAlert: boolean;
}

export interface ShippingRatePoint {
  date: string;
  value: number;
}

export interface GetChokepointStatusRequest {
}

export interface GetChokepointStatusResponse {
  chokepoints: ChokepointInfo[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface ChokepointInfo {
  id: string;
  name: string;
  lat: number;
  lon: number;
  disruptionScore: number;
  status: string;
  activeWarnings: number;
  congestionLevel: string;
  affectedRoutes: string[];
  description: string;
  aisDisruptions: number;
  directions: string[];
  directionalDwt: DirectionalDwt[];
  transitSummary?: TransitSummary;
  flowEstimate?: FlowEstimate;
  warRiskTier: WarRiskTier;
}

export interface DirectionalDwt {
  direction: string;
  dwtThousandTonnes: number;
  wowChangePct: number;
}

export interface TransitSummary {
  todayTotal: number;
  todayTanker: number;
  todayCargo: number;
  todayOther: number;
  wowChangePct: number;
  history: TransitDayCount[];
  riskLevel: string;
  incidentCount7d: number;
  disruptionPct: number;
  riskSummary: string;
  riskReportAction: string;
}

export interface TransitDayCount {
  date: string;
  tanker: number;
  cargo: number;
  other: number;
  total: number;
  container: number;
  dryBulk: number;
  generalCargo: number;
  roro: number;
  capContainer: number;
  capDryBulk: number;
  capGeneralCargo: number;
  capRoro: number;
  capTanker: number;
}

export interface FlowEstimate {
  currentMbd: number;
  baselineMbd: number;
  flowRatio: number;
  disrupted: boolean;
  source: string;
  hazardAlertLevel: string;
  hazardAlertName: string;
}

export interface GetCriticalMineralsRequest {
}

export interface GetCriticalMineralsResponse {
  minerals: CriticalMineral[];
  fetchedAt: string;
  upstreamUnavailable: boolean;
}

export interface CriticalMineral {
  mineral: string;
  topProducers: MineralProducer[];
  hhi: number;
  riskRating: string;
  globalProduction: number;
  unit: string;
}

export interface MineralProducer {
  country: string;
  countryCode: string;
  productionTonnes: number;
  sharePct: number;
}

export interface GetShippingStressRequest {
}

export interface GetShippingStressResponse {
  carriers: ShippingStressCarrier[];
  stressScore: number;
  stressLevel: string;
  fetchedAt: number;
  upstreamUnavailable: boolean;
}

export interface ShippingStressCarrier {
  symbol: string;
  name: string;
  price: number;
  changePct: number;
  carrierType: string;
  sparkline: number[];
}

export interface GetCountryChokepointIndexRequest {
  iso2: string;
  hs2: string;
}

export interface GetCountryChokepointIndexResponse {
  iso2: string;
  hs2: string;
  exposures: ChokepointExposureEntry[];
  primaryChokepointId: string;
  vulnerabilityIndex: number;
  fetchedAt: string;
}

export interface ChokepointExposureEntry {
  chokepointId: string;
  chokepointName: string;
  exposureScore: number;
  coastSide: string;
  shockSupported: boolean;
}

export interface GetBypassOptionsRequest {
  chokepointId: string;
  cargoType: string;
  closurePct: number;
}

export interface GetBypassOptionsResponse {
  chokepointId: string;
  cargoType: string;
  closurePct: number;
  options: BypassOption[];
  fetchedAt: string;
  primaryChokepointWarRiskTier: WarRiskTier;
}

export interface BypassOption {
  id: string;
  name: string;
  type: string;
  addedTransitDays: number;
  addedCostMultiplier: number;
  capacityConstraintTonnage: string;
  suitableCargoTypes: string[];
  activationThreshold: string;
  waypointChokepointIds: string[];
  liveScore: number;
  bypassWarRiskTier: WarRiskTier;
  notes: string;
}

export interface GetCountryCostShockRequest {
  iso2: string;
  chokepointId: string;
  hs2: string;
}

export interface GetCountryCostShockResponse {
  iso2: string;
  chokepointId: string;
  hs2: string;
  supplyDeficitPct: number;
  coverageDays: number;
  warRiskPremiumBps: number;
  warRiskTier: WarRiskTier;
  hasEnergyModel: boolean;
  unavailableReason: string;
  fetchedAt: string;
}

export interface GetSectorDependencyRequest {
  iso2: string;
  hs2: string;
}

export interface GetSectorDependencyResponse {
  iso2: string;
  hs2: string;
  hs2Label: string;
  flags: DependencyFlag[];
  primaryExporterIso2: string;
  primaryExporterShare: number;
  primaryChokepointId: string;
  primaryChokepointExposure: number;
  hasViableBypass: boolean;
  fetchedAt: string;
}

export interface GetRouteExplorerLaneRequest {
  fromIso2: string;
  toIso2: string;
  hs2: string;
  cargoType: string;
}

export interface GetRouteExplorerLaneResponse {
  fromIso2: string;
  toIso2: string;
  hs2: string;
  cargoType: string;
  primaryRouteId: string;
  primaryRouteGeometry: GeoPoint[];
  chokepointExposures: ChokepointExposureSummary[];
  bypassOptions: BypassCorridorOption[];
  warRiskTier: string;
  disruptionScore: number;
  estTransitDaysRange?: NumberRange;
  estFreightUsdPerTeuRange?: NumberRange;
  noModeledLane: boolean;
  fetchedAt: string;
}

export interface GeoPoint {
  lon: number;
  lat: number;
}

export interface ChokepointExposureSummary {
  chokepointId: string;
  chokepointName: string;
  exposurePct: number;
}

export interface BypassCorridorOption {
  id: string;
  name: string;
  type: string;
  addedTransitDays: number;
  addedCostMultiplier: number;
  warRiskTier: string;
  status: CorridorStatus;
  fromPort?: GeoPoint;
  toPort?: GeoPoint;
}

export interface NumberRange {
  min: number;
  max: number;
}

export interface GetRouteImpactRequest {
  fromIso2: string;
  toIso2: string;
  hs2: string;
}

export interface GetRouteImpactResponse {
  laneValueUsd: number;
  primaryExporterIso2: string;
  primaryExporterShare: number;
  topStrategicProducts: StrategicProduct[];
  resilienceScore: number;
  dependencyFlags: DependencyFlag[];
  hs2InSeededUniverse: boolean;
  comtradeSource: string;
  fetchedAt: string;
}

export interface StrategicProduct {
  hs4: string;
  label: string;
  totalValueUsd: number;
  topExporterIso2: string;
  topExporterShare: number;
  primaryChokepointId: string;
}

export type CorridorStatus = "CORRIDOR_STATUS_UNSPECIFIED" | "CORRIDOR_STATUS_ACTIVE" | "CORRIDOR_STATUS_PROPOSED" | "CORRIDOR_STATUS_UNAVAILABLE";

export type DependencyFlag = "DEPENDENCY_FLAG_UNSPECIFIED" | "DEPENDENCY_FLAG_SINGLE_SOURCE_CRITICAL" | "DEPENDENCY_FLAG_SINGLE_CORRIDOR_CRITICAL" | "DEPENDENCY_FLAG_COMPOUND_RISK" | "DEPENDENCY_FLAG_DIVERSIFIABLE";

export type WarRiskTier = "WAR_RISK_TIER_UNSPECIFIED" | "WAR_RISK_TIER_NORMAL" | "WAR_RISK_TIER_ELEVATED" | "WAR_RISK_TIER_HIGH" | "WAR_RISK_TIER_CRITICAL" | "WAR_RISK_TIER_WAR_ZONE";

export interface FieldViolation {
  field: string;
  description: string;
}

export class ValidationError extends Error {
  violations: FieldViolation[];

  constructor(violations: FieldViolation[]) {
    super("Validation failed");
    this.name = "ValidationError";
    this.violations = violations;
  }
}

export class ApiError extends Error {
  statusCode: number;
  body: string;

  constructor(statusCode: number, message: string, body: string) {
    super(message);
    this.name = "ApiError";
    this.statusCode = statusCode;
    this.body = body;
  }
}

export interface ServerContext {
  request: Request;
  pathParams: Record<string, string>;
  headers: Record<string, string>;
}

export interface ServerOptions {
  onError?: (error: unknown, req: Request) => Response | Promise<Response>;
  validateRequest?: (methodName: string, body: unknown) => FieldViolation[] | undefined;
}

export interface RouteDescriptor {
  method: string;
  path: string;
  handler: (req: Request) => Promise<Response>;
}

export interface SupplyChainServiceHandler {
  getShippingRates(ctx: ServerContext, req: GetShippingRatesRequest): Promise<GetShippingRatesResponse>;
  getChokepointStatus(ctx: ServerContext, req: GetChokepointStatusRequest): Promise<GetChokepointStatusResponse>;
  getCriticalMinerals(ctx: ServerContext, req: GetCriticalMineralsRequest): Promise<GetCriticalMineralsResponse>;
  getShippingStress(ctx: ServerContext, req: GetShippingStressRequest): Promise<GetShippingStressResponse>;
  getCountryChokepointIndex(ctx: ServerContext, req: GetCountryChokepointIndexRequest): Promise<GetCountryChokepointIndexResponse>;
  getBypassOptions(ctx: ServerContext, req: GetBypassOptionsRequest): Promise<GetBypassOptionsResponse>;
  getCountryCostShock(ctx: ServerContext, req: GetCountryCostShockRequest): Promise<GetCountryCostShockResponse>;
  getSectorDependency(ctx: ServerContext, req: GetSectorDependencyRequest): Promise<GetSectorDependencyResponse>;
  getRouteExplorerLane(ctx: ServerContext, req: GetRouteExplorerLaneRequest): Promise<GetRouteExplorerLaneResponse>;
  getRouteImpact(ctx: ServerContext, req: GetRouteImpactRequest): Promise<GetRouteImpactResponse>;
}

export function createSupplyChainServiceRoutes(
  handler: SupplyChainServiceHandler,
  options?: ServerOptions,
): RouteDescriptor[] {
  return [
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-shipping-rates",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetShippingRatesRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getShippingRates(ctx, body);
          return new Response(JSON.stringify(result as GetShippingRatesResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-chokepoint-status",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetChokepointStatusRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getChokepointStatus(ctx, body);
          return new Response(JSON.stringify(result as GetChokepointStatusResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-critical-minerals",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetCriticalMineralsRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCriticalMinerals(ctx, body);
          return new Response(JSON.stringify(result as GetCriticalMineralsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-shipping-stress",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const body = {} as GetShippingStressRequest;

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getShippingStress(ctx, body);
          return new Response(JSON.stringify(result as GetShippingStressResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-country-chokepoint-index",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetCountryChokepointIndexRequest = {
            iso2: params.get("iso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getCountryChokepointIndex", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCountryChokepointIndex(ctx, body);
          return new Response(JSON.stringify(result as GetCountryChokepointIndexResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-bypass-options",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetBypassOptionsRequest = {
            chokepointId: params.get("chokepointId") ?? "",
            cargoType: params.get("cargoType") ?? "",
            closurePct: Number(params.get("closurePct") ?? "0"),
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getBypassOptions", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getBypassOptions(ctx, body);
          return new Response(JSON.stringify(result as GetBypassOptionsResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-country-cost-shock",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetCountryCostShockRequest = {
            iso2: params.get("iso2") ?? "",
            chokepointId: params.get("chokepointId") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getCountryCostShock", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getCountryCostShock(ctx, body);
          return new Response(JSON.stringify(result as GetCountryCostShockResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-sector-dependency",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetSectorDependencyRequest = {
            iso2: params.get("iso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getSectorDependency", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getSectorDependency(ctx, body);
          return new Response(JSON.stringify(result as GetSectorDependencyResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-route-explorer-lane",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetRouteExplorerLaneRequest = {
            fromIso2: params.get("fromIso2") ?? "",
            toIso2: params.get("toIso2") ?? "",
            hs2: params.get("hs2") ?? "",
            cargoType: params.get("cargoType") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getRouteExplorerLane", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getRouteExplorerLane(ctx, body);
          return new Response(JSON.stringify(result as GetRouteExplorerLaneResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
    {
      method: "GET",
      path: "/api/supply-chain/v1/get-route-impact",
      handler: async (req: Request): Promise<Response> => {
        try {
          const pathParams: Record<string, string> = {};
          const url = new URL(req.url, "http://localhost");
          const params = url.searchParams;
          const body: GetRouteImpactRequest = {
            fromIso2: params.get("fromIso2") ?? "",
            toIso2: params.get("toIso2") ?? "",
            hs2: params.get("hs2") ?? "",
          };
          if (options?.validateRequest) {
            const bodyViolations = options.validateRequest("getRouteImpact", body);
            if (bodyViolations) {
              throw new ValidationError(bodyViolations);
            }
          }

          const ctx: ServerContext = {
            request: req,
            pathParams,
            headers: Object.fromEntries(req.headers.entries()),
          };

          const result = await handler.getRouteImpact(ctx, body);
          return new Response(JSON.stringify(result as GetRouteImpactResponse), {
            status: 200,
            headers: { "Content-Type": "application/json" },
          });
        } catch (err: unknown) {
          if (err instanceof ValidationError) {
            return new Response(JSON.stringify({ violations: err.violations }), {
              status: 400,
              headers: { "Content-Type": "application/json" },
            });
          }
          if (options?.onError) {
            return options.onError(err, req);
          }
          const message = err instanceof Error ? err.message : String(err);
          return new Response(JSON.stringify({ message }), {
            status: 500,
            headers: { "Content-Type": "application/json" },
          });
        }
      },
    },
  ];
}

