import {isLoginRequiredError} from '@_api/apiClient';
import {fetchSidoList, fetchSigunguList} from '@_api/region/regionAPI';
import {type SidoResponse, type SigunguResponse} from '@_api/region/regionTypes';
import {fetchSchedules, holdSchedule} from '@_api/schedule/scheduleAPI';
import {ScheduleStatus, type ScheduleWithThemeResponse} from '@_api/schedule/scheduleTypes';
import {getStores} from '@_api/store/storeAPI';
import {type SimpleStoreResponse} from '@_api/store/storeTypes';
import {fetchThemeById} from '@_api/theme/themeAPI';
import {DifficultyKoreanMap, type ThemeInfoResponse} from '@_api/theme/themeTypes';
import '@_css/reservation-v2-1.css';
import React, {useEffect, useState} from 'react';
import {useLocation, useNavigate} from 'react-router-dom';
import {type ReservationData} from '@_api/reservation/reservationTypes';
import {formatDate} from 'src/util/DateTimeFormatter';

const ReservationStep1Page: React.FC = () => {
    const [selectedDate, setSelectedDate] = useState<Date>(new Date());
    const [viewDate, setViewDate] = useState<Date>(new Date());

    const [sidoList, setSidoList] = useState<SidoResponse[]>([]);
    const [sigunguList, setSigunguList] = useState<SigunguResponse[]>([]);
    const [storeList, setStoreList] = useState<SimpleStoreResponse[]>([]);

    const [selectedSido, setSelectedSido] = useState('');
    const [selectedSigungu, setSelectedSigungu] = useState('');
    const [selectedStore, setSelectedStore] = useState<SimpleStoreResponse | null>(null);

    const [schedulesByTheme, setSchedulesByTheme] = useState<Record<string, ScheduleWithThemeResponse[]>>({});
    const [selectedSchedule, setSelectedSchedule] = useState<ScheduleWithThemeResponse | null>(null);

    const [isThemeModalOpen, setIsThemeModalOpen] = useState(false);
    const [modalThemeDetails, setModalThemeDetails] = useState<ThemeInfoResponse | null>(null);
    const [isConfirmModalOpen, setIsConfirmModalOpen] = useState(false);

    const navigate = useNavigate();
    const location = useLocation();

    const handleError = (err: any) => {
        if (isLoginRequiredError(err)) {
            alert('로그인이 필요해요.');
            navigate('/login', {state: {from: location}});
        } else {
            const message = err.response?.data?.message || '알 수 없는 오류가 발생했습니다.';
            alert(message);
            console.error(err);
        }
    };

    useEffect(() => {
        fetchSidoList().then(res => setSidoList(res.sidoList)).catch(handleError);
    }, []);

    useEffect(() => {
        if (selectedSido) {
            fetchSigunguList(selectedSido).then(res => setSigunguList(res.sigunguList)).catch(handleError);
        } else {
            setSigunguList([]);
        }
        setSelectedSigungu('');
    }, [selectedSido]);

    useEffect(() => {
        if (selectedSido) {
            getStores(selectedSido, selectedSigungu)
                .then(res => setStoreList(res.stores))
                .catch(handleError);
        } else {
            setStoreList([]);
        }
        setSelectedStore(null);
    }, [selectedSido, selectedSigungu]);

    useEffect(() => {
        if (selectedDate && selectedStore) {
            const dateStr = selectedDate.toLocaleDateString('en-CA');
            fetchSchedules(selectedStore.id, dateStr)
                .then(res => {
                    const grouped = res.schedules.reduce((acc, schedule) => {
                        const key = schedule.themeName;
                        if (!acc[key]) acc[key] = [];
                        acc[key].push(schedule);
                        return acc;
                    }, {} as Record<string, ScheduleWithThemeResponse[]>);
                    setSchedulesByTheme(grouped);
                })
                .catch(handleError);
        } else {
            setSchedulesByTheme({});
        }
        setSelectedSchedule(null);
    }, [selectedDate, selectedStore]);

    const handleDateSelect = (date: Date) => {
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        if (date < today) {
            alert("지난 날짜는 선택할 수 없습니다.");
            return;
        }
        setSelectedDate(date);
    };

    const handleNextStep = () => {
        if (!selectedSchedule) {
            alert('예약할 시간을 선택해주세요.');
            return;
        }
        setIsConfirmModalOpen(true);
    };

    const handleConfirmReservation = () => {
        if (!selectedSchedule) return;

        holdSchedule(selectedSchedule.id)
            .then(() => {
                fetchThemeById(selectedSchedule.themeId).then(res => {
                    const reservationData: ReservationData = {
                        scheduleId: selectedSchedule.id,
                        store: {
                            id: selectedStore!.id,
                            name: selectedStore!.name,
                        },
                        theme: {
                            id: res.id,
                            name: res.name,
                            price: res.price,
                            minParticipants: res.minParticipants,
                            maxParticipants: res.maxParticipants,
                        },
                        date: selectedDate.toLocaleDateString('en-CA'),
                        startFrom: selectedSchedule.startFrom,
                        endAt: selectedSchedule.endAt,
                    };
                    navigate('/reservation/form', {state: reservationData});
                }).catch(handleError);
            })
            .catch(handleError);
    };

    const openThemeModal = (themeId: string) => {
        fetchThemeById(themeId)
            .then(themeDetails => {
                setModalThemeDetails(themeDetails);
                setIsThemeModalOpen(true);
            })
            .catch(handleError);
    };

    const renderDateCarousel = () => {
        const dates = [];
        const today = new Date();
        today.setHours(0, 0, 0, 0);

        for (let i = 0; i < 7; i++) {
            const date = new Date(viewDate);
            date.setDate(viewDate.getDate() + i);
            dates.push(date);
        }

        const handlePrev = () => {
            const newViewDate = new Date(viewDate);
            newViewDate.setDate(viewDate.getDate() - 1);
            if (newViewDate < today) {
                alert("지난 날짜는 조회할 수 없습니다.");
                return;
            }
            setViewDate(newViewDate);
        }

        const handleNext = () => {
            const newViewDate = new Date(viewDate);
            newViewDate.setDate(viewDate.getDate() + 1);
            setViewDate(newViewDate);
        }

        const goToToday = () => {
            setViewDate(new Date());
            setSelectedDate(new Date());
        }

        return (
            <div className="date-carousel">
                <button onClick={handlePrev} className="carousel-arrow">‹</button>
                <div className="date-options-container">
                    {dates.map(date => {
                        const isSelected = selectedDate.toDateString() === date.toDateString();
                        const isPast = date < today;
                        return (
                            <div
                                key={date.toISOString()}
                                className={`date-option ${isSelected ? 'active' : ''} ${isPast ? 'disabled' : ''}`}
                                onClick={() => handleDateSelect(date)}
                            >
                                <div className="day-of-week">{['일', '월', '화', '수', '목', '금', '토'][date.getDay()]}</div>
                                <div className="day-circle">{date.getDate()}</div>
                            </div>
                        );
                    })}
                </div>
                <button onClick={handleNext} className="carousel-arrow">›</button>
                <button onClick={goToToday} className="today-button">오늘</button>
            </div>
        );
    };

    const getStatusText = (status: ScheduleStatus) => {
        switch (status) {
            case ScheduleStatus.AVAILABLE:
                return '예약가능';
            case ScheduleStatus.HOLD:
                return '예약 진행중';
            default:
                return '예약불가';
        }
    };

    return (
        <div className="reservation-v21-container">
            <h2 className="page-title">예약하기</h2>

            <div className="step-section">
                <h3>1. 날짜 선택</h3>
                {renderDateCarousel()}
            </div>

            <div className={`step-section ${!selectedDate ? 'disabled' : ''}`}>
                <h3>2. 매장 선택</h3>
                <div className="region-store-selectors">
                    <select value={selectedSido} onChange={e => setSelectedSido(e.target.value)}>
                        <option value="">시/도</option>
                        {sidoList.map(s => <option key={s.code} value={s.code}>{s.name}</option>)}
                    </select>
                    <select value={selectedSigungu} onChange={e => setSelectedSigungu(e.target.value)}
                            disabled={!selectedSido}>
                        <option value="">시/군/구 (전체)</option>
                        {sigunguList.map(s => <option key={s.code} value={s.code}>{s.name}</option>)}
                    </select>
                    <select value={selectedStore?.id || ''}
                            onChange={e => setSelectedStore(storeList.find(s => s.id === e.target.value) || null)}
                            disabled={storeList.length === 0}>
                        <option value="">매장 선택</option>
                        {storeList.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
                    </select>
                </div>
            </div>

            <div className={`step-section ${!selectedStore ? 'disabled' : ''}`}>
                <h3>3. 시간 선택</h3>
                <div className="schedule-list">
                    {Object.keys(schedulesByTheme).length > 0 ? (
                        Object.entries(schedulesByTheme).map(([themeName, schedules]) => (
                            <div key={themeName} className="theme-schedule-group">
                                <div className="theme-header">
                                    <h4>{themeName}</h4>
                                    <button onClick={() => openThemeModal(schedules[0].themeId)}
                                            className="theme-detail-button">상세보기
                                    </button>
                                </div>
                                <div className="time-slots">
                                    {schedules.map(schedule => (
                                        <div
                                            key={schedule.id}
                                            className={`time-slot ${selectedSchedule?.id === schedule.id ? 'active' : ''} ${schedule.status !== ScheduleStatus.AVAILABLE ? 'disabled' : ''}`}
                                            onClick={() => schedule.status === ScheduleStatus.AVAILABLE && setSelectedSchedule(schedule)}
                                        >
                                            {`${schedule.startFrom} ~ ${schedule.endAt}`}
                                            <span className="time-availability">{getStatusText(schedule.status)}</span>
                                        </div>
                                    ))}
                                </div>
                            </div>
                        ))
                    ) : (
                        <div className="no-times">선택한 조건으로 예약 가능한 시간이 없습니다.</div>
                    )}
                </div>
            </div>

            <div className="next-step-button-container">
                <button className="next-step-button" disabled={!selectedSchedule} onClick={handleNextStep}>
                    예약하기
                </button>
            </div>

            {isThemeModalOpen && modalThemeDetails && (
                <div className="modal-overlay" onClick={() => setIsThemeModalOpen(false)}>
                    <div className="modal-content" onClick={(e) => e.stopPropagation()}>
                        <button className="modal-close-button" onClick={() => setIsThemeModalOpen(false)}>×</button>
                        <img src={modalThemeDetails.thumbnailUrl} alt={modalThemeDetails.name}
                             className="modal-theme-thumbnail"/>
                        <h2>{modalThemeDetails.name}</h2>
                        <div className="modal-section modal-info-grid">
                            <h3>테마 정보</h3>
                            <p><strong>난이도:</strong><span>{DifficultyKoreanMap[modalThemeDetails.difficulty]}</span></p>
                            <p><strong>이용 가능 인원:</strong><span>{modalThemeDetails.minParticipants} ~ {modalThemeDetails.maxParticipants}명</span></p>
                            <p><strong>1인당 요금:</strong><span>{modalThemeDetails.price.toLocaleString()}원</span></p>
                            <p><strong>예상 시간:</strong><span>{modalThemeDetails.expectedMinutesFrom} ~ {modalThemeDetails.expectedMinutesTo}분</span></p>
                            <p><strong>이용 가능 시간:</strong><span>{modalThemeDetails.availableMinutes}분</span></p>
                        </div>
                        <div className="modal-section">
                            <h3>소개</h3>
                            <p>{modalThemeDetails.description}</p>
                        </div>
                    </div>
                </div>
            )}

            {isConfirmModalOpen && selectedSchedule && (
                <div className="modal-overlay" onClick={() => setIsConfirmModalOpen(false)}>
                    <div className="modal-content" onClick={(e) => e.stopPropagation()}>
                        <button className="modal-close-button" onClick={() => setIsConfirmModalOpen(false)}>×</button>
                        <h2>예약 정보를 확인해주세요</h2>
                        <div className="modal-section modal-info-grid">
                            <p><strong>날짜:</strong><span>{formatDate(selectedDate.toLocaleDateString('ko-KR'))}</span></p>
                            <p><strong>매장:</strong><span>{selectedStore?.name}</span></p>
                            <p><strong>테마:</strong><span>{selectedSchedule.themeName}</span></p>
                            <p><strong>시간:</strong><span>{`${selectedSchedule.startFrom} ~ ${selectedSchedule.endAt}`}</span></p>
                        </div>
                        <div className="modal-actions">
                            <button className="cancel-button" onClick={() => setIsConfirmModalOpen(false)}>취소</button>
                            <button className="confirm-button" onClick={handleConfirmReservation}>예약하기</button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
};

export default ReservationStep1Page;
