import { ISLANDER_CONFIG } from './config'
import type { IslanderAction, IslanderActionResult } from './types'

export type { IslanderAction, IslanderActionResult } from './types'

function actionBlockRegex() {
  return new RegExp(ISLANDER_CONFIG.actionBlockRe, 'gi')
}

function parseActionJson(raw: string): IslanderAction[] {
  try {
    const parsed = JSON.parse(raw) as IslanderAction | IslanderAction[]
    if (Array.isArray(parsed)) return parsed.filter(isIslanderAction)
    if (isIslanderAction(parsed)) return [parsed]
  } catch {
    // ignore malformed action JSON
  }
  return []
}

export function parseIslanderActions(content: string): IslanderAction[] {
  const actions: IslanderAction[] = []
  const matches = [...content.matchAll(actionBlockRegex())]
  for (const match of matches) {
    actions.push(...parseActionJson(match[1]?.trim() ?? ''))
  }
  if (actions.length > 0) return actions

  const jsonMatches = [...content.matchAll(VISIBLE_ACTION_JSON_RE)]
  for (const match of jsonMatches) {
    actions.push(...parseActionJson(match[0].replace(/```(?:json)?|```/g, '').trim()))
  }
  return actions
}

const VISIBLE_ACTION_JSON_RE =
  /```(?:json)?\s*[\s\S]*?"type"\s*:\s*"(?:navigate|click|fill|select|focus|highlight|scroll|wait|generateOutreachReply|applyDraft|publishOutreach|markHandled|expandKnowledgeGraph|toggleGraphNode|startScan|startViralScan|startCopyMissionAnalyze|startCopyMissionScan|generateCopyMatrix|generateCopyDraft|publishCopyDraft|navigateToPersona8D)"[\s\S]*?```/gi

export function stripIslanderActions(content: string): string {
  return content
    .replace(actionBlockRegex(), '')
    .replace(VISIBLE_ACTION_JSON_RE, '')
    .replace(/\n{3,}/g, '\n\n')
    .trim()
}

function isIslanderAction(value: unknown): value is IslanderAction {
  if (!value || typeof value !== 'object') return false
  const action = value as IslanderAction
  switch (action.type) {
    case 'navigate':
      return typeof action.path === 'string' && action.path.length > 0
    case 'click':
    case 'focus':
    case 'highlight':
      return typeof action.ref === 'string' && action.ref.length > 0
    case 'fill':
      return (
        typeof action.value === 'string' &&
        ((typeof action.ref === 'string' && action.ref.length > 0) ||
          (typeof action.label === 'string' && action.label.length > 0))
      )
    case 'select':
      return (
        typeof action.ref === 'string' &&
        action.ref.length > 0 &&
        typeof action.value === 'string'
      )
    case 'scroll':
      return action.ref === undefined || typeof action.ref === 'string'
    case 'wait':
      return action.ms === undefined || typeof action.ms === 'number'
    case 'generateOutreachReply':
      return (
        typeof action.scan_post_id === 'string' &&
        action.scan_post_id.length > 0 &&
        (action.count === undefined || typeof action.count === 'number')
      )
    case 'applyDraft':
      return (
        typeof action.value === 'string' &&
        (action.label === undefined || typeof action.label === 'string')
      )
    case 'publishOutreach':
      return (
        typeof action.scan_post_id === 'string' &&
        action.scan_post_id.length > 0 &&
        typeof action.text === 'string' &&
        action.text.length > 0 &&
        (action.confirm === undefined || typeof action.confirm === 'boolean')
      )
    case 'markHandled':
      return (
        typeof action.scan_post_id === 'string' &&
        action.scan_post_id.length > 0 &&
        (action.status === undefined ||
          action.status === 'handled' ||
          action.status === 'skipped' ||
          action.status === 'pending')
      )
    case 'expandKnowledgeGraph':
      return (
        (action.seed_query === undefined || typeof action.seed_query === 'string') &&
        (action.supplemental === undefined || typeof action.supplemental === 'boolean')
      )
    case 'toggleGraphNode':
      return typeof action.node_id === 'string' && action.node_id.length > 0 && typeof action.selected === 'boolean'
    case 'startScan':
    case 'startViralScan':
    case 'startCopyMissionAnalyze':
    case 'startCopyMissionScan':
    case 'generateCopyMatrix':
    case 'navigateToPersona8D':
      return true
    case 'generateCopyDraft':
      return typeof action.scan_post_id === 'string' && action.scan_post_id.length > 0
    case 'publishCopyDraft':
      return (
        typeof action.draft_id === 'string' &&
        action.draft_id.length > 0 &&
        (action.confirm === undefined || typeof action.confirm === 'boolean')
      )
    default:
      return false
  }
}

export function formatActionResults(results: IslanderActionResult[]): string {
  if (results.length === 0) return '（沒有執行任何操作）'
  return results
    .map((item) => {
      const status = item.ok ? 'ok' : 'failed'
      const summary = describeAction(item.action)
      return `- ${summary}: ${status}${item.detail ? ` — ${item.detail}` : ''}`
    })
    .join('\n')
}

function describeAction(action: IslanderAction): string {
  switch (action.type) {
    case 'navigate':
      return `navigate ${action.path}`
    case 'click':
      return `click ${action.ref}`
    case 'fill':
      return `fill ${action.label ?? action.ref ?? '?'}`
    case 'select':
      return `select ${action.ref}`
    case 'focus':
      return `focus ${action.ref}`
    case 'scroll':
      return action.ref ? `scroll ${action.ref}` : 'scroll page'
    case 'highlight':
      return `highlight ${action.ref}`
    case 'wait':
      return `wait ${action.ms ?? 300}ms`
    case 'generateOutreachReply':
      return `generateOutreachReply ${action.scan_post_id}`
    case 'applyDraft':
      return `applyDraft ${action.label ?? '獲客留言草稿'}`
    case 'publishOutreach':
      return `publishOutreach ${action.scan_post_id}`
    case 'markHandled':
      return `markHandled ${action.scan_post_id}`
    case 'expandKnowledgeGraph':
      return `expandKnowledgeGraph ${action.seed_query ?? '(seed)'}` 
    case 'toggleGraphNode':
      return `toggleGraphNode ${action.node_id}`
    case 'startScan':
      return 'startScan'
    case 'startViralScan':
      return 'startViralScan'
    case 'startCopyMissionAnalyze':
      return 'startCopyMissionAnalyze'
    case 'startCopyMissionScan':
      return 'startCopyMissionScan'
    case 'generateCopyMatrix':
      return 'generateCopyMatrix'
    case 'generateCopyDraft':
      return `generateCopyDraft ${action.scan_post_id}`
    case 'publishCopyDraft':
      return `publishCopyDraft ${action.draft_id}`
    case 'navigateToPersona8D':
      return 'navigateToPersona8D'
    default:
      return 'unknown'
  }
}