'use client';

import { useRef } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrash, faUpload } from '@fortawesome/free-solid-svg-icons';
import type { AlertConfigItem } from '@/types/response/donation/alertConfig';
import { Checkbox } from '@/components/ui/checkbox';
import { POPUP_EFFECTS, TEXT_EFFECTS, FONT_OPTIONS, MATCH_TYPES } from '../constants';
import type { FormState, PendingFiles } from '../types';
import {
	ALERT_TITLE_MAX_LENGTH, ALERT_MESSAGE_MAX_LENGTH, ALERT_AMOUNT_MIN,
	ALERT_DELAY_MIN, ALERT_DELAY_MAX, ALERT_DELAY_STEP,
	ALERT_DURATION_MIN, ALERT_DURATION_MAX, ALERT_DURATION_STEP,
	FONT_SIZE_MIN, FONT_SIZE_MAX, COLOR_HEX_MAX_LENGTH
} from '@/constants/donation';

type Props = {
	form: FormState;
	editingItem: AlertConfigItem|null;
	saving: boolean;
	pendingFiles: PendingFiles;
	onFileSelect: (file: File, type: 'image'|'sound') => void;
	onFormChange: <K extends keyof FormState>(field: K, value: FormState[K]) => void;
	onSave: () => void;
	onCancel: () => void;
};

