import { useState, useCallback, useMemo } from "react" import type { PipConfig, PipLayer, PipGridPosition } from "../../../types" import { DEFAULT_PIP_LAYER, DEFAULT_PIP_CONFIG } from "../../../types" import { GRID_POSITION_MAP, genLayerId } from "../constants" const MIN_DIMENSION = 10 const MAX_DIMENSION = 80 interface UsePipConfigPanelOptions { config: PipConfig onChange: (config: PipConfig) => void } export const usePipConfigPanel = ({ config, onChange }: UsePipConfigPanelOptions) => { const [selectedId, setSelectedId] = useState("") const selectedLayer = useMemo( () => config.layers.find((l) => l.id === selectedId) ?? null, [config.layers, selectedId], ) /* ── 添加图层 ── */ const handleAddLayer = useCallback(() => { const newLayer: PipLayer = { ...DEFAULT_PIP_LAYER, id: genLayerId(), name: `图层 ${config.layers.length + 1}`, z_index: config.layers.length + 1, } onChange({ ...config, layers: [...config.layers, newLayer], }) setSelectedId(newLayer.id) }, [config, onChange]) /* ── 删除图层 ── */ const handleDeleteLayer = useCallback( (id: string) => { const newLayers = config.layers.filter((l) => l.id !== id) onChange({ ...config, layers: newLayers }) if (selectedId === id) { setSelectedId(newLayers.length > 0 ? newLayers[0].id : "") } }, [config, onChange, selectedId], ) /* ── 更新图层 ── */ const updateLayer = useCallback( (id: string, partial: Partial) => { onChange({ ...config, layers: config.layers.map((l) => (l.id === id ? { ...l, ...partial } : l)), }) }, [config, onChange], ) /* ── 切换启用 ── */ const handleEnableToggle = useCallback( (checked: boolean) => { onChange({ ...config, enabled: checked }) }, [config, onChange], ) /* ── 重置 ── */ const handleReset = useCallback(() => { onChange({ ...DEFAULT_PIP_CONFIG }) setSelectedId("") }, [onChange]) /* ── 九宫格点击 ── */ const handleGridClick = useCallback( (pos: PipGridPosition) => { if (!selectedLayer) return const coords = GRID_POSITION_MAP[pos] updateLayer(selectedLayer.id, { grid_position: pos, x: coords.x, y: coords.y, }) }, [selectedLayer, updateLayer], ) /* ── 宽高变化 ── */ const handleWidthChange = useCallback( (val: number) => { if (!selectedLayer) return const partial: Partial = { width: val } if (selectedLayer.aspect_lock && selectedLayer.height > 0) { const ratio = selectedLayer.width / selectedLayer.height const newHeight = Math.round(val / ratio) partial.height = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newHeight)) } updateLayer(selectedLayer.id, partial) }, [selectedLayer, updateLayer], ) const handleHeightChange = useCallback( (val: number) => { if (!selectedLayer) return const partial: Partial = { height: val } if (selectedLayer.aspect_lock && selectedLayer.width > 0 && selectedLayer.height > 0) { const ratio = selectedLayer.width / selectedLayer.height const newWidth = Math.round(val * ratio) partial.width = Math.max(MIN_DIMENSION, Math.min(MAX_DIMENSION, newWidth)) } updateLayer(selectedLayer.id, partial) }, [selectedLayer, updateLayer], ) return { selectedId, setSelectedId, selectedLayer, handleAddLayer, handleDeleteLayer, updateLayer, handleEnableToggle, handleReset, handleGridClick, handleWidthChange, handleHeightChange, } }