// Shared TypeScript types for the Custom Views frontend.
//
// These mirror the Go shapes in internal/services/{filter_spec,
// render_spec,view_service,user_view_service}.go. Keep field names + enum
// values in sync — the substrate's validator will reject anything else.

export type DataSource = "deadline" | "appointment" | "project_event" | "approval_request";

export type ScopeMode = "all_visible" | "my_subtree" | "explicit";

export interface ScopeProjects {
  mode: ScopeMode;
  ids?: string[];
}

export interface ScopeSpec {
  projects: ScopeProjects;
  personal_only?: boolean;
}

export type TimeHorizon =
  | "next_7d" | "next_30d" | "next_90d"
  | "past_7d" | "past_30d" | "past_90d"
  | "any" | "all" | "custom";

export type TimeField = "auto" | "created_at";

export interface TimeSpec {
  horizon: TimeHorizon;
  field?: TimeField;
  from?: string; // ISO 8601
  to?: string;
}

export interface DeadlinePredicates {
  status?: string[];
  approval_status?: string[];
  event_types?: string[];
  include_untyped?: boolean;
}

export interface AppointmentPredicates {
  approval_status?: string[];
  appointment_types?: string[];
}

export interface ProjectEventPredicates {
  event_types?: string[];
}

export interface ApprovalRequestPredicates {
  viewer_role?: "approver_eligible" | "self_requested" | "any_visible";
  status?: string[];
  entity_types?: string[];
}

export interface Predicates {
  deadline?: DeadlinePredicates;
  appointment?: AppointmentPredicates;
  project_event?: ProjectEventPredicates;
  approval_request?: ApprovalRequestPredicates;
}

export interface FilterSpec {
  version: number;
  sources: DataSource[];
  scope: ScopeSpec;
  time: TimeSpec;
  predicates?: Partial<Record<DataSource, Predicates>>;
}

export type RenderShape = "list" | "cards" | "calendar" | "timeline";

export interface TimelineCVConfig {
  palette?: "default" | "kind-coded" | "track-coded" | "high-contrast" | "print";
  density?: "compact" | "standard" | "spacious";
  range_preset?: "1y" | "2y" | "all" | "custom";
  range_from?: string;
  range_to?: string;
}

export type ListRowAction = "navigate" | "complete_toggle" | "approve" | "none";

export interface ListConfig {
  columns?: string[];
  sort?: "date_asc" | "date_desc";
  density?: "comfortable" | "compact";
  row_action?: ListRowAction;
}

export interface CardsConfig {
  group_by?: "day" | "week" | "none";
  sort?: "date_asc" | "date_desc";
  show_empty_days?: boolean;
}

export interface CalendarConfig {
  default_view?: "month" | "week";
  show_weekends?: boolean;
}

export interface RenderSpec {
  shape: RenderShape;
  list?: ListConfig;
  cards?: CardsConfig;
  calendar?: CalendarConfig;
  timeline?: TimelineCVConfig;
}

// ViewRow — the discriminated row shape from ViewService.RunSpec.
export interface ViewRow {
  kind: DataSource;
  id: string;
  title: string;
  subtitle?: string;
  event_date: string;
  project_id?: string;
  project_title?: string;
  project_reference?: string;
  project_type?: string;
  actor_id?: string;
  actor_name?: string;
  detail: Record<string, unknown>;
}

export interface ViewRunResult {
  rows: ViewRow[];
  inaccessible_project_ids?: string[];
}

// UserView — the persisted shape from /api/user-views.
export interface UserView {
  id: string;
  user_id: string;
  slug: string;
  name: string;
  icon?: string;
  filter_spec: FilterSpec;
  render_spec: RenderSpec;
  sort_order: number;
  show_count: boolean;
  last_used_at?: string;
  created_at: string;
  updated_at: string;
}

// SystemView — code-resident definition from /api/views/system.
export interface SystemView {
  Slug: string;
  Name: string;
  Filter: FilterSpec;
  Render: RenderSpec;
}

export const SPEC_VERSION = 1;

export function defaultFilterSpec(): FilterSpec {
  return {
    version: SPEC_VERSION,
    sources: ["deadline", "appointment"],
    scope: { projects: { mode: "all_visible" } },
    time: { horizon: "next_30d", field: "auto" },
  };
}

export function defaultRenderSpec(): RenderSpec {
  return {
    shape: "list",
    list: { sort: "date_asc", density: "comfortable" },
  };
}
