export type JsonMap = Record<string, unknown>;

export interface ModelGroup extends JsonMap {
  id: string;
  code: string;
  name: string;
  model_type: "detection" | "segmentation" | "thermal" | "pointcloud" | "change";
  description: string;
  input_modalities: string[];
  owner_team: string;
  production_version_id?: string;
  production_version?: string;
  candidate_version_id?: string;
  candidate_version?: string;
  production_metrics?: JsonMap;
  service_status: string;
  test_count: number;
  running_tests: number;
  pending_releases: number;
}

export interface ModelVersion extends JsonMap {
  id: string;
  model_group: string;
  version: string;
  display_name: string;
  status: string;
  scenes: string[];
  metrics: JsonMap;
  release_notes: string;
  dataset_version: string;
  runtime_requirements: JsonMap;
  artifact_id?: string;
  artifact_type?: string;
  artifact_sha256?: string;
  artifact_size_bytes?: number;
  artifact_validation_status?: string;
  created_at: string;
}

export interface RuntimeDeployment extends JsonMap {
  id: string;
  model_group_id: string;
  model_group_code: string;
  model_version_id: string;
  model_version: string;
  model_version_name: string;
  name: string;
  environment: "local" | "development" | "staging" | "production";
  service_url: string;
  health_path: string;
  runtime_path: string;
  inference_path: string;
  test_path: string;
  runtime_engine: string;
  execution_provider: string;
  device: string;
  precision: string;
  artifact_uri?: string;
  auth_secret_ref?: string;
  replicas: number;
  max_concurrency: number;
  request_timeout_seconds: number;
  config: JsonMap;
  status: string;
  health_status: "unknown" | "healthy" | "degraded" | "unreachable" | "incompatible";
  health_message?: string;
  health_snapshot: JsonMap;
  last_health_at?: string;
  connectivity_status: "unknown" | "connected" | "unreachable";
  connectivity_message?: string;
  last_connectivity_at?: string;
  active: boolean;
  revision: number;
  updated_at: string;
}

export interface ParameterProperty extends JsonMap {
  type: "number" | "integer" | "string" | "boolean";
  title: string;
  minimum?: number;
  maximum?: number;
  multipleOf?: number;
  enum?: Array<string | number>;
  default?: unknown;
}

export interface ParameterSchema extends JsonMap {
  id: string;
  schema_version: string;
  json_schema: {
    type: string;
    properties: Record<string, ParameterProperty>;
    required?: string[];
  };
  ui_schema: {
    groups: Array<{ title: string; fields: string[] }>;
  };
}

export interface ParameterProfile extends JsonMap {
  id: string;
  model_group_id: string;
  model_version_id: string;
  model_version: string;
  name: string;
  revision: number;
  scope_type: string;
  scope_value: JsonMap;
  parameters: JsonMap;
  based_on_id?: string;
  status: string;
  change_reason?: string;
  created_by: string;
  updated_at: string;
}

export interface ModelSample extends JsonMap {
  id: string;
  name: string;
  model_group_id: string;
  modality: string;
  storage_url: string;
  thumbnail_url?: string;
  line_id?: string;
  mileage?: string;
  scene: string;
  source: string;
  label_status: string;
  split_type: string;
  quality_status: string;
  difficulty_tags: string[];
  metadata: JsonMap;
  ground_truth: JsonMap;
  sha256: string;
}

export interface SamplePreviewData extends JsonMap {
  id: string;
  name?: string;
  modality?: string;
  preview_url?: string;
  storage_url?: string;
  source?: string;
  scene?: string;
  line_id?: string;
  mileage?: string;
  label_status?: string;
  quality_status?: string;
  feedback_reason?: string;
  target_model_group?: string;
  model_group_id?: string;
  source_model_version?: string;
  size_bytes?: number;
  content_type?: string;
  difficulty_tags?: string[];
  validation_messages?: JsonMap[];
  metadata?: JsonMap;
  ground_truth?: JsonMap;
  evidence?: JsonMap;
}

export interface UploadFileRecord extends JsonMap {
  id: string;
  session_id: string;
  file_name: string;
  content_type: string;
  modality: string;
  size_bytes: number;
  sha256: string;
  validation_status: string;
  validation_messages: Array<JsonMap>;
  metadata: JsonMap;
}

