'use client';

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { fetchApi } from '@/lib/utils/client';
import { useStudioContext } from '@/app/studio/context';
import { useCrewWidgetConfigContext } from '../context';
import { CREW_WIDGET_THEMES, CREW_PERIODS, FONT_FAMILIES } from '../constants';
import { type FormState, createEmptyForm, formatInput, parseInput } from '../types';
import type { CrewWidgetConfigItem } from '@/types/response/crew/widgetConfig';
import { Checkbox } from '@/components/ui/checkbox';

type CrewListItem = { id: number; name: string };

/** 색상 입력 (color picker + hex text) */
function ColorInput({ value, onChange }: { value: string; onChange: (v: string) => void }) {
	return (
		<div className="crew-widget-form__color-field">
			<input
				type="color"
				className="crew-widget-form__color-picker"
				value={value}
				onChange={e => onChange(e.target.value)}
			/>
			<input
				type="text"
				className="crew-widget-form__input crew-widget-form__input--color-text"
				value={value}
				onChange={e => onChange(e.target.value)}
				maxLength={7}
			/>
		</div>
	);
}

type Props = {
	editItem?: CrewWidgetConfigItem;
	form?: FormState;
	onFormChange?: (form: FormState) => void;
	onSaved?: () => void;
	onCancel?: () => void;
	channelID?: number;
	saving?: boolean;
	setSaving?: (v: boolean) => void;
};

