import { useState } from 'react'
import { useT } from '../i18n'
import { thumbUrl, baseName } from '../media'
import type { AssetGroup, IndexedAsset } from '@shared/types'

const VIDEO_EXTS = ['.mp4', '.mov', '.avi', '.mkv', '.webm', '.m4v']

/** 스마트 그룹화 + 자가정화 (Phase 3) */
export function GroupsView(): JSX.Element {
  const t = useT()
  const [threshold, setThreshold] = useState(0.92)
  const [groups, setGroups] = useState<AssetGroup[]>([])
  const [finding, setFinding] = useState(false)
  const [searched, setSearched] = useState(false)
  const [selected, setSelected] = useState<Set<number>>(new Set())
  const [trashing, setTrashing] = useState(false)

  const find = async () => {
    setFinding(true)
    setSearched(true)
    try {
      const g = await window.api.groups.build(threshold)
      setGroups(g)
      // 기본 선택: 각 그룹에서 보관 추천을 제외한 나머지(중복 후보)
      const pre = new Set<number>()
      for (const grp of g) {
        for (const m of grp.members) {
          if (m.id != null && m.id !== grp.bestId) pre.add(m.id)
        }
      }
      setSelected(pre)
    } finally {
      setFinding(false)
    }
  }

  const toggle = (id: number) => {
    setSelected((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }

  const trash = async () => {
    if (selected.size === 0) return
    if (!window.confirm(t('groups.confirmTrash', { n: selected.size }))) return
    setTrashing(true)
    try {
      const ids = [...selected]
      const n = await window.api.groups.trash(ids)
      // 휴지통으로 보낸 항목 제거
      const removed = new Set(ids)
      setGroups((prev) =>
        prev
          .map((g) => ({
            ...g,
            members: g.members.filter((m) => m.id == null || !removed.has(m.id))
          }))
          .filter((g) => g.members.length > 1)
      )
      setSelected(new Set())
      window.alert(t('groups.trashed', { n }))
    } finally {
      setTrashing(false)
    }
  }

  return (
    <div className="max-w-5xl mx-auto w-full flex flex-col gap-4">
      <div className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4">
        <div className="flex items-center justify-between mb-1">
          <h2 className="font-semibold dark:text-slate-100">{t('groups.section')}</h2>
          {searched && !finding && (
            <span className="text-xs text-slate-400">{t('groups.count', { n: groups.length })}</span>
          )}
        </div>
        <p className="text-[11px] text-slate-400 mb-3">{t('groups.hint')}</p>

        <div className="flex items-center gap-4">
          <label className="text-sm flex-1 max-w-xs">
            <span className="block text-xs text-slate-500 dark:text-slate-400 mb-1">
              {t('groups.threshold', { v: threshold.toFixed(2) })}
            </span>
            <input
              type="range"
              min={0.8}
              max={0.99}
              step={0.01}
              value={threshold}
              onChange={(e) => setThreshold(Number(e.target.value))}
              className="w-full"
            />
          </label>
          <button
            className="bg-brand hover:bg-brand-dark text-white rounded-lg px-4 py-2 font-semibold disabled:opacity-40"
            onClick={find}
            disabled={finding}
          >
            {finding ? t('groups.finding') : t('groups.find')}
          </button>
          {selected.size > 0 && (
            <button
              className="bg-red-500 hover:bg-red-600 text-white rounded-lg px-4 py-2 font-semibold disabled:opacity-40 ml-auto"
              onClick={trash}
              disabled={trashing}
            >
              🗑 {t('groups.trashSelected', { n: selected.size })}
            </button>
          )}
        </div>
      </div>

      {searched && !finding && groups.length === 0 && (
        <p className="text-sm text-slate-400">{t('groups.empty')}</p>
      )}

      {groups.map((g, gi) => (
        <div
          key={gi}
          className="bg-white dark:bg-slate-800 rounded-xl border border-slate-200 dark:border-slate-700 p-4"
        >
          <div className="text-xs text-slate-400 mb-2">
            {t('groups.groupSize', { n: g.members.length })}
          </div>
          <div className="grid grid-cols-6 gap-2">
            {g.members.map((m) => (
              <GroupTile
                key={m.contentHash}
                asset={m}
                isBest={m.id === g.bestId}
                checked={m.id != null && selected.has(m.id)}
                keepLabel={t('groups.keep')}
                onToggle={() => m.id != null && toggle(m.id)}
              />
            ))}
          </div>
        </div>
      ))}
    </div>
  )
}

function GroupTile(props: {
  asset: IndexedAsset
  isBest: boolean
  checked: boolean
  keepLabel: string
  onToggle: () => void
}): JSX.Element {
  const { asset: a, isBest, checked } = props
  const isVideo = VIDEO_EXTS.includes(a.ext)
  return (
    <div
      className={`relative aspect-square rounded-md overflow-hidden border-2 bg-slate-100 dark:bg-slate-700 ${
        isBest ? 'border-emerald-500' : checked ? 'border-red-400' : 'border-transparent'
      }`}
      title={a.path}
    >
      {isVideo ? (
        <div className="w-full h-full flex items-center justify-center text-slate-400 text-xs">▶</div>
      ) : (
        <img
          src={thumbUrl(a.contentHash)}
          alt={baseName(a.path)}
          className="w-full h-full object-cover"
          loading="lazy"
        />
      )}
      {isBest ? (
        <span className="absolute bottom-0.5 left-0.5 text-[9px] font-semibold text-white rounded px-1 py-0.5 bg-emerald-500/90">
          ★ {props.keepLabel}
        </span>
      ) : (
        <button
          className="absolute top-1 right-1 w-5 h-5 rounded bg-black/50 flex items-center justify-center"
          onClick={props.onToggle}
          title={a.path}
        >
          <span className={`text-xs ${checked ? 'text-red-400' : 'text-white/60'}`}>
            {checked ? '✓' : '○'}
          </span>
        </button>
      )}
    </div>
  )
}
