import type { RFFlowFile, FlowExportData } from '@/types'

export class RFFlowParseError extends Error {
  constructor(message: string) {
    super(message)
    this.name = 'RFFlowParseError'
  }
}

export function parseRFFlowFile(content: string): RFFlowFile {
  const trimmed = content.trim()

  if (!trimmed.startsWith('{')) {
    throw new RFFlowParseError('Invalid file format. Expected JSON.')
  }

  try {
    const data = JSON.parse(trimmed)
    validateEnvelope(data)
    return data as RFFlowFile
  } catch (err) {
    if (err instanceof RFFlowParseError) throw err
    throw new RFFlowParseError(`Invalid JSON: ${(err as Error).message}`)
  }
}

function validateEnvelope(data: unknown): asserts data is RFFlowFile {
  const obj = data as Record<string, unknown>

  if (!obj.rfflow_version) {
    throw new RFFlowParseError('Missing rfflow_version')
  }
  if (obj.rfflow_version !== '1.0') {
    throw new RFFlowParseError(`Unsupported version: ${obj.rfflow_version}. Only 1.0 is supported.`)
  }

  const flow = obj.flow as Record<string, unknown> | undefined
  if (!flow) {
    throw new RFFlowParseError('Missing flow data')
  }
  if (!flow.name) {
    throw new RFFlowParseError('Flow must have a name')
  }
  if (!flow.tree_structure) {
    throw new RFFlowParseError('Flow must have a tree_structure')
  }

  const validTypes: FlowExportData['tree_type'][] = ['troubleshooting', 'procedural', 'maintenance']
  if (!validTypes.includes(flow.tree_type as FlowExportData['tree_type'])) {
    throw new RFFlowParseError(`Invalid tree_type: ${flow.tree_type}`)
  }
}