export default function CrewWidgetFormPanel({ editItem, form: externalForm, onFormChange, onSaved, onCancel, channelID: directChannelID, saving: directSaving, setSaving: directSetSaving }: Props)
{
	const router = useRouter();
	const studio = useStudioContext();
	const channelID = directChannelID ?? studio.channelID;

	// context 사용 가능 여부에 따라 분기
	let ctxSaving = false;
	let ctxSetSaving: (v: boolean) => void = () => {};
	let ctxFetchList: () => void = () => {};

	try {
		const ctx = useCrewWidgetConfigContext();
		ctxSaving = ctx.saving;
		ctxSetSaving = ctx.setSaving;
		ctxFetchList = ctx.fetchList;
	} catch {

	}

	const saving = directSaving ?? ctxSaving;
	const setSaving = directSetSaving ?? ctxSetSaving;
	const fetchList = ctxFetchList;

	const [internalForm, setInternalForm] = useState<FormState>(createEmptyForm());
	const form = externalForm ?? internalForm;
	const [crews, setCrews] = useState<CrewListItem[]>([]);

	// 채널의 활성 Crew 목록 로드
	useEffect(() => {
		if (!channelID) {
			return;
		}
		fetchApi<{ list: CrewListItem[] }>(`/api/crew?channelID=${channelID}`, { silent: true }).then(res => {
			if (res.data?.list) {
				setCrews(res.data.list);
				if (!editItem && res.data.list.length > 0 && form.crewID === 0) {
					if (onFormChange) {
						onFormChange({ ...form, crewID: res.data.list[0].id, crewName: res.data.list[0].name });
					} else {
						setInternalForm(prev => ({ ...prev, crewID: res.data!.list[0].id, crewName: res.data!.list[0].name }));
					}
				}
			}
		}).catch(() => {});
	}, [channelID]);

	useEffect(() => {
		if (!editItem) {
			return;
		}

		const data: FormState = {
			crewID: editItem.crewID,
			crewName: editItem.crewName,
			title: editItem.title,
			theme: editItem.theme,
			period: editItem.period,
			startAt: editItem.startAt,
			endAt: editItem.endAt,
			maxDisplayCount: editItem.maxDisplayCount,
			isShowAmount: editItem.isShowAmount,
			isShowDonationCount: editItem.isShowDonationCount,
			isShowContributionRate: editItem.isShowContributionRate,
			isShowMemberIcon: editItem.isShowMemberIcon,
			isActive: editItem.isActive,
			bgColor: editItem.bgColor,
			titleFontFamily: editItem.titleFontFamily,
			titleFontSizePx: editItem.titleFontSizePx,
			titleFontColor: editItem.titleFontColor,
			rank1FontFamily: editItem.rank1FontFamily,
			rank1FontSizePx: editItem.rank1FontSizePx,
			rank1FontColor: editItem.rank1FontColor,
			rank2FontFamily: editItem.rank2FontFamily,
			rank2FontSizePx: editItem.rank2FontSizePx,
			rank2FontColor: editItem.rank2FontColor,
			rank3FontFamily: editItem.rank3FontFamily,
			rank3FontSizePx: editItem.rank3FontSizePx,
			rank3FontColor: editItem.rank3FontColor,
			rowFontFamily: editItem.rowFontFamily,
			rowFontSizePx: editItem.rowFontSizePx,
			rowFontColor: editItem.rowFontColor
		};

		if (onFormChange) {
			onFormChange(data);
		} else {
			setInternalForm(data);
		}
	}, [editItem]);

	const set = (key: keyof FormState, value: FormState[keyof FormState]) => {
		const updater = (f: FormState): FormState => ({ ...f, [key]: value });
		if (onFormChange) {
			onFormChange(updater(form));
		} else {
			setInternalForm(updater);
		}
	};

	const handleSave = async () => {
		if (!form.crewID || form.crewID === 0) {
			alert('크루를 선택해 주세요.');
			return;
		}
		if (!form.title.trim()) {
			alert('제목을 입력해 주세요.');
			return;
		}

		if (form.period === 5) {
			if (!form.startAt || !form.endAt) {
				alert('사용자 지정 기간을 입력해 주세요.');
				return;
			}
		}

		setSaving(true);

		try {

			await fetchApi('/api/studio/crew/widget/config', {
				method: 'POST',
				body: { ...form, channelID, id: editItem?.id ?? undefined }
			});

			fetchList();

			if (onSaved) {
				onSaved();
			} else {
				router.push('/studio/donation/crew/widget/list');
			}

		} catch (err: unknown) {
			alert(err instanceof Error ? err.message : '저장에 실패했습니다.');
		} finally {
			setSaving(false);
		}
	};

	const renderFontFields = (prefix: string) =>
	{
		const familyKey = `${prefix}FontFamily` as keyof FormState;
		const sizeKey = `${prefix}FontSizePx` as keyof FormState;
		const colorKey = `${prefix}FontColor` as keyof FormState;

		return (
			<>
				<div className="crew-widget-form__field">
					<label className="crew-widget-form__field-label">글꼴</label>
					<select
						className="crew-widget-form__select"
						aria-label="글꼴"
						value={(form[familyKey] as string) ?? ''}
						onChange={e => set(familyKey, e.target.value || null)}
					>
						{FONT_FAMILIES.map(f => <option key={f.value} value={f.value}>{f.label}</option>)}
					</select>
				</div>
				<div className="crew-widget-form__row">
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__field-label">크기(px)</label>
						<input
							type="number"
							className="crew-widget-form__input"
							min={10}
							max={48}
							value={form[sizeKey] as number}
							onChange={e => set(sizeKey, Number(e.target.value))}
						/>
					</div>
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__field-label">색상</label>
						<ColorInput
							value={form[colorKey] as string}
							onChange={v => set(colorKey, v)}
						/>
					</div>
				</div>
			</>
		);
	};

	const renderFontDetails = (label: string, prefix: string) => {
		return (
			<details className="crew-widget-form__details">
				<summary className="crew-widget-form__details-summary">{label} 폰트 설정</summary>
				<div className="crew-widget-form__details-body">
					{renderFontFields(prefix)}
				</div>
			</details>
		);
	};

	return (
		<main className="crew-widget-form">
			{/* 기본 설정 */}
			<details className="crew-widget-form__section" open>
				<summary className="crew-widget-form__section-title">기본 설정</summary>
				<div className="crew-widget-form__section-body">
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__field-label"><span className="text-destructive mr-0.5">*</span> 크루</label>
						<select
							className="crew-widget-form__select"
							aria-label="크루 선택"
							value={form.crewID}
							onChange={e => {
								const id = Number(e.target.value);
								const sel = crews.find(c => c.id === id);
								set('crewID', id);
								set('crewName', sel?.name ?? '');
							}}
						>
							<option value={0}>-- 크루 선택 --</option>
							{crews.map(c => (
								<option key={c.id} value={c.id}>{c.name}</option>
							))}
						</select>
					</div>

					<div className="crew-widget-form__field">
						<label className="crew-widget-form__field-label"><span className="text-destructive mr-0.5">*</span> 제목</label>
						<input
							type="text"
							className="crew-widget-form__input"
							value={form.title}
							onChange={e => set('title', e.target.value)}
							maxLength={300}
						/>
					</div>

					<div className="crew-widget-form__row">
						<div className="crew-widget-form__field">
							<label className="crew-widget-form__field-label">테마</label>
							<select
								className="crew-widget-form__select"
								aria-label="테마"
								value={form.theme}
								onChange={e => set('theme', Number(e.target.value))}
							>
								{CREW_WIDGET_THEMES.map(t => <option key={t.value} value={t.value}>{t.label}</option>)}
							</select>
						</div>
						<div className="crew-widget-form__field">
							<label className="crew-widget-form__field-label">기간</label>
							<select
								className="crew-widget-form__select"
								aria-label="기간"
								value={form.period}
								onChange={e => set('period', Number(e.target.value))}
							>
								{CREW_PERIODS.map(p => <option key={p.value} value={p.value}>{p.label}</option>)}
							</select>
						</div>
					</div>

					{form.period === 5 && (
						<div className="crew-widget-form__row">
							<div className="crew-widget-form__field">
								<label className="crew-widget-form__field-label">시작</label>
								<input
									type="text"
									className="crew-widget-form__input"
									placeholder="2026.04.12 14:00"
									maxLength={16}
									value={form.startAt ? formatInput(new Date(form.startAt)) : ''}
									onChange={e => set('startAt', parseInput(e.target.value) || null)}
								/>
							</div>
							<div className="crew-widget-form__field">
								<label className="crew-widget-form__field-label">종료</label>
								<input
									type="text"
									className="crew-widget-form__input"
									placeholder="2026.04.13 14:00"
									maxLength={16}
									value={form.endAt ? formatInput(new Date(form.endAt)) : ''}
									onChange={e => set('endAt', parseInput(e.target.value) || null)}
								/>
							</div>
						</div>
					)}

					<div className="crew-widget-form__row">
						<div className="crew-widget-form__field">
							<label className="crew-widget-form__field-label">최대 표시 수</label>
							<input
								type="number"
								className="crew-widget-form__input"
								min={1}
								max={20}
								value={form.maxDisplayCount}
								onChange={e => set('maxDisplayCount', Number(e.target.value))}
							/>
						</div>
						<div className="crew-widget-form__field">
							<label className="crew-widget-form__field-label">배경 색상</label>
							<ColorInput
								value={form.bgColor}
								onChange={v => set('bgColor', v)}
							/>
						</div>
					</div>
				</div>
			</details>

			{/* 표시 옵션 */}
			<details className="crew-widget-form__section" open>
				<summary className="crew-widget-form__section-title">표시 옵션</summary>
				<div className="crew-widget-form__section-body">
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__checkbox-label">
							<Checkbox checked={form.isShowAmount} onCheckedChange={v => set('isShowAmount', !!v)} />
							후원 금액 표시
						</label>
					</div>
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__checkbox-label">
							<Checkbox checked={form.isShowDonationCount} onCheckedChange={v => set('isShowDonationCount', !!v)} />
							후원 건수 표시
						</label>
					</div>
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__checkbox-label">
							<Checkbox checked={form.isShowContributionRate} onCheckedChange={v => set('isShowContributionRate', !!v)} />
							기여율 표시
						</label>
					</div>
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__checkbox-label">
							<Checkbox checked={form.isShowMemberIcon} onCheckedChange={v => set('isShowMemberIcon', !!v)} />
							크루원 아이콘 표시
						</label>
					</div>
					<div className="crew-widget-form__field">
						<label className="crew-widget-form__checkbox-label">
							<Checkbox checked={form.isActive} onCheckedChange={v => set('isActive', !!v)} />
							활성화
						</label>
					</div>
				</div>
			</details>

			{/* 제목 폰트 */}
			<details className="crew-widget-form__section" open>
				<summary className="crew-widget-form__section-title">제목 폰트</summary>
				<div className="crew-widget-form__section-body">
					{renderFontFields('title')}
				</div>
			</details>

			{/* 순위별 폰트 */}
			<details className="crew-widget-form__section" open>
				<summary className="crew-widget-form__section-title">순위별 폰트</summary>
				<div className="crew-widget-form__section-body">
					{renderFontDetails('1위', 'rank1')}
					{renderFontDetails('2위', 'rank2')}
					{renderFontDetails('3위', 'rank3')}
					{renderFontDetails('일반', 'row')}
				</div>
			</details>

			{/* 버튼 */}
			<div className="crew-widget-form__footer flex-1 w-full sm:justify-end gap-2">
				<button type="button" className="crew-widget-form__btn flex-1 sm:flex-none" onClick={() => onCancel ? onCancel() : router.push('/studio/donation/crew/widget/list')}>취소</button>
				<button type="button" className="crew-widget-form__btn crew-widget-form__btn--primary flex-1 sm:flex-none" onClick={handleSave} disabled={saving}>
					{saving ? '저장 중...' : '저장'}
				</button>
			</div>
		</main>
	);
}