import { useCallback, useEffect, useState } from 'react'
import {
  injectRule,
  listInjectedRules,
  readClaudeMd,
  readInjectedRule,
  removeInjectedRule,
  ruleSlug,
  setRuleEnabled,
  writeClaudeMd
} from '../ipc'
import type { Config, InjectedRule } from '../types'
import { ConfirmDialog, Modal } from './Modal'
import { IconPlus, IconRefresh, IconTrash } from './Icons'

interface Props {
  projectPath: string
  config: Config
}

/** 项目规则页：已注入规则的启停/移除 + CLAUDE.md 直接编辑 */
export function ProjectRulesView({ projectPath, config }: Props) {
  const [injected, setInjected] = useState<InjectedRule[]>([])
  const [claudeMd, setClaudeMd] = useState('')
  const [savedMd, setSavedMd] = useState('')
  const [picking, setPicking] = useState(false)
  const [removing, setRemoving] = useState<InjectedRule | null>(null)
  const [notice, setNotice] = useState('')

  const refresh = useCallback(async () => {
    setInjected(await listInjectedRules(projectPath))
    const md = await readClaudeMd(projectPath)
    setClaudeMd(md)
    setSavedMd(md)
  }, [projectPath])

  useEffect(() => {
    void refresh()
  }, [refresh])

  const flashNotice = (text: string) => {
    setNotice(text)
    setTimeout(() => setNotice(''), 4000)
  }

  const toggle = async (rule: InjectedRule) => {
    await setRuleEnabled(projectPath, rule.slug, !rule.enabled)
    await refresh()
    flashNotice('规则改动对已运行的会话不生效，需要新开会话')
  }

  const doInject = async (ruleId: string) => {
    await injectRule(projectPath, ruleId)
    setPicking(false)
    await refresh()
    flashNotice('已注入。规则对新开的会话生效；若项目是 git 仓库且不想提交规则，请自行忽略 .claude/rules/')
  }

  const mdDirty = claudeMd !== savedMd

  return (
    <div className="page">
      <h2>项目规则</h2>
      <p className="page-desc">{projectPath}\CLAUDE.md</p>
      {notice && (
        <div
          style={{
            padding: '6px 10px',
            marginBottom: 10,
            borderRadius: 4,
            background: 'var(--accent-dim)',
            fontSize: 12.5
          }}
        >
          {notice}
        </div>
      )}

      <div className="toolbar">
        <button className="btn primary" onClick={() => setPicking(true)}>
          <IconPlus />
          从规则库注入
        </button>
        <button className="btn" title="刷新" onClick={() => void refresh()}>
          <IconRefresh />
        </button>
      </div>

      <div className="row-list" style={{ marginBottom: 18 }}>
        {injected.length === 0 && <div className="empty-hint">还没有注入任何规则</div>}
        {injected.map((rule) => (
          <div key={rule.slug} className="row">
            <button
              className={`switch ${rule.enabled ? 'on' : ''}`}
              title={rule.enabled ? '已启用（CLAUDE.md 中存在引用行）' : '已停用（保留规则文件）'}
              onClick={() => void toggle(rule)}
            />
            <div className="row-main">
              <div className="row-title">{rule.slug}</div>
              <div className="row-sub">.claude/rules/{rule.slug}.md</div>
            </div>
            <div className="row-actions">
              <button
                className="btn small danger"
                title="彻底移除（删除引用行和规则文件）"
                onClick={() => setRemoving(rule)}
              >
                <IconTrash />
              </button>
            </div>
          </div>
        ))}
      </div>

      <h2 style={{ fontSize: 14 }}>CLAUDE.md</h2>
      <p className="page-desc">
        直接编辑项目记忆文件。上方开关操作的 @ 引用行也会出现在这里，注意不要手动破坏。
      </p>
      <textarea
        className="input"
        style={{ width: '100%', minHeight: 260 }}
        value={claudeMd}
        placeholder="（文件不存在或为空）"
        onChange={(e) => setClaudeMd(e.target.value)}
      />
      <div className="toolbar" style={{ marginTop: 8 }}>
        <button
          className="btn primary"
          disabled={!mdDirty}
          onClick={async () => {
            await writeClaudeMd(projectPath, claudeMd)
            setSavedMd(claudeMd)
            void refresh()
            flashNotice('已保存。对新开的会话生效')
          }}
        >
          保存 CLAUDE.md
        </button>
        {mdDirty && <span style={{ color: 'var(--warn)', fontSize: 12 }}>有未保存的修改</span>}
      </div>

      {picking && (
        <RulePicker
          config={config}
          projectPath={projectPath}
          injected={injected}
          onPick={(id) => void doInject(id)}
          onClose={() => setPicking(false)}
        />
      )}

      {removing && (
        <ConfirmDialog
          title="移除注入的规则"
          message={`将删除 CLAUDE.md 中的引用行和文件 .claude/rules/${removing.slug}.md。\n规则库中的原始规则不受影响。`}
          confirmText="移除"
          danger
          onCancel={() => setRemoving(null)}
          onConfirm={async () => {
            await removeInjectedRule(projectPath, removing.slug)
            setRemoving(null)
            await refresh()
          }}
        />
      )}
    </div>
  )
}

interface PickerProps {
  config: Config
  projectPath: string
  injected: InjectedRule[]
  onPick: (ruleId: string) => void
  onClose: () => void
}

function RulePicker({ config, projectPath, injected, onPick, onClose }: PickerProps) {
  const [slugs, setSlugs] = useState<Record<string, string>>({})

  // 预先算出每条规则的 slug，用于标记"已注入/内容有差异"
  useEffect(() => {
    void (async () => {
      const map: Record<string, string> = {}
      for (const rule of config.rules) {
        map[rule.id] = await ruleSlug(rule.name)
      }
      setSlugs(map)
    })()
  }, [config.rules])

  const [diffs, setDiffs] = useState<Record<string, boolean>>({})
  useEffect(() => {
    void (async () => {
      const map: Record<string, boolean> = {}
      for (const rule of config.rules) {
        const slug = slugs[rule.id]
        if (slug && injected.some((i) => i.slug === slug)) {
          const current = await readInjectedRule(projectPath, slug)
          map[rule.id] = current !== rule.content
        }
      }
      setDiffs(map)
    })()
  }, [slugs, injected, config.rules, projectPath])

  const catName = (id: string | null) =>
    config.ruleCategories.find((c) => c.id === id)?.name ?? '未分类'

  return (
    <Modal
      title="从规则库注入"
      width={560}
      onClose={onClose}
      footer={<button className="btn" onClick={onClose}>关闭</button>}
    >
      <div className="row-list">
        {config.rules.length === 0 && (
          <div className="empty-hint">规则库为空，先到「规则库」页创建规则</div>
        )}
        {config.rules.map((rule) => {
          const slug = slugs[rule.id]
          const already = !!slug && injected.some((i) => i.slug === slug)
          const changed = diffs[rule.id]
          return (
            <div key={rule.id} className="row">
              <div className="row-main">
                <div className="row-title">
                  {rule.name} <span className="badge">{catName(rule.categoryId)}</span>{' '}
                  {already && <span className="badge accent">{changed ? '已注入·内容有更新' : '已注入'}</span>}
                </div>
                <div className="row-sub">{rule.content}</div>
              </div>
              <div className="row-actions">
                <button className="btn small primary" onClick={() => onPick(rule.id)}>
                  {already ? '重新注入' : '注入'}
                </button>
              </div>
            </div>
          )
        })}
      </div>
    </Modal>
  )
}
