import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
    bypassAccountApi,
    type BypassRequestSubmitRequest,
} from '../api/bypassAccountApi';
import { useToastContext } from '../contexts/ToastContext';

interface FormState {
    applicantName: string;
    organization: string;
    purpose: string;
    email: string;
    requestedAccessPeriod: string;
}

interface ErrorState {
    applicantName?: string;
    email?: string;
    requestedAccessPeriod?: string;
}

interface TouchedState {
    applicantName: boolean;
    email: boolean;
    requestedAccessPeriod: boolean;
}

type PeriodPreset = '3개월' | '6개월' | '9개월' | '1년';

const INITIAL_FORM: FormState = {
    applicantName: '',
    organization: '',
    purpose: '',
    email: '',
    requestedAccessPeriod: '',
};

const INITIAL_TOUCHED: TouchedState = {
    applicantName: false,
    email: false,
    requestedAccessPeriod: false,
};

const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

function toDateString(date: Date): string {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
}

function addMonths(date: Date, months: number): Date {
    const result = new Date(date);
    result.setMonth(result.getMonth() + months);
    return result;
}

function addYears(date: Date, years: number): Date {
    const result = new Date(date);
    result.setFullYear(result.getFullYear() + years);
    return result;
}

function calcPresetPeriod(preset: PeriodPreset): string {
    const today = new Date();
    const from = toDateString(today);
    let to: string;
    switch (preset) {
        case '3개월': to = toDateString(addMonths(today, 3)); break;
        case '6개월': to = toDateString(addMonths(today, 6)); break;
        case '9개월': to = toDateString(addMonths(today, 9)); break;
        case '1년':   to = toDateString(addYears(today, 1));  break;
    }
    return `${from} ~ ${to}`;
}

function validateForm(form: FormState): ErrorState {
    const errors: ErrorState = {};

    if (!form.applicantName.trim()) {
        errors.applicantName = '신청자명을 입력해주세요.';
    }

    if (!form.email.trim()) {
        errors.email = '이메일을 입력해주세요.';
    } else if (!EMAIL_REGEX.test(form.email.trim())) {
        errors.email = '올바른 이메일 형식을 입력해주세요.';
    }

    if (!form.requestedAccessPeriod.trim()) {
        errors.requestedAccessPeriod = '사용 기간을 선택해주세요.';
    }

    return errors;
}

