import type { WorkspaceListResponse } from '@dify/contracts/api/openapi/types.gen'
import type { TableCell } from '../../../framework/output.js'
import type { TableColumn, TableHandler, TableRow } from '../../../printers/format-table.js'
import { isPayloadShape } from '../app/payload-shape.js'

export const WORKSPACE_MODE_KEY = 'workspace'
const CURRENT_MARKER = '*'

export type WorkspaceObject = {
  mode: () => string
  raw: () => WorkspaceListResponse
}

export function newWorkspaceObject(env: WorkspaceListResponse): WorkspaceObject {
  return {
    mode: () => WORKSPACE_MODE_KEY,
    raw: () => env,
  }
}

export const WORKSPACE_COLUMNS: readonly TableColumn[] = [
  { name: 'ID', priority: 0 },
  { name: 'NAME', priority: 0 },
  { name: 'ROLE', priority: 0 },
  { name: 'STATUS', priority: 0 },
  { name: 'CURRENT', priority: 0 },
]

export class WorkspaceRow {
  readonly id: string
  readonly displayName: string
  readonly role: string
  readonly status: string
  readonly current: boolean

  constructor(
    id: string,
    displayName: string,
    role: string,
    status: string,
    current: boolean,
  ) {
    this.id = id
    this.displayName = displayName
    this.role = role
    this.status = status
    this.current = current
  }

  tableRow(): readonly TableCell[] {
    return [
      this.id,
      this.displayName,
      this.role,
      this.status,
      this.current ? CURRENT_MARKER : '',
    ]
  }

  name(): string {
    return this.id
  }

  json() {
    return {
      id: this.id,
      name: this.displayName,
      role: this.role,
      status: this.status,
      current: this.current,
    }
  }
}

export class WorkspaceListOutput {
  readonly rows: readonly WorkspaceRow[]
  readonly envelope: WorkspaceListResponse

  constructor(rows: readonly WorkspaceRow[], envelope: WorkspaceListResponse) {
    this.rows = rows
    this.envelope = envelope
  }

  static tableColumns(): readonly TableColumn[] {
    return WORKSPACE_COLUMNS
  }

  tableColumns(): readonly TableColumn[] {
    return WorkspaceListOutput.tableColumns()
  }

  tableRows(): readonly (readonly TableCell[])[] {
    return this.rows.map(row => row.tableRow())
  }

  name(): string {
    return this.rows.map(row => row.name()).join('\n')
  }

  json(): WorkspaceListResponse {
    return this.envelope
  }
}

export function workspaceTableHandler(currentId: string): TableHandler {
  return {
    columns: () => WORKSPACE_COLUMNS,
    rows: (raw): readonly TableRow[] => {
      if (!isPayloadShape<WorkspaceListResponse>(raw, 'workspaces'))
        throw new Error('get/workspace table: unexpected payload shape')
      return raw.workspaces.map(w => [
        w.id,
        w.name,
        w.role,
        w.status,
        w.current || (currentId !== '' && w.id === currentId) ? CURRENT_MARKER : '',
      ])
    },
  }
}
