import { isLoginRequiredError } from '@_api/apiClient';
import { createSchedule, deleteSchedule, findScheduleById, findSchedules, updateSchedule } from '@_api/schedule/scheduleAPI';
import { ScheduleStatus, type ScheduleDetailRetrieveResponse, type ScheduleRetrieveResponse } from '@_api/schedule/scheduleTypes';
import { fetchAdminThemes } from '@_api/theme/themeAPI';
import type { AdminThemeSummaryRetrieveResponse } from '@_api/theme/themeTypes';
import '@_css/admin-schedule-page.css';
import React, { Fragment, useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

const getScheduleStatusText = (status: ScheduleStatus): string => {
    switch (status) {
        case ScheduleStatus.AVAILABLE:
            return '예약 가능';
        case ScheduleStatus.PENDING:
            return '예약 진행 중';
        case ScheduleStatus.RESERVED:
            return '예약 완료';
        case ScheduleStatus.BLOCKED:
            return '예약 불가';
        default:
            return status;
    }
};

const AdminSchedulePage: React.FC = () => {
    const [schedules, setSchedules] = useState<ScheduleRetrieveResponse[]>([]);
    const [themes, setThemes] = useState<AdminThemeSummaryRetrieveResponse[]>([]);
    const [selectedThemeId, setSelectedThemeId] = useState<string>('');
    const [selectedDate, setSelectedDate] = useState<string>(new Date().toLocaleDateString('en-CA'));

    const [isAdding, setIsAdding] = useState(false);
    const [newScheduleTime, setNewScheduleTime] = useState('');

    const [expandedScheduleId, setExpandedScheduleId] = useState<string | null>(null);
    const [detailedSchedules, setDetailedSchedules] = useState<{ [key: string]: ScheduleDetailRetrieveResponse }>({});
    const [isLoadingDetails, setIsLoadingDetails] = useState<boolean>(false);
    const [isEditing, setIsEditing] = useState(false);
    const [editingSchedule, setEditingSchedule] = useState<ScheduleDetailRetrieveResponse | null>(null);

    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(() => {
        fetchAdminThemes()
            .then(res => {
                setThemes(res.themes);
                if (res.themes.length > 0) {
                    setSelectedThemeId(String(res.themes[0].id));
                }
            })
            .catch(handleError);
    }, []);

    const fetchSchedules = () => {
        if (selectedDate && selectedThemeId) {
            findSchedules(selectedDate, selectedThemeId)
                .then(res => setSchedules(res.schedules))
                .catch(err => {
                    setSchedules([]);
                    if (err.response?.status !== 404) {
                        handleError(err);
                    }
                });
        }
    }

    useEffect(() => {
        fetchSchedules();
    }, [selectedDate, selectedThemeId]);

    const handleAddSchedule = async () => {
        if (!newScheduleTime) {
            alert('시간을 입력해주세요.');
            return;
        }
        if (!/\d{2}:\d{2}/.test(newScheduleTime)) {
            alert('시간 형식이 올바르지 않습니다. HH:MM 형식으로 입력해주세요.');
            return;
        }
        try {
            await createSchedule({
                date: selectedDate,
                themeId: selectedThemeId,
                time: newScheduleTime,
            });
            fetchSchedules();
            setIsAdding(false);
            setNewScheduleTime('');
        } catch (error) {
            handleError(error);
        }
    };

    const handleDeleteSchedule = async (scheduleId: string) => {
        if (window.confirm('정말 이 일정을 삭제하시겠습니까?')) {
            try {
                await deleteSchedule(scheduleId);
                setSchedules(schedules.filter(s => s.id !== scheduleId));
                setExpandedScheduleId(null); // Close the details view after deletion
            } catch (error) {
                handleError(error);
            }
        }
    };

    const handleToggleDetails = async (scheduleId: string) => {
        const isAlreadyExpanded = expandedScheduleId === scheduleId;
        setIsEditing(false); // Reset editing state whenever toggling
        if (isAlreadyExpanded) {
            setExpandedScheduleId(null);
        } else {
            setExpandedScheduleId(scheduleId);
            if (!detailedSchedules[scheduleId]) {
                setIsLoadingDetails(true);
                try {
                    const details = await findScheduleById(scheduleId);
                    setDetailedSchedules(prev => ({ ...prev, [scheduleId]: details }));
                } catch (error) {
                    handleError(error);
                } finally {
                    setIsLoadingDetails(false);
                }
            }
        }
    };

    const handleEditClick = () => {
        if (expandedScheduleId && detailedSchedules[expandedScheduleId]) {
            setEditingSchedule({ ...detailedSchedules[expandedScheduleId] });
            setIsEditing(true);
        }
    };

    const handleCancelEdit = () => {
        setIsEditing(false);
        setEditingSchedule(null);
    };

    const handleEditChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
        const { name, value } = e.target;
        if (editingSchedule) {
            setEditingSchedule({ ...editingSchedule, [name]: value });
        }
    };

    const handleSave = async () => {
        if (!editingSchedule) return;

        try {
            await updateSchedule(editingSchedule.id, {
                time: editingSchedule.time,
                status: editingSchedule.status,
            });
            // Refresh data
            const details = await findScheduleById(editingSchedule.id);
            setDetailedSchedules(prev => ({ ...prev, [editingSchedule.id]: details }));
            setSchedules(schedules.map(s => s.id === editingSchedule.id ? { ...s, time: details.time, status: details.status } : s));

            alert('일정이 성공적으로 업데이트되었습니다.');
            setIsEditing(false);
        } catch (error) {
            handleError(error);
        }
    };

    return (
        <div className="admin-schedule-container">
            <h2 className="page-title">일정 관리</h2>

            <div className="schedule-controls">
                <div className="form-group">
                    <label className="form-label" htmlFor="date-filter">날짜</label>
                    <input
                        id="date-filter"
                        type="date"
                        className="form-input"
                        value={selectedDate}
                        onChange={e => setSelectedDate(e.target.value)}
                    />
                </div>
                <div className="form-group">
                    <label className="form-label" htmlFor="theme-filter">테마</label>
                    <select
                        id="theme-filter"
                        className="form-select"
                        value={selectedThemeId}
                        onChange={e => setSelectedThemeId(e.target.value)}
                    >
                        {themes.map(theme => (
                            <option key={theme.id} value={theme.id}>{theme.name}</option>
                        ))}
                    </select>
                </div>
            </div>

            <div className="section-card">
                <div className="table-header">
                    <button className="btn btn-primary" onClick={() => setIsAdding(true)}>일정 추가</button>
                </div>
                <div className="table-container">
                    <table>
                        <thead>
                            <tr>
                                <th>시간</th>
                                <th>상태</th>
                                <th>관리</th>
                            </tr>
                        </thead>
                        <tbody>
                            {schedules.map(schedule => (
                                <Fragment key={schedule.id}>
                                    <tr>
                                        <td>{schedule.time}</td>
                                        <td>{getScheduleStatusText(schedule.status)}</td>
                                        <td className="action-buttons">
                                            <button
                                                className="btn btn-secondary"
                                                onClick={() => handleToggleDetails(schedule.id)}
                                            >
                                                {expandedScheduleId === schedule.id ? '닫기' : '상세'}
                                            </button>
                                        </td>
                                    </tr>
                                    {expandedScheduleId === schedule.id && (
                                        <tr className="schedule-details-row">
                                            <td colSpan={3}>
                                                {isLoadingDetails ? (
                                                    <p>로딩 중...</p>
                                                ) : detailedSchedules[schedule.id] ? (
                                                    <div className="details-form-container">
                                                        <div className="audit-info">
                                                            <h4 className="audit-title">감사 정보</h4>
                                                            <div className="audit-body">
                                                                <p><strong>생성일:</strong> {new Date(detailedSchedules[schedule.id].createdAt).toLocaleString()}</p>
                                                                <p><strong>수정일:</strong> {new Date(detailedSchedules[schedule.id].updatedAt).toLocaleString()}</p>
                                                                <p><strong>생성자:</strong> {detailedSchedules[schedule.id].createdBy}</p>
                                                                <p><strong>수정자:</strong> {detailedSchedules[schedule.id].updatedBy}</p>
                                                            </div>
                                                        </div>

                                                        {isEditing && editingSchedule ? (
                                                            // --- EDIT MODE ---
                                                            <div className="form-card">
                                                                <div className="form-section">
                                                                    <div className="form-row">
                                                                        <div className="form-group">
                                                                            <label className="form-label">시간</label>
                                                                            <input type="time" name="time" className="form-input" value={editingSchedule.time} onChange={handleEditChange} />
                                                                        </div>
                                                                        <div className="form-group">
                                                                            <label className="form-label">상태</label>
                                                                            <select name="status" className="form-select" value={editingSchedule.status} onChange={handleEditChange}>
                                                                                {Object.values(ScheduleStatus).map(s => <option key={s} value={s}>{getScheduleStatusText(s)}</option>)}
                                                                            </select>
                                                                        </div>
                                                                    </div>
                                                                </div>
                                                                <div className="button-group">
                                                                    <button type="button" className="btn btn-secondary" onClick={handleCancelEdit}>취소</button>
                                                                    <button type="button" className="btn btn-primary" onClick={handleSave}>저장</button>
                                                                </div>
                                                            </div>
                                                        ) : (
                                                            // --- VIEW MODE ---
                                                            <div className="button-group view-mode-buttons">
                                                                <button type="button" className="btn btn-danger" onClick={() => handleDeleteSchedule(schedule.id)}>삭제</button>
                                                                <button type="button" className="btn btn-primary" onClick={handleEditClick}>수정</button>
                                                            </div>
                                                        )}
                                                    </div>
                                                ) : (
                                                    <p>상세 정보를 불러올 수 없습니다.</p>
                                                )}
                                            </td>
                                        </tr>
                                    )}
                                </Fragment>
                            ))}
                            {isAdding && (
                                <tr className="editing-row">
                                    <td>
                                        <input
                                            type="time"
                                            className="form-input"
                                            value={newScheduleTime}
                                            onChange={e => setNewScheduleTime(e.target.value)}
                                        />
                                    </td>
                                    <td></td>
                                    <td className="action-buttons">
                                        <button className="btn btn-primary" onClick={handleAddSchedule}>저장</button>
                                        <button className="btn btn-secondary" onClick={() => setIsAdding(false)}>취소</button>
                                    </td>
                                </tr>
                            )}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    );
};

export default AdminSchedulePage;
