import { useState, useMemo } from 'react' import { AlertTriangle } from 'lucide-react' import { cn } from '@/lib' import { numberToKorean } from '@/features/chat/lib/koreanNumber' import { useChatStore } from '@/features/chat/stores/useChatStore' import { useChatInitStore } from '@/features/chat/stores/useChatInitStore' import { SelectRadio, SubmitButton } from '@/features/chat/components/templates/rejectControls' import { OtherReason } from '@/features/chat/components/templates/OtherReason' import { findRestoreScript, restoreRejectRSP, extractPart } from '@/features/chat/lib/rejectForm' const MAX_PRICE = 999999999999999 // 합의 불가 사유 프리셋 (rejectRSP 와 동일 목록) const REASONS = [ { value: '단가인상', text: "'원재료 가격 상승' 또는 '제조사 가격 인상'으로 요청한 공급가격을 맞출 수 없습니다." }, { value: '수량', text: '주문 수량이 적어, 소량 생산 시 발생하는 제조비용으로 맞출 수 없습니다.' }, { value: '단종', text: '현재 단종된 제품으로 물량 수급이 원활하지 않아 가격을 맞출 수 없습니다.' }, { value: '품절', text: '해당 상품이 품절되어 납품할 수 없습니다.' }, ] // 통일된 협상 결렬 폼 — 최종 제안 단가 + 합의 불가 사유 + 의견. // rejectRSP / rejectCM 두 유형 모두 이 폼 하나로 받는다(액션바 렌더). export function RejectForm() { const isLoading = useChatStore((s) => s.isLoading) const sendMessage = useChatStore((s) => s.sendMessage) const messages = useChatStore((s) => s.messages) const item_vat_yn = useChatInitStore((s) => s.item_vat_yn) const isVAT = item_vat_yn === 'VAT별도' // 직전 제출 내역에서 1회 복원 (rejectRSP/rejectCM 어느 유형이든). const priorScript = useState( () => findRestoreScript(messages, 'rejectRSP') ?? findRestoreScript(messages, 'rejectCM'), )[0] const restored = useState(() => restoreRejectRSP(priorScript))[0] const [price, setPrice] = useState(restored.price) const [selectedReason, setSelectedReason] = useState(restored.selectedReason) const [reason, setReason] = useState(restored.reason) const [opinion, setOpinion] = useState(() => extractPart(priorScript, '의견-')) const [otherErrorMessage, setOtherErrorMessage] = useState('') const [priceErrorMessage, setPriceErrorMessage] = useState('') const [radioErrorMessage, setRadioErrorMessage] = useState('') const isSubmitted = useMemo( () => Boolean(findRestoreScript(messages, 'rejectRSP') ?? findRestoreScript(messages, 'rejectCM')), [messages], ) // 사유는 필수(20번), 의견은 선택(18번). const isValid = Boolean(price && parseInt(price) > 0) && Boolean(selectedReason) && (selectedReason !== '기타' || reason.trim() !== '') const handlePriceChange = (value: string) => { const numeric = value.replace(/\D/g, '') if (numeric && parseInt(numeric) > MAX_PRICE) return setPrice(numeric) if (numeric) setPriceErrorMessage('') } const handleRadioChange = (value: string) => { setSelectedReason(value) setRadioErrorMessage('') if (value !== '기타') { setReason('') setOtherErrorMessage('') } } const koreanPrice = (() => { if (!price) return '영' const n = parseInt(price) return Number.isNaN(n) || n === 0 ? '영' : numberToKorean(n) })() const handleSubmit = () => { setPriceErrorMessage(!price || parseInt(price) === 0 ? '가격을 입력해주세요.' : '') setRadioErrorMessage(!selectedReason ? '사유를 선택해주세요.' : '') setOtherErrorMessage(selectedReason === '기타' && !reason.trim() ? '기타 사유를 입력해주세요.' : '') if (isValid && !isLoading && !isSubmitted) { const reasonPart = selectedReason === '기타' ? `합의불가사유-기타-${reason.trim()}` : `합의불가사유-${selectedReason}` const script = `공급희망가격-${price}, ${reasonPart}, 의견-${opinion.trim()}` sendMessage(script, 'text') } } const isDisabled = isLoading || isSubmitted return (