import type {
  ApprovalRequest,
  ToolApprovalsMode,
} from '#cli/core/model'
import { shouldAutoApproveRequest } from '#cli/core/store/approvals'
import { watch } from 'vue'

interface ApprovalState {
  approval: {
    active: ApprovalRequest | null
    mode: ToolApprovalsMode
  }
  runningAgentRound: boolean
}

export function createApprovalsFlow(
  opts: Readonly<{
    state: ApprovalState
    resolveActiveApproval: (decision: 'approved' | 'denied') => Promise<void>
    isInSendQueueRun: () => boolean
  }>,
): Readonly<{
  shouldAutoApproveActiveApproval: () => boolean
}> {
  const shouldAutoApproveActiveApproval = (): boolean => {
    // `send()` already handles auto-approve inline; avoid racing it with watchers.
    if (opts.isInSendQueueRun()) return false
    const active = opts.state.approval.active
    if (!active || active.status !== 'pending') return false
    if (!shouldAutoApproveRequest(opts.state.approval.mode, active))
      return false
    // Avoid concurrent resume while a stream is in-flight; wait for the agent round to finish.
    if (opts.state.runningAgentRound) return false
    return true
  }

  // If the user enables auto-approval while an approval is already pending, approve automatically.
  watch(
    () => opts.state.approval.mode,
    () => {
      if (shouldAutoApproveActiveApproval())
        void opts.resolveActiveApproval('approved')
    },
  )

  // If an agent round ends with a pending approval and auto-approval is enabled, approve automatically.
  watch(
    () => opts.state.runningAgentRound,
    (running) => {
      if (running) return
      if (shouldAutoApproveActiveApproval())
        void opts.resolveActiveApproval('approved')
    },
  )

  return { shouldAutoApproveActiveApproval }
}