export interface UploadSession extends JsonMap {
  id: string;
  model_group_id: string;
  status: string;
  file_count: number;
  total_size_bytes: number;
  expires_at: string;
  storage_mode: string;
  files: UploadFileRecord[];
}

export interface TestEvent extends JsonMap {
  event_id: string;
  sequence_no: number;
  event_type: string;
  step_key: string;
  status: string;
  progress: number;
  message: string;
  payload: JsonMap;
  created_at: string;
}

export interface ModelTestInput extends JsonMap {
  id: string;
  source_type: string;
  sample_id?: string;
  upload_file_id?: string;
  name: string;
  modality: string;
  validation_status: string;
  metadata_snapshot: JsonMap;
  ground_truth_snapshot: JsonMap;
}

export interface ModelTestTask extends JsonMap {
  id: string;
  task_no: string;
  name: string;
  test_type: string;
  model_group_id: string;
  model_group_name: string;
  model_group_code: string;
  model_type: string;
  status: string;
  current_step: string;
  progress: number;
  trace_id: string;
  matrix_snapshot: Array<JsonMap>;
  input_snapshot: JsonMap;
  options: JsonMap;
  inputs: ModelTestInput[];
  events: TestEvent[];
  summaries: TestSummary[];
  created_at: string;
  started_at?: string;
  finished_at?: string;
}

export interface TestResult extends JsonMap {
  id: string;
  test_task_id: string;
  test_input_id: string;
  input_name: string;
  modality: string;
  source_type: string;
  upload_file_id?: string;
  preview_url?: string;
  input_metadata: JsonMap;
  model_version_id: string;
  model_version: string;
  parameter_profile_id?: string;
  parameter_profile_name?: string;
  parameter_snapshot: JsonMap;
  status: string;
  prediction: JsonMap;
  metrics: JsonMap;
  artifacts: JsonMap;
  runtime_snapshot: JsonMap;
  timings: JsonMap;
  error_code?: string;
}

export interface TestSummary extends JsonMap {
  id: string;
  test_task_id: string;
  model_version_id: string;
  model_version: string;
  model_version_name: string;
  parameter_profile_id?: string;
  parameter_profile_name?: string;
  metrics: JsonMap;
  baseline_delta: JsonMap;
  acceptance_status: string;
  acceptance_details: Array<JsonMap>;
  conclusion: string;
}

export interface ModelRelease extends JsonMap {
  id: string;
  release_no: string;
  model_group_id: string;
  model_version_id: string;
  model_version: string;
  model_version_name: string;
  parameter_profile_id: string;
  parameter_profile_name: string;
  evaluation_task_id?: string;
  evaluation_task_no?: string;
  status: string;
  gray_strategy: JsonMap;
  gray_percent: number;
  applicant: string;
  approver?: string;
  approval_comment?: string;
  rollback_version_id?: string;
  rollback_profile_id?: string;
  created_at: string;
  updated_at: string;
}

export function modelTypeLabel(value: string) {
  return ({ detection: "目标检测", segmentation: "图像分割", thermal: "红外分析", pointcloud: "点云分析", change: "变化检测" } as Record<string, string>)[value] || value;
}

export function testStatusLabel(value: string) {
  return ({
    draft: "草稿", validating: "校验中", rejected: "校验未通过", queued: "排队中", running: "运行中",
    cancelling: "取消中", cancelled: "已取消", completed: "已完成", partially_completed: "部分完成", failed: "失败"
  } as Record<string, string>)[value] || value;
}

export function releaseStatusLabel(value: string) {
  return ({ requested: "待审批", approved: "已批准", rejected: "已驳回", gray: "灰度中", production: "生产中", rolled_back: "已回滚" } as Record<string, string>)[value] || value;
}

export function statusTagType(value: string): "success" | "warning" | "danger" | "info" | "primary" {
  if (["healthy", "production", "completed", "passed", "active", "valid", "qualified"].includes(value)) return "success";
  if (["failed", "rejected", "invalid"].includes(value)) return "danger";
  if (["running", "queued", "gray", "partially_completed", "warning", "candidate"].includes(value)) return "warning";
  if (["draft", "retired", "inactive", "cancelled"].includes(value)) return "info";
  return "primary";
}

export function formatBytes(value: unknown) {
  const bytes = Number(value || 0);
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;
  if (bytes < 1024 ** 3) return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
  return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
}

export function formatDateTime(value: unknown) {
  return value ? new Date(String(value)).toLocaleString("zh-CN", { hour12: false }) : "-";
}