export default function BypassAccessRequest() {
    const { showToast } = useToastContext();
    const navigate = useNavigate();

    const [form, setForm] = useState<FormState>(INITIAL_FORM);
    const [submitting, setSubmitting] = useState(false);
    const [submittedId, setSubmittedId] = useState<number | null>(null);

    // Validation state
    const [errors, setErrors] = useState<ErrorState>({});
    const [touched, setTouched] = useState<TouchedState>(INITIAL_TOUCHED);
    const [submitAttempted, setSubmitAttempted] = useState(false);

    // Period mode
    const [periodManual, setPeriodManual] = useState(false);
    const [selectedPreset, setSelectedPreset] = useState<PeriodPreset | null>(null);
    const [periodFrom, setPeriodFrom] = useState('');
    const [periodTo, setPeriodTo] = useState('');
    const [periodRangeError, setPeriodRangeError] = useState('');

    const handleChange = (field: keyof FormState, value: string) => {
        setForm((prev) => ({ ...prev, [field]: value }));
    };

    const handleBlur = (field: keyof TouchedState) => {
        setTouched((prev) => ({ ...prev, [field]: true }));
        const currentErrors = validateForm(form);
        setErrors(currentErrors);
    };

    const handlePresetClick = (preset: PeriodPreset) => {
        setSelectedPreset(preset);
        const period = calcPresetPeriod(preset);
        handleChange('requestedAccessPeriod', period);
    };

    const handlePeriodFromChange = (value: string) => {
        setPeriodFrom(value);
        setPeriodRangeError('');
        if (value && periodTo) {
            if (value >= periodTo) {
                setPeriodRangeError('시작일은 종료일보다 이전이어야 합니다.');
            } else {
                handleChange('requestedAccessPeriod', `${value} ~ ${periodTo}`);
            }
        }
    };

    const handlePeriodToChange = (value: string) => {
        setPeriodTo(value);
        setPeriodRangeError('');
        if (periodFrom && value) {
            if (periodFrom >= value) {
                setPeriodRangeError('시작일은 종료일보다 이전이어야 합니다.');
            } else {
                handleChange('requestedAccessPeriod', `${periodFrom} ~ ${value}`);
            }
        }
    };

    const handleToggleManual = () => {
        setPeriodManual((prev) => {
            const next = !prev;
            if (!next) {
                // Switching back to preset: clear manual inputs
                setPeriodFrom('');
                setPeriodTo('');
                setPeriodRangeError('');
                setSelectedPreset(null);
                handleChange('requestedAccessPeriod', '');
            } else {
                // Switching to manual: clear preset selection
                setSelectedPreset(null);
                handleChange('requestedAccessPeriod', '');
            }
            return next;
        });
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setSubmitAttempted(true);
        setTouched({ applicantName: true, email: true, requestedAccessPeriod: true });

        const currentErrors = validateForm(form);

        if (periodManual && periodRangeError) {
            return;
        }

        if (Object.keys(currentErrors).length > 0) {
            setErrors(currentErrors);
            // 첫 번째 에러 필드로 스크롤
            const firstErrorField = Object.keys(currentErrors)[0];
            const el = document.getElementById(`field-${firstErrorField}`);
            if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
            return;
        }

        setSubmitting(true);
        try {
            const requestData: BypassRequestSubmitRequest = {
                applicantName: form.applicantName,
                organization: form.organization,
                purpose: form.purpose,
                email: form.email,
                phone: '',
                requestedAccessPeriod: form.requestedAccessPeriod,
            };
            const res = await bypassAccountApi.submitRequest(requestData);
            setSubmittedId(res.data.id);
            showToast('신청이 완료되었습니다.', 'success');
        } catch (err) {
            showToast('신청 제출 실패. 다시 시도해주세요.', 'error');
            console.error(err);
        } finally {
            setSubmitting(false);
        }
    };

    const showError = (field: keyof TouchedState): boolean =>
        (touched[field] || submitAttempted) && Boolean(errors[field]);

    const inputClass = (field: keyof TouchedState) =>
        `w-full px-3 py-2 text-sm rounded-lg border ${
            showError(field) ? 'border-red-400' : 'border-wing-border'
        } bg-wing-card text-wing-text placeholder:text-wing-muted focus:outline-none focus:ring-2 ${
            showError(field) ? 'focus:ring-red-400/50' : 'focus:ring-wing-accent/50'
        }`;

    const PRESETS: PeriodPreset[] = ['3개월', '6개월', '9개월', '1년'];

    return (
        <div className="space-y-6">
            {/* 헤더 */}
            <div>
                <h1 className="text-2xl font-bold text-wing-text">S&P API 계정 신청</h1>
                <p className="mt-1 text-sm text-wing-muted">
                    S&P API 계정을 신청합니다. 검토 후 계정 정보가 이메일로 발송됩니다.
                </p>
            </div>

            {submittedId !== null ? (
                /* 제출 완료 화면 */
                <div className="bg-wing-surface rounded-xl shadow-md p-8 text-center">
                    <div className="w-14 h-14 bg-emerald-100 rounded-full flex items-center justify-center mx-auto mb-4">
                        <svg className="w-7 h-7 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                        </svg>
                    </div>
                    <h2 className="text-xl font-bold text-wing-text mb-2">신청이 완료되었습니다</h2>
                    <p className="text-sm text-wing-muted mb-1">
                        신청 번호: <span className="font-semibold text-wing-text">#{submittedId}</span>
                    </p>
                    <p className="text-sm text-wing-muted">
                        검토 후 입력하신 이메일로 안내 드리겠습니다.
                    </p>
                    <button
                        type="button"
                        onClick={() => {
                            setForm(INITIAL_FORM);
                            setErrors({});
                            setTouched(INITIAL_TOUCHED);
                            setSubmitAttempted(false);
                            setSelectedPreset(null);
                            setPeriodManual(false);
                            setPeriodFrom('');
                            setPeriodTo('');
                            setPeriodRangeError('');
                            setSubmittedId(null);
                        }}
                        className="mt-6 px-6 py-2 text-sm font-medium text-wing-text bg-wing-card hover:bg-wing-hover border border-wing-border rounded-lg transition-colors"
                    >
                        새 신청 작성
                    </button>
                    <button
                        type="button"
                        onClick={() => navigate('/bypass-catalog')}
                        className="mt-3 px-6 py-2 text-sm font-medium text-wing-text bg-wing-card hover:bg-wing-hover border border-wing-border rounded-lg transition-colors"
                    >
                        S&P API 목록 보기
                    </button>
                </div>
            ) : (
                /* 신청 폼 */
                <form onSubmit={handleSubmit}>
                    <div className="bg-wing-surface rounded-xl shadow-md p-6">
                        <div className="space-y-5">
                            {/* 신청자명 + 기관 */}
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div id="field-applicantName">
                                    <label className="block text-sm font-medium text-wing-text mb-1">
                                        신청자명 <span className="text-red-500">*</span>
                                    </label>
                                    <input
                                        type="text"
                                        value={form.applicantName}
                                        onChange={(e) => handleChange('applicantName', e.target.value)}
                                        onBlur={() => handleBlur('applicantName')}
                                        placeholder="홍길동"
                                        disabled={submitting}
                                        className={inputClass('applicantName')}
                                    />
                                    {showError('applicantName') && (
                                        <p className="mt-1 text-xs text-red-500">{errors.applicantName}</p>
                                    )}
                                </div>
                                <div>
                                    <label className="block text-sm font-medium text-wing-text mb-1">
                                        기관
                                    </label>
                                    <input
                                        type="text"
                                        value={form.organization}
                                        onChange={(e) => handleChange('organization', e.target.value)}
                                        placeholder="소속 기관명"
                                        disabled={submitting}
                                        className="w-full px-3 py-2 text-sm rounded-lg border border-wing-border bg-wing-card text-wing-text placeholder:text-wing-muted focus:outline-none focus:ring-2 focus:ring-wing-accent/50"
                                    />
                                </div>
                            </div>

                            {/* 이메일 + 사용 기간 */}
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div id="field-email">
                                    <label className="block text-sm font-medium text-wing-text mb-1">
                                        이메일 <span className="text-red-500">*</span>
                                    </label>
                                    <input
                                        type="text"
                                        value={form.email}
                                        onChange={(e) => handleChange('email', e.target.value)}
                                        onBlur={() => handleBlur('email')}
                                        placeholder="example@domain.com"
                                        disabled={submitting}
                                        className={inputClass('email')}
                                    />
                                    {showError('email') && (
                                        <p className="mt-1 text-xs text-red-500">{errors.email}</p>
                                    )}
                                </div>
                                <div id="field-requestedAccessPeriod">
                                    <div className="flex items-center justify-between mb-1">
                                        <label className="text-sm font-medium text-wing-text">
                                            사용 기간 <span className="text-red-500">*</span>
                                        </label>
                                        <button
                                            type="button"
                                            onClick={handleToggleManual}
                                            className="flex items-center gap-2 text-xs text-wing-muted hover:text-wing-text transition-colors"
                                        >
                                            <span>직접 선택</span>
                                            <span
                                                className={`relative inline-flex h-4 w-8 items-center rounded-full transition-colors ${
                                                    periodManual ? 'bg-wing-accent' : 'bg-wing-border'
                                                }`}
                                            >
                                                <span
                                                    className={`inline-block h-3 w-3 rounded-full bg-white shadow transition-transform ${
                                                        periodManual ? 'translate-x-4' : 'translate-x-0.5'
                                                    }`}
                                                />
                                            </span>
                                        </button>
                                    </div>
                                    {!periodManual ? (
                                        <div className="flex flex-wrap gap-2">
                                            {PRESETS.map((preset) => (
                                                <button
                                                    key={preset}
                                                    type="button"
                                                    onClick={() => handlePresetClick(preset)}
                                                    disabled={submitting}
                                                    className={`px-4 py-1.5 text-sm rounded-full border transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${
                                                        selectedPreset === preset
                                                            ? 'bg-wing-accent text-white border-wing-accent'
                                                            : 'bg-wing-card text-wing-text border-wing-border hover:border-wing-accent hover:text-wing-accent'
                                                    }`}
                                                >
                                                    {preset}
                                                </button>
                                            ))}
                                        </div>
                                    ) : (
                                        <div className="flex items-center gap-3">
                                            <div className="flex-1">
                                                <input
                                                    type="date"
                                                    value={periodFrom}
                                                    onChange={(e) => handlePeriodFromChange(e.target.value)}
                                                    disabled={submitting}
                                                    className="w-full px-3 py-2 text-sm rounded-lg border border-wing-border bg-wing-card text-wing-text focus:outline-none focus:ring-2 focus:ring-wing-accent/50"
                                                />
                                            </div>
                                            <span className="text-sm text-wing-muted flex-shrink-0">~</span>
                                            <div className="flex-1">
                                                <input
                                                    type="date"
                                                    value={periodTo}
                                                    onChange={(e) => handlePeriodToChange(e.target.value)}
                                                    disabled={submitting}
                                                    className="w-full px-3 py-2 text-sm rounded-lg border border-wing-border bg-wing-card text-wing-text focus:outline-none focus:ring-2 focus:ring-wing-accent/50"
                                                />
                                            </div>
                                        </div>
                                    )}

                                    {form.requestedAccessPeriod && !periodRangeError && (
                                        <p className="mt-2 text-xs text-wing-muted">
                                            선택된 기간: <span className="font-medium text-wing-text">{form.requestedAccessPeriod}</span>
                                        </p>
                                    )}
                                    {periodRangeError && (
                                        <p className="mt-1 text-xs text-red-500">{periodRangeError}</p>
                                    )}
                                    {showError('requestedAccessPeriod') && !periodRangeError && (
                                        <p className="mt-1 text-xs text-red-500">{errors.requestedAccessPeriod}</p>
                                    )}
                                </div>
                            </div>

                            {/* 사용 목적 */}
                            <div>
                                <label className="block text-sm font-medium text-wing-text mb-1">
                                    사용 목적
                                </label>
                                <textarea
                                    value={form.purpose}
                                    onChange={(e) => handleChange('purpose', e.target.value)}
                                    placeholder="Bypass API를 사용하려는 목적을 간략히 설명해주세요."
                                    rows={4}
                                    disabled={submitting}
                                    className="w-full px-3 py-2 text-sm rounded-lg border border-wing-border bg-wing-card text-wing-text placeholder:text-wing-muted focus:outline-none focus:ring-2 focus:ring-wing-accent/50 resize-none"
                                />
                            </div>

                        </div>

                        <div className="mt-6 flex justify-end">
                            <button
                                type="submit"
                                disabled={submitting}
                                className="px-6 py-2 text-sm font-medium text-white bg-wing-accent hover:bg-wing-accent/80 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                {submitting ? '제출 중...' : '신청 제출'}
                            </button>
                        </div>
                    </div>
                </form>
            )}
        </div>
    );
}