export default function AlertFormPanel({
	form,
	editingItem,
	saving,
	pendingFiles,
	onFileSelect,
	onFormChange,
	onSave,
	onCancel
}: Props) {
	const imageInputRef = useRef<HTMLInputElement>(null);
	const soundInputRef = useRef<HTMLInputElement>(null);

	// ── 폰트 그룹 렌더러 ─────────────────────────────
	const renderFontGroup = (
		label: string,
		prefix: string,
		familyField: 'nicknameFontFamily'|'amountFontFamily'|'messageFontFamily'|'templateFontFamily',
		sizeField: 'nicknameFontSize'|'amountFontSize'|'messageFontSize'|'templateFontSize',
		colorField: 'nicknameFontColor'|'amountFontColor'|'messageFontColor'|'templateFontColor',
		defaultSize: number
	) => (
		<div className="alert-config__font-group">
			<div className="alert-config__font-group-title">{label}</div>
			<div className="alert-config__font-grid">
				<div className="alert-config__field">
					<label htmlFor={`${prefix}-family`} className="alert-config__field-label">글꼴</label>
					<select
						id={`${prefix}-family`}
						className="alert-config__select"
						value={form[familyField] ?? ''}
						onChange={e => onFormChange(familyField, e.target.value || null)}
					>
						{FONT_OPTIONS.map(f => (
							<option key={f.value} value={f.value}>{f.label}</option>
						))}
					</select>
				</div>
				<div className="alert-config__field">
					<label htmlFor={`${prefix}-size`} className="alert-config__field-label">크기 (px)</label>
					<input
						id={`${prefix}-size`}
						type="number"
						className="alert-config__input"
						min={FONT_SIZE_MIN}
						max={FONT_SIZE_MAX}
						value={form[sizeField]}
						onChange={e => onFormChange(sizeField, parseInt(e.target.value) || defaultSize)}
						title='Font Size'
					/>
				</div>
				<div className="alert-config__field">
					<label htmlFor={`${prefix}-color`} className="alert-config__field-label">색상</label>
					<div className="alert-config__color-wrap">
						<input
							id={`${prefix}-color`}
							type="color"
							className="alert-config__color-input"
							value={form[colorField]}
							onChange={e => onFormChange(colorField, e.target.value)}
						/>
						<input
							type="text"
							className="alert-config__input alert-config__color-text"
							value={form[colorField]}
							onChange={e => onFormChange(colorField, e.target.value)}
							maxLength={COLOR_HEX_MAX_LENGTH}
							title='Font Color'
						/>
					</div>
				</div>
			</div>
		</div>
	);

	return (
		<main className="alert-config__form-panel">
			{/* ── 기본 설정 ────────────────────────────── */}
			<section className="alert-config__section">
				<h3 className="alert-config__section-title">기본 설정</h3>
				<div className="alert-config__section-body">
					<div className="alert-config__field">
						<label htmlFor="config-title" className="alert-config__field-label">제목</label>
						<input
							id="config-title"
							type="text"
							className="alert-config__input"
							value={form.title}
							onChange={e => onFormChange('title', e.target.value)}
							placeholder="알림 제목 (선택)"
							maxLength={ALERT_TITLE_MAX_LENGTH}
						/>
					</div>

					<div className="alert-config__field-row">
						<div className="alert-config__field">
							<label htmlFor="config-amount" className="alert-config__field-label">금액 (원)</label>
							<input
								id="config-amount"
								type="number"
								className="alert-config__input"
								min={ALERT_AMOUNT_MIN}
								value={form.amount}
								onChange={e => onFormChange('amount', parseInt(e.target.value) || 0)}
							/>
						</div>
						<div className="alert-config__field">
							<label className="alert-config__field-label">조건</label>
							<div className="alert-config__radio-group">
								{MATCH_TYPES.map(mt => (
									<label key={mt.value} className="alert-config__radio-label">
										<input
											type="radio"
											name="matchType"
											value={mt.value}
											checked={form.matchType === mt.value}
											onChange={() => onFormChange('matchType', mt.value)}
										/>
										{mt.label}
									</label>
								))}
							</div>
						</div>
					</div>

					<div className="alert-config__field">
						<label htmlFor="config-message" className="alert-config__field-label">메시지</label>
						<input
							id="config-message"
							type="text"
							className="alert-config__input"
							value={form.message}
							onChange={e => onFormChange('message', e.target.value)}
							placeholder="{이름}님이 {금액}원을 후원했습니다!"
							maxLength={ALERT_MESSAGE_MAX_LENGTH}
						/>
						<span className="alert-config__field-hint">
							사용 가능한 변수: {'{이름}'}, {'{금액}'}
						</span>
					</div>

					<div className="alert-config__field-row">
						<div className="alert-config__field">
							<label htmlFor="config-play-delay" className="alert-config__field-label">재생 지연 (초)</label>
							<input
								id="config-play-delay"
								type="number"
								className="alert-config__input"
								min={ALERT_DELAY_MIN}
								max={ALERT_DELAY_MAX}
								step={ALERT_DELAY_STEP}
								value={form.playDelaySec}
								onChange={e => onFormChange('playDelaySec', parseFloat(e.target.value) || 0)}
							/>
						</div>
						<div className="alert-config__field">
							<label htmlFor="config-display-duration" className="alert-config__field-label">노출 시간 (초)</label>
							<input
								id="config-display-duration"
								type="number"
								className="alert-config__input"
								min={ALERT_DURATION_MIN}
								max={ALERT_DURATION_MAX}
								step={ALERT_DURATION_STEP}
								value={form.displayDurationSec}
								onChange={e => onFormChange('displayDurationSec', parseFloat(e.target.value) || 0)}
							/>
						</div>
					</div>

					<div className="alert-config__field">
						<label htmlFor="config-is-active" className="alert-config__checkbox-label">
							<Checkbox
								id="config-is-active"
								checked={form.isActive}
								onCheckedChange={v => onFormChange('isActive', !!v)}
							/>
							알림을 사용합니다.
						</label>
					</div>
				</div>
			</section>

			{/* ── 효과 ────────────────────────────────── */}
			<section className="alert-config__section">
				<h3 className="alert-config__section-title">효과</h3>
				<div className="alert-config__section-body">
					<div className="alert-config__field-row">
						<div className="alert-config__field">
							<label htmlFor="config-popup-effect" className="alert-config__field-label">팝업 효과</label>
							<select
								id="config-popup-effect"
								className="alert-config__select"
								value={form.popupEffect ?? ''}
								onChange={e => onFormChange('popupEffect', e.target.value || null)}
							>
								{POPUP_EFFECTS.map(e => (
									<option key={e.value} value={e.value}>{e.label}</option>
								))}
							</select>
						</div>
						<div className="alert-config__field">
							<label htmlFor="config-text-effect" className="alert-config__field-label">텍스트 효과</label>
							<select
								id="config-text-effect"
								className="alert-config__select"
								value={form.textEffect ?? ''}
								onChange={e => onFormChange('textEffect', e.target.value || null)}
							>
								{TEXT_EFFECTS.map(e => (
									<option key={e.value} value={e.value}>{e.label}</option>
								))}
							</select>
						</div>
					</div>
				</div>
			</section>

			{/* ── 폰트 ────────────────────────────────── */}
			<section className="alert-config__section">
				<h3 className="alert-config__section-title">폰트</h3>
				<div className="alert-config__section-body">
					{renderFontGroup('이름', 'font-nickname', 'nicknameFontFamily', 'nicknameFontSize', 'nicknameFontColor', 24)}
					{renderFontGroup('금액', 'font-amount', 'amountFontFamily', 'amountFontSize', 'amountFontColor', 24)}
					{renderFontGroup('보낼 내용', 'font-message', 'messageFontFamily', 'messageFontSize', 'messageFontColor', 18)}
					{renderFontGroup('알림 문구', 'font-template', 'templateFontFamily', 'templateFontSize', 'templateFontColor', 24)}
				</div>
			</section>

			{/* ── 미디어 ───────────────────────────────── */}
			<section className="alert-config__section">
				<h3 className="alert-config__section-title">미디어</h3>
				<div className="alert-config__section-body">

					{/* 이미지 */}
					<div className="alert-config__field">
						<label htmlFor="config-enable-image" className="alert-config__checkbox-label">
							<Checkbox
								id="config-enable-image"
								checked={form.enableImage}
								onCheckedChange={v => onFormChange('enableImage', !!v)}
							/>
							이미지 사용
						</label>
					</div>

					{form.enableImage && (
						<div className="alert-config__media-upload">
							{form.imageUrl && (
								<div className="alert-config__media-preview">
									<img src={form.imageUrl} alt="알림 이미지" />
									<button
										type="button"
										className="alert-config__media-remove"
										onClick={() => onFormChange('imageUrl', null)}
										title="삭제"
									>
										<FontAwesomeIcon icon={faTrash} />
									</button>
								</div>
							)}
							<input
								ref={imageInputRef}
								type="file"
								accept=".jpg,.jpeg,.png,.gif"
								className="alert-config__file-hidden"
								onChange={e => {
									const file = e.target.files?.[0];
									if (file) onFileSelect(file, 'image');
									e.target.value = '';
								}}
								title='이미지 첨부'
							/>
							<button
								type="button"
								className="alert-config__btn"
								onClick={() => imageInputRef.current?.click()}
								disabled={saving}
							>
								<FontAwesomeIcon icon={faUpload} />
								이미지 선택
							</button>
							{pendingFiles.image && (
								<span className="alert-config__field-hint">{pendingFiles.image.name}</span>
							)}
							<span className="alert-config__field-hint">JPG, PNG, GIF (최대 20MB)</span>
						</div>
					)}

					{/* 사운드 */}
					<div className="alert-config__field">
						<label htmlFor="config-enable-sound" className="alert-config__checkbox-label">
							<Checkbox
								id="config-enable-sound"
								checked={form.enableSound}
								onCheckedChange={v => onFormChange('enableSound', !!v)}
							/>
							사운드 사용
						</label>
					</div>
					{form.enableSound && (
						<div className="alert-config__media-upload">
							{form.soundUrl && (
								<div className="alert-config__media-preview alert-config__media-preview--audio">
									<audio controls src={form.soundUrl} />
									<button
										type="button"
										className="alert-config__media-remove"
										onClick={() => onFormChange('soundUrl', null)}
										title="삭제"
									>
										<FontAwesomeIcon icon={faTrash} />
									</button>
								</div>
							)}
							<input
								ref={soundInputRef}
								type="file"
								accept=".mp3,.ogg,.wav,.m4a"
								className="alert-config__file-hidden"
								onChange={e => {
									const file = e.target.files?.[0];
									if (file) onFileSelect(file, 'sound');
									e.target.value = '';
								}}
								title='사운드 첨부'
							/>
							<button
								type="button"
								className="alert-config__btn"
								onClick={() => soundInputRef.current?.click()}
								disabled={saving}
							>
								<FontAwesomeIcon icon={faUpload} />
								사운드 선택
							</button>
							{pendingFiles.sound && (
								<span className="alert-config__field-hint">{pendingFiles.sound.name}</span>
							)}
							<span className="alert-config__field-hint">MP3, OGG, WAV, M4A (최대 50MB)</span>
						</div>
					)}
				</div>
			</section>

			{/* ── 하단 버튼 ────────────────────────────── */}
			<div className="alert-config__form-footer flex-1 w-full sm:justify-end gap-2">
				<button type="button" className="alert-config__btn flex-1 sm:flex-none" onClick={onCancel}>
					취소
				</button>
				<button
					type="button"
					className="alert-config__btn alert-config__btn--primary flex-1 sm:flex-none"
					onClick={onSave}
					disabled={saving}
				>
					{saving ? '저장 중...' : (editingItem ? '수정하기' : '등록하기')}
				</button>
			</div>
		</main>
	);
}