/**
 * 配置端自动分段的弹框状态机（spec §3.2 / §3.2.1）。
 *
 * 三种触发共用同一个 `POST /article/segment`（整篇，非单段）：
 * ① 空文本框粘贴长文 → mode='paste'
 * ② 点「自动分段」按钮 → mode='overwrite'
 * ③ 应用配置撞上 300 词硬守卫 → mode='guard'
 */
import { onScopeDispose, ref, type Ref } from 'vue'
import { lang } from '@/main'
import message from '@/utils/message'
import { segmentArticle } from '../services/articleReading'
import {
  hasOverlongParagraph,
  normalizeParagraphs,
  shouldPromptOnPaste,
} from './articleAutoFormatRules'

export type FormatDialogMode = 'paste' | 'overwrite' | 'guard'

export function useArticleAutoFormat(content: Ref<string>) {
  const dialogVisible = ref(false)
  const dialogMode = ref<FormatDialogMode>('paste')
  const isFormatting = ref(false)

  // ArticlePracticeConfig 是 v-else-if'd（真会卸载）。晚到的分段响应不能在作用域销毁后
  // 还去写 content（它是外部传入、直连 pinia store 的 computed）。
  let disposed = false
  onScopeDispose(() => {
    disposed = true
  })

  /**
   * textarea 的 @input。恒写 store —— 取消弹窗即「保留原始粘贴」。
   * 上一次的内容直接取 content.value：此刻还没写入，它就是输入前的值。
   * 不缓存到局部变量，否则 store.replaceConfig 载入已有配置后会陈旧。
   */
  function onContentInput(next: string) {
    const prev = content.value
    content.value = next
    if (shouldPromptOnPaste(prev, next)) {
      dialogMode.value = 'paste'
      dialogVisible.value = true
    }
  }

  /** 「自动分段」按钮：先弹覆盖确认，确认才调后端。 */
  function openOverwrite() {
    if (!content.value.trim() || isFormatting.value) return
    dialogMode.value = 'overwrite'
    dialogVisible.value = true
  }

  /**
   * 「应用配置」前置校验：归一化回写 + 300 词硬守卫。
   * @returns true = 放行提交；false = 已开守卫弹框，调用方必须中止提交
   */
  function guardBeforeApply(): boolean {
    if (isFormatting.value) return false // 请求进行中：不放行提交，也不误开/误改弹框状态
    const normalized = normalizeParagraphs(content.value)
    content.value = normalized
    if (!hasOverlongParagraph(normalized)) return true
    dialogMode.value = 'guard'
    dialogVisible.value = true
    return false
  }

  /** 三种弹框的确认键共用；整篇送后端，结果原样归一化后回填。 */
  async function confirmDialog() {
    if (isFormatting.value) return // 防重复（承 enspeak runAutoFormat 早退）
    const source = content.value.trim()
    if (!source) {
      // 可达路径：老师清空文本框后点确认。不能静默无反应，必须关框（否则弹框卡住）。
      dialogVisible.value = false
      return
    }

    isFormatting.value = true
    try {
      const { content: segmented } = await segmentArticle(source)
      if (disposed) return // 组件已卸载：作用域已销毁，响应作废，不再写 store
      if (content.value.trim() !== source) {
        // 30 秒等待期间老师又改了文本：新内容优先，只关框，绝不覆盖
        dialogVisible.value = false
        return
      }
      content.value = normalizeParagraphs(segmented)
      dialogVisible.value = false
    }
    catch (err: unknown) {
      if (disposed) return
      console.error('[article-reading] auto format failed:', err)
      message.error(lang.ssArticleSegmentFailed as string)
      // 守卫框保持打开：老师可原地重试或改选「手动修改」。其余两种关掉即可。
      if (dialogMode.value !== 'guard') dialogVisible.value = false
    }
    finally {
      if (!disposed) isFormatting.value = false
    }
  }

  function cancelDialog() {
    if (isFormatting.value) return
    dialogVisible.value = false
  }

  return {
    dialogVisible,
    dialogMode,
    isFormatting,
    onContentInput,
    openOverwrite,
    guardBeforeApply,
    confirmDialog,
    cancelDialog,
  }
}
