import { useState, useEffect, useRef } from "react";
import { useNavigate, Link, useParams } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import { formatDate } from "../../../utils/date";
import {
  Home,
  ChevronRight,
  Calendar,
  Save,
  X,
  Upload,
  Link as LinkIcon,
  ChevronLeft,
  ChevronDown,
  Clock,
  Image,
  Users,
  Check,
  Plus,
  MapPin,
  Settings,
  Trash2,
  Search,
} from "lucide-react";
import Toast from "../../../components/Toast";
import Lightbox from "../../../components/common/Lightbox";
import CustomDatePicker from "../../../components/admin/CustomDatePicker";
import CustomTimePicker from "../../../components/admin/CustomTimePicker";
import AdminLayout from "../../../components/admin/AdminLayout";
import ConfirmDialog from "../../../components/admin/ConfirmDialog";
import useAdminAuth from "../../../hooks/useAdminAuth";
import useToast from "../../../hooks/useToast";
import * as categoriesApi from "../../../api/admin/categories";
import * as schedulesApi from "../../../api/admin/schedules";
import { getMembers } from "../../../api/public/members";

function AdminScheduleForm() {
  const navigate = useNavigate();
  const { id } = useParams();
  const isEditMode = !!id;
  const { user, isAuthenticated } = useAdminAuth();

  const { toast, setToast } = useToast();
  const [loading, setLoading] = useState(false);
  const [members, setMembers] = useState([]);

  // 폼 데이터 (날짜/시간 범위 지원)
  const [formData, setFormData] = useState({
    title: "",
    startDate: "",
    endDate: "",
    startTime: "",
    endTime: "",
    isRange: false, // 범위 설정 여부
    category: "",
    description: "",
    url: "",
    sourceName: "",
    members: [],
    images: [],
    // 장소 정보
    locationName: "", // 장소 이름
    locationAddress: "", // 주소
    locationDetail: "", // 상세주소 (예: 3관, N열 등)
    locationLat: null, // 위도
    locationLng: null, // 경도
  });

  // 이미지 미리보기
  const [imagePreviews, setImagePreviews] = useState([]);

  // 라이트박스 상태
  const [lightboxOpen, setLightboxOpen] = useState(false);
  const [lightboxIndex, setLightboxIndex] = useState(0);

  // 삭제 다이얼로그 상태
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [deleteTargetIndex, setDeleteTargetIndex] = useState(null);

  // 카테고리 목록 (API에서 로드)
  const [categories, setCategories] = useState([]);

  // 저장 중 상태
  const [saving, setSaving] = useState(false);

  // 장소 검색 관련 상태
  const [locationDialogOpen, setLocationDialogOpen] = useState(false);
  const [locationSearch, setLocationSearch] = useState("");
  const [locationResults, setLocationResults] = useState([]);
  const [locationSearching, setLocationSearching] = useState(false);

  // 수정 모드용 기존 이미지 ID 추적
  const [existingImageIds, setExistingImageIds] = useState([]);

  // 카테고리 색상 맵핑
  const colorMap = {
    blue: "bg-blue-500",
    green: "bg-green-500",
    purple: "bg-purple-500",
    red: "bg-red-500",
    pink: "bg-pink-500",
    yellow: "bg-yellow-500",
    orange: "bg-orange-500",
    gray: "bg-gray-500",
    cyan: "bg-cyan-500",
    indigo: "bg-indigo-500",
  };

  // 색상 스타일 (기본 색상 또는 커스텀 HEX)
  const getColorStyle = (color) => {
    if (!color) return { className: "bg-gray-500" };
    if (color.startsWith("#")) {
      return { style: { backgroundColor: color } };
    }
    return { className: colorMap[color] || "bg-gray-500" };
  };

  // 카테고리 색상
  const getCategoryColor = (categoryId) => {
    const cat = categories.find((c) => c.id === categoryId);
    if (cat && colorMap[cat.color]) {
      return colorMap[cat.color];
    }
    return "bg-gray-500";
  };

  // 날짜에서 요일 가져오기 (월, 화, 수 등)
  const getDayOfWeek = (dateStr) => {
    if (!dateStr) return '';
    const days = ['일', '월', '화', '수', '목', '금', '토'];
    const date = new Date(dateStr);
    return days[date.getDay()];
  };

  // 카테고리 로드
  const fetchCategories = async () => {
    try {
      const data = await categoriesApi.getCategories();
      setCategories(data);
      // 첫 번째 카테고리를 기본값으로 설정
      if (data.length > 0 && !formData.category) {
        setFormData((prev) => ({ ...prev, category: data[0].id }));
      }
    } catch (error) {
      console.error("카테고리 로드 오류:", error);
    }
  };

  useEffect(() => {
    if (!isAuthenticated) return;

    fetchMembers();
    fetchCategories();

    // 수정 모드일 경우 기존 데이터 로드
    if (isEditMode && id) {
      fetchSchedule();
    }
  }, [isAuthenticated, isEditMode, id]);

  // 기존 일정 데이터 로드 (수정 모드)
  const fetchSchedule = async () => {
    setLoading(true);
    try {
      const data = await schedulesApi.getSchedule(id);

      // 폼 데이터 설정
      setFormData({
        title: data.title || "",
        startDate: data.date ? formatDate(data.date) : "",
        endDate: data.end_date ? formatDate(data.end_date) : "",
        startTime: data.time?.slice(0, 5) || "",
        endTime: data.end_time?.slice(0, 5) || "",
        isRange: !!data.end_date,
        category: data.category_id || "",
        description: data.description || "",
        url: data.source?.url || "",
        sourceName: data.source?.name || "",
        members: data.members?.map((m) => m.id) || [],
        images: [],
        locationName: data.location_name || "",
        locationAddress: data.location_address || "",
        locationDetail: data.location_detail || "",
        locationLat: data.location_lat || null,
        locationLng: data.location_lng || null,
      });

      // 기존 이미지 설정
      if (data.images && data.images.length > 0) {
        // 기존 이미지를 formData.images에 저장 (id 포함)
        setFormData(prev => ({
          ...prev,
          title: data.title || "",
          isRange: data.is_range || false,
          startDate: data.date?.split("T")[0] || "",
          endDate: data.end_date?.split("T")[0] || "",
          startTime: data.time?.slice(0, 5) || "",
          endTime: data.end_time?.slice(0, 5) || "",
          category: data.category_id || 1,
          description: data.description || "",
          url: data.source?.url || "",
          sourceName: data.source?.name || "",
          members: data.members?.map((m) => m.id) || [],
          images: data.images.map(img => ({ id: img.id, url: img.image_url })),
          locationName: data.location_name || "",
          locationAddress: data.location_address || "",
          locationDetail: data.location_detail || "",
          locationLat: data.location_lat || null,
          locationLng: data.location_lng || null,
        }));
        setImagePreviews(data.images.map((img) => img.image_url));
        setExistingImageIds(data.images.map((img) => img.id));
      }
    } catch (error) {
      console.error("일정 로드 오류:", error);
      setToast({
        type: "error",
        message: error.message || "일정을 불러오는 중 오류가 발생했습니다.",
      });
      navigate("/admin/schedule");
    } finally {
      setLoading(false);
    }
  };

  const fetchMembers = async () => {
    try {
      const data = await getMembers();
      setMembers(data.filter((m) => !m.is_former));
    } catch (error) {
      console.error("멤버 로드 오류:", error);
    }
  };

  // 멤버 토글
  const toggleMember = (memberId) => {
    const newMembers = formData.members.includes(memberId)
      ? formData.members.filter((id) => id !== memberId)
      : [...formData.members, memberId];
    setFormData({ ...formData, members: newMembers });
  };

  // 전체 선택/해제
  const toggleAllMembers = () => {
    if (formData.members.length === members.length) {
      setFormData({ ...formData, members: [] });
    } else {
      setFormData({ ...formData, members: members.map((m) => m.id) });
    }
  };

  // 다중 이미지 업로드
  const handleImagesUpload = (e) => {
    const files = Array.from(e.target.files);
    // 파일을 {file: File} 형태로 저장 (제출 시 image.file로 접근하기 위함)
    const newImageObjects = files.map((file) => ({ file }));
    const newImages = [...formData.images, ...newImageObjects];
    setFormData({ ...formData, images: newImages });

    files.forEach((file) => {
      const reader = new FileReader();
      reader.onloadend = () => {
        setImagePreviews((prev) => [...prev, reader.result]);
      };
      reader.readAsDataURL(file);
    });
  };

  // 이미지 삭제 다이얼로그 열기
  const openDeleteDialog = (index) => {
    setDeleteTargetIndex(index);
    setDeleteDialogOpen(true);
  };

  // 이미지 삭제 확인
  const confirmDeleteImage = () => {
    if (deleteTargetIndex !== null) {
      const deletedImage = formData.images[deleteTargetIndex];
      const newImages = formData.images.filter(
        (_, i) => i !== deleteTargetIndex
      );
      const newPreviews = imagePreviews.filter(
        (_, i) => i !== deleteTargetIndex
      );
      setFormData({ ...formData, images: newImages });
      setImagePreviews(newPreviews);
      
      // 기존 이미지(서버에 있는)를 삭제한 경우 existingImageIds에서도 제거
      if (deletedImage && deletedImage.id) {
        setExistingImageIds(prev => prev.filter(id => id !== deletedImage.id));
      }
    }
    setDeleteDialogOpen(false);
    setDeleteTargetIndex(null);
  };

  // 라이트박스 열기
  const openLightbox = (index) => {
    setLightboxIndex(index);
    setLightboxOpen(true);
  };

  // 드래그 앤 드롭 상태
  const [draggedIndex, setDraggedIndex] = useState(null);
  const [dragOverIndex, setDragOverIndex] = useState(null);

  // 드래그 시작
  const handleDragStart = (e, index) => {
    setDraggedIndex(index);
    e.dataTransfer.effectAllowed = "move";
    // 드래그 이미지 설정
    e.dataTransfer.setData("text/plain", index);
  };

  // 드래그 오버
  const handleDragOver = (e, index) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";
    if (dragOverIndex !== index) {
      setDragOverIndex(index);
    }
  };

  // 드래그 종료
  const handleDragEnd = () => {
    setDraggedIndex(null);
    setDragOverIndex(null);
  };

  // 드롭 - 이미지 순서 변경
  const handleDrop = (e, dropIndex) => {
    e.preventDefault();
    if (draggedIndex === null || draggedIndex === dropIndex) {
      handleDragEnd();
      return;
    }

    // 새 배열 생성
    const newPreviews = [...imagePreviews];
    const newImages = [...formData.images];

    // 드래그된 아이템 제거 후 새 위치에 삽입
    const [movedPreview] = newPreviews.splice(draggedIndex, 1);
    const [movedImage] = newImages.splice(draggedIndex, 1);

    newPreviews.splice(dropIndex, 0, movedPreview);
    newImages.splice(dropIndex, 0, movedImage);

    setImagePreviews(newPreviews);
    setFormData({ ...formData, images: newImages });
    handleDragEnd();
  };

  // 카카오 장소 검색 API 호출 (엔터 키로 검색)
  const handleLocationSearch = async () => {
    if (!locationSearch.trim()) {
      setLocationResults([]);
      return;
    }

    setLocationSearching(true);
    try {
      const token = localStorage.getItem("adminToken");
      const response = await fetch(
        `/api/admin/kakao/places?query=${encodeURIComponent(locationSearch)}`,
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        }
      );

      if (response.ok) {
        const data = await response.json();
        setLocationResults(data.documents || []);
      }
    } catch (error) {
      console.error("장소 검색 오류:", error);
    } finally {
      setLocationSearching(false);
    }
  };

  // 장소 선택
  const selectLocation = (place) => {
    setFormData({
      ...formData,
      locationName: place.place_name,
      locationAddress: place.road_address_name || place.address_name,
      locationLat: parseFloat(place.y),
      locationLng: parseFloat(place.x),
    });
    setLocationDialogOpen(false);
    setLocationSearch("");
    setLocationResults([]);
  };

  // 폼 제출
  const handleSubmit = async (e) => {
    e.preventDefault();

    // 유효성 검사
    if (!formData.title.trim()) {
      setToast({ type: "error", message: "제목을 입력해주세요." });
      return;
    }
    // 날짜 검증: 단일/기간 모드 모두 startDate를 사용함
    if (!formData.startDate) {
      setToast({ type: "error", message: "날짜를 선택해주세요." });
      return;
    }

    if (!formData.category) {
      setToast({ type: "error", message: "카테고리를 선택해주세요." });
      return;
    }

    setSaving(true);

    try {
      const token = localStorage.getItem("adminToken");

      // FormData 생성
      const submitData = new FormData();

      // JSON 데이터 - 항상 startDate를 date로 사용 (UI에서 단일/기간 모드 모두 startDate 사용)
      const jsonData = {
        title: formData.title.trim(),
        date: formData.startDate,
        time: formData.startTime || null,
        endDate: formData.isRange ? formData.endDate : null,
        endTime: formData.isRange ? formData.endTime : null,
        isRange: formData.isRange,
        category: formData.category,
        description: formData.description.trim() || null,
        url: formData.url.trim() || null,
        sourceName: formData.sourceName.trim() || null,
        members: formData.members,
        locationName: formData.locationName.trim() || null,
        locationAddress: formData.locationAddress.trim() || null,
        locationDetail: formData.locationDetail?.trim() || null,
        locationLat: formData.locationLat,
        locationLng: formData.locationLng,
      };

      // 수정 모드일 경우 유지할 기존 이미지 ID 추가
      if (isEditMode) {
        jsonData.existingImages = existingImageIds;
      }

      submitData.append("data", JSON.stringify(jsonData));

      // 이미지 파일 추가 (새로 추가된 이미지만)
      for (const image of formData.images) {
        if (image.file) {
          submitData.append("images", image.file);
        }
      }

      // 수정 모드면 PUT, 생성 모드면 POST
      const url = isEditMode
        ? `/api/admin/schedules/${id}`
        : "/api/admin/schedules";
      const method = isEditMode ? "PUT" : "POST";

      const response = await fetch(url, {
        method,
        headers: {
          Authorization: `Bearer ${token}`,
        },
        body: submitData,
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(
          error.error ||
            (isEditMode
              ? "일정 수정에 실패했습니다."
              : "일정 생성에 실패했습니다.")
        );
      }

      // 성공 메시지를 sessionStorage에 저장하고 목록 페이지로 이동
      sessionStorage.setItem(
        "scheduleToast",
        JSON.stringify({
          type: "success",
          message: isEditMode
            ? "일정이 수정되었습니다."
            : "일정이 추가되었습니다.",
        })
      );
      navigate("/admin/schedule");
    } catch (error) {
      console.error("일정 저장 오류:", error);
      setToast({
        type: "error",
        message: error.message || "일정 저장 중 오류가 발생했습니다.",
      });
    } finally {
      setSaving(false);
    }
  };

  return (
    <AdminLayout user={user}>
      <Toast toast={toast} onClose={() => setToast(null)} />

      {/* 삭제 확인 다이얼로그 */}
      <ConfirmDialog
        isOpen={deleteDialogOpen}
        onClose={() => setDeleteDialogOpen(false)}
        onConfirm={confirmDeleteImage}
        title="이미지 삭제"
        message={
          <>
            이 이미지를 삭제하시겠습니까?
            <br />
            <span className="text-sm text-red-500">이 작업은 되돌릴 수 없습니다.</span>
          </>
        }
      />

      {/* 장소 검색 다이얼로그 */}
      <AnimatePresence>
        {locationDialogOpen && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
            onClick={() => {
              setLocationDialogOpen(false);
              setLocationSearch("");
              setLocationResults([]);
            }}
          >
            <motion.div
              initial={{ scale: 0.9, opacity: 0 }}
              animate={{ scale: 1, opacity: 1 }}
              exit={{ scale: 0.9, opacity: 0 }}
              className="bg-white rounded-2xl p-6 max-w-lg w-full mx-4 shadow-xl"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="flex items-center justify-between mb-4">
                <h3 className="text-lg font-bold text-gray-900">장소 검색</h3>
                <button
                  type="button"
                  onClick={() => {
                    setLocationDialogOpen(false);
                    setLocationSearch("");
                    setLocationResults([]);
                  }}
                  className="text-gray-400 hover:text-gray-600"
                >
                  <X size={20} />
                </button>
              </div>

              {/* 검색 입력 */}
              <div className="flex gap-2 mb-4">
                <div className="flex-1 relative">
                  <Search
                    size={18}
                    className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"
                  />
                  <input
                    type="text"
                    value={locationSearch}
                    onChange={(e) => setLocationSearch(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") {
                        e.preventDefault();
                        handleLocationSearch();
                      }
                    }}
                    placeholder="장소명을 입력하세요"
                    className="w-full pl-12 pr-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
                    autoFocus
                  />
                </div>
                <button
                  type="button"
                  onClick={handleLocationSearch}
                  disabled={locationSearching}
                  className="px-4 py-3 bg-primary text-white rounded-xl hover:bg-primary-dark transition-colors disabled:opacity-50"
                >
                  {locationSearching ? (
                    <motion.div
                      animate={{ rotate: 360 }}
                      transition={{
                        duration: 1,
                        repeat: Infinity,
                        ease: "linear",
                      }}
                    >
                      <Search size={18} />
                    </motion.div>
                  ) : (
                    "검색"
                  )}
                </button>
              </div>

              {/* 검색 결과 */}
              <div className="max-h-80 overflow-y-auto pr-2">
                {locationResults.length > 0 ? (
                  <div className="space-y-2">
                    {locationResults.map((place, index) => (
                      <button
                        key={index}
                        type="button"
                        onClick={() => selectLocation(place)}
                        className="w-full p-3 text-left hover:bg-gray-50 rounded-xl flex items-start gap-3 border border-gray-100"
                      >
                        <MapPin
                          size={18}
                          className="text-gray-400 mt-0.5 flex-shrink-0"
                        />
                        <div className="flex-1 min-w-0">
                          <p className="font-medium text-gray-900">
                            {place.place_name}
                          </p>
                          <p className="text-sm text-gray-500 truncate">
                            {place.road_address_name || place.address_name}
                          </p>
                          {place.category_name && (
                            <p className="text-xs text-gray-400 mt-1">
                              {place.category_name}
                            </p>
                          )}
                        </div>
                      </button>
                    ))}
                  </div>
                ) : locationSearch && !locationSearching ? (
                  <div className="text-center py-8 text-gray-500">
                    <MapPin size={32} className="mx-auto mb-2 text-gray-300" />
                    <p>검색어를 입력하고 검색 버튼을 눌러주세요</p>
                  </div>
                ) : (
                  <div className="text-center py-8 text-gray-500">
                    <MapPin size={32} className="mx-auto mb-2 text-gray-300" />
                    <p>장소명을 입력하고 검색해주세요</p>
                  </div>
                )}
              </div>
            </motion.div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* 이미지 라이트박스 - 공통 컴포넌트 사용 */}
      <Lightbox
        images={imagePreviews}
        currentIndex={lightboxIndex}
        isOpen={lightboxOpen}
        onClose={() => setLightboxOpen(false)}
        onIndexChange={setLightboxIndex}
      />

      {/* 메인 콘텐츠 */}
      <div className="max-w-4xl mx-auto px-6 py-8">
        {/* 브레드크럼 */}
        <div className="flex items-center gap-2 text-sm text-gray-400 mb-8">
          <Link
            to="/admin/dashboard"
            className="hover:text-primary transition-colors"
          >
            <Home size={16} />
          </Link>
          <ChevronRight size={14} />
          <Link
            to="/admin/schedule"
            className="hover:text-primary transition-colors"
          >
            일정 관리
          </Link>
          <ChevronRight size={14} />
          <span className="text-gray-700">
            {isEditMode ? "일정 수정" : "일정 추가"}
          </span>
        </div>

        {/* 타이틀 */}
        <div className="mb-8">
          <h1 className="text-3xl font-bold text-gray-900 mb-2">
            {isEditMode ? "일정 수정" : "일정 추가"}
          </h1>
          <p className="text-gray-500">새로운 일정을 등록합니다</p>
        </div>

        {/* 폼 */}
        <form onSubmit={handleSubmit} className="space-y-8">
          {/* 기본 정보 카드 */}
          <div className="bg-white rounded-2xl shadow-sm p-8">
            <h2 className="text-lg font-bold text-gray-900 mb-6">기본 정보</h2>

            <div className="space-y-6">
              {/* 제목 */}
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  제목 *
                </label>
                <input
                  type="text"
                  value={formData.title}
                  onChange={(e) =>
                    setFormData({ ...formData, title: e.target.value })
                  }
                  placeholder="일정 제목을 입력하세요"
                  className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
                  required
                />
              </div>

              {/* 범위 설정 토글 */}
              <div className="flex items-center gap-3">
                <button
                  type="button"
                  onClick={() =>
                    setFormData({ ...formData, isRange: !formData.isRange })
                  }
                  className={`relative w-12 h-6 rounded-full transition-colors ${
                    formData.isRange ? "bg-primary" : "bg-gray-300"
                  }`}
                >
                  <span
                    className={`absolute top-0.5 w-5 h-5 bg-white rounded-full shadow transition-all ${
                      formData.isRange ? "left-6" : "left-0.5"
                    }`}
                  />
                </button>
                <span className="text-sm text-gray-700">
                  기간 설정 (시작~종료)
                </span>
              </div>

              {/* 날짜 + 시간 */}
              {formData.isRange ? (
                // 범위 설정 모드
                <div className="space-y-4">
                  {/* 시작 */}
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        시작 날짜 *
                      </label>
                      <CustomDatePicker
                        value={formData.startDate}
                        onChange={(date) =>
                          setFormData({ ...formData, startDate: date })
                        }
                        placeholder="시작 날짜 선택"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        시작 시간
                      </label>
                      <CustomTimePicker
                        value={formData.startTime}
                        onChange={(time) =>
                          setFormData({ ...formData, startTime: time })
                        }
                        placeholder="시작 시간 선택"
                      />
                    </div>
                  </div>
                  {/* 종료 */}
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        종료 날짜 *
                      </label>
                      <CustomDatePicker
                        value={formData.endDate}
                        onChange={(date) =>
                          setFormData({ ...formData, endDate: date })
                        }
                        placeholder="종료 날짜 선택"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">
                        종료 시간
                      </label>
                      <CustomTimePicker
                        value={formData.endTime}
                        onChange={(time) =>
                          setFormData({ ...formData, endTime: time })
                        }
                        placeholder="종료 시간 선택"
                      />
                    </div>
                  </div>
                </div>
              ) : (
                // 단일 날짜 모드
                <div className="grid grid-cols-2 gap-6">
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-2">
                      날짜 *
                    </label>
                    <CustomDatePicker
                      value={formData.startDate}
                      onChange={(date) =>
                        setFormData({ ...formData, startDate: date })
                      }
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-2">
                      시간
                    </label>
                    <CustomTimePicker
                      value={formData.startTime}
                      onChange={(time) =>
                        setFormData({ ...formData, startTime: time })
                      }
                    />
                  </div>
                </div>
              )}

              {/* 카테고리 */}
              <div>
                <div className="flex items-center justify-between mb-2">
                  <label className="block text-sm font-medium text-gray-700">
                    카테고리 *
                  </label>
                  <Link
                    to="/admin/schedule/categories"
                    className="flex items-center gap-1 text-xs text-gray-400 hover:text-primary transition-colors"
                  >
                    <Settings size={12} />
                    카테고리 관리
                  </Link>
                </div>
                <div className="flex flex-wrap gap-3">
                  {categories.map((category) => (
                    <button
                      key={category.id}
                      type="button"
                      onClick={() =>
                        setFormData({ ...formData, category: category.id })
                      }
                      className={`flex items-center justify-center gap-2 px-4 py-3 rounded-xl border-2 transition-all ${
                        formData.category === category.id
                          ? "border-primary bg-primary/5"
                          : "border-gray-200 hover:border-gray-300"
                      }`}
                    >
                      <span
                        className={`w-2.5 h-2.5 rounded-full ${
                          getColorStyle(category.color).className || ""
                        }`}
                        style={getColorStyle(category.color).style}
                      />
                      <span className="text-sm font-medium">
                        {category.name}
                      </span>
                    </button>
                  ))}
                </div>
              </div>

              {/* 장소 */}
              <div>
                <div className="flex items-center justify-between mb-2">
                  <label className="block text-sm font-medium text-gray-700">
                    장소
                  </label>
                  {/* 검색으로 입력된 경우(좌표가 있는 경우) 초기화 버튼 표시 */}
                  {formData.locationLat && formData.locationLng && (
                    <button
                      type="button"
                      onClick={() =>
                        setFormData({
                          ...formData,
                          locationName: '',
                          locationAddress: '',
                          locationDetail: '',
                          locationLat: null,
                          locationLng: null,
                        })
                      }
                      className="text-xs text-gray-400 hover:text-red-500 transition-colors flex items-center gap-1"
                    >
                      <X size={12} />
                      초기화
                    </button>
                  )}
                </div>
                <div className="space-y-3">
                  {/* 장소 이름 + 검색 버튼 */}
                  <div className="flex gap-2">
                    <div className="flex-1 relative">
                      <MapPin
                        size={18}
                        className={`absolute left-4 top-1/2 -translate-y-1/2 ${formData.locationLat ? 'text-primary' : 'text-gray-400'}`}
                      />
                      <input
                        type="text"
                        value={formData.locationName}
                        onChange={(e) =>
                          setFormData({
                            ...formData,
                            locationName: e.target.value,
                          })
                        }
                        placeholder="장소 이름 (예: 잠실실내체육관)"
                        disabled={!!(formData.locationLat && formData.locationLng)}
                        className={`w-full pl-12 pr-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent ${formData.locationLat && formData.locationLng ? 'bg-gray-50 text-gray-700 cursor-not-allowed' : ''}`}
                      />
                    </div>
                    <button
                      type="button"
                      onClick={() => setLocationDialogOpen(true)}
                      className="px-4 py-3 bg-gray-100 text-gray-600 rounded-xl hover:bg-gray-200 transition-colors flex items-center gap-2"
                    >
                      <Search size={18} />
                      <span className="hidden sm:inline">검색</span>
                    </button>
                  </div>

                  {/* 주소 */}
                  <input
                    type="text"
                    value={formData.locationAddress}
                    onChange={(e) =>
                      setFormData({
                        ...formData,
                        locationAddress: e.target.value,
                      })
                    }
                    placeholder="주소 (예: 서울특별시 송파구 올림픽로 25)"
                    disabled={!!(formData.locationLat && formData.locationLng)}
                    className={`w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent ${formData.locationLat && formData.locationLng ? 'bg-gray-50 text-gray-700 cursor-not-allowed' : ''}`}
                  />

                  {/* 상세주소 */}
                  <input
                    type="text"
                    value={formData.locationDetail}
                    onChange={(e) =>
                      setFormData({
                        ...formData,
                        locationDetail: e.target.value,
                      })
                    }
                    placeholder="상세주소 (예: 3관 A구역, N열 등)"
                    className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
                  />
                </div>
              </div>

              {/* 설명 */}
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  설명
                </label>
                <div className="border border-gray-200 rounded-xl overflow-hidden focus-within:ring-2 focus-within:ring-primary focus-within:border-transparent">
                  <textarea
                    rows={6}
                    value={formData.description}
                    onChange={(e) =>
                      setFormData({ ...formData, description: e.target.value })
                    }
                    placeholder="일정에 대한 설명을 입력하세요"
                    className="w-full px-4 py-3 border-none focus:outline-none resize-none"
                  />
                </div>
              </div>

              {/* URL */}
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  관련 URL
                </label>
                <div className="relative">
                  <LinkIcon
                    size={18}
                    className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"
                  />
                  <input
                    type="url"
                    value={formData.url}
                    onChange={(e) =>
                      setFormData({ ...formData, url: e.target.value })
                    }
                    placeholder="https://..."
                    className="w-full pl-12 pr-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
                  />
                </div>
              </div>

              {/* 출처 이름 */}
              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  출처 이름
                </label>
                <input
                  type="text"
                  value={formData.sourceName}
                  onChange={(e) =>
                    setFormData({ ...formData, sourceName: e.target.value })
                  }
                  placeholder="예: 스프:스튜디오 프로미스나인, MUSINSA TV"
                  className="w-full px-4 py-3 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
                />
              </div>
            </div>
          </div>

          {/* 멤버 선택 카드 */}
          <div className="bg-white rounded-2xl shadow-sm p-8">
            <div className="flex items-center justify-between mb-6">
              <div className="flex items-center gap-2">
                <Users size={20} className="text-primary" />
                <h2 className="text-lg font-bold text-gray-900">참여 멤버</h2>
              </div>
              <button
                type="button"
                onClick={toggleAllMembers}
                className="text-sm text-primary hover:underline"
              >
                {formData.members.length === members.length
                  ? "전체 해제"
                  : "전체 선택"}
              </button>
            </div>

            <div className="grid grid-cols-5 gap-4">
              {members.map((member) => (
                <button
                  key={member.id}
                  type="button"
                  onClick={() => toggleMember(member.id)}
                  className={`relative rounded-xl overflow-hidden transition-all ${
                    formData.members.includes(member.id)
                      ? "ring-2 ring-primary ring-offset-2"
                      : "hover:opacity-80"
                  }`}
                >
                  <div className="aspect-[3/4] bg-gray-100">
                    {member.image_url ? (
                      <img
                        src={member.image_url}
                        alt={member.name}
                        className="w-full h-full object-cover"
                      />
                    ) : (
                      <div className="w-full h-full flex items-center justify-center bg-gray-200">
                        <Users size={24} className="text-gray-400" />
                      </div>
                    )}
                  </div>
                  <div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/70 to-transparent p-3">
                    <p className="text-white text-sm font-medium">
                      {member.name}
                    </p>
                  </div>
                  {formData.members.includes(member.id) && (
                    <div className="absolute top-2 right-2 w-6 h-6 bg-primary rounded-full flex items-center justify-center">
                      <Check size={14} className="text-white" />
                    </div>
                  )}
                </button>
              ))}
            </div>
          </div>

          {/* 다중 이미지 업로드 카드 */}
          <div className="bg-white rounded-2xl shadow-sm p-8">
            <div className="flex items-center gap-2 mb-6">
              <Image size={20} className="text-primary" />
              <h2 className="text-lg font-bold text-gray-900">일정 이미지</h2>
              <span className="text-sm text-gray-400 ml-2">
                여러 장 업로드 가능
              </span>
            </div>

            {/* 이미지 그리드 */}
            <div className="grid grid-cols-4 gap-4">
              {/* 이미지 추가 버튼 - 항상 첫번째 */}
              <label className="aspect-square border-2 border-dashed border-gray-200 rounded-xl cursor-pointer hover:border-primary/50 hover:bg-primary/5 transition-colors flex flex-col items-center justify-center">
                <input
                  type="file"
                  accept="image/*"
                  multiple
                  onChange={handleImagesUpload}
                  className="hidden"
                />
                <Plus size={24} className="text-gray-400 mb-2" />
                <p className="text-sm text-gray-500">이미지 추가</p>
              </label>

              {/* 이미지 목록 - 드래그 앤 드롭 가능 */}
              {imagePreviews.map((preview, index) => (
                <div
                  key={index}
                  className={`relative aspect-square rounded-xl overflow-hidden group cursor-grab active:cursor-grabbing transition-all duration-200 ${
                    draggedIndex === index ? "opacity-50 scale-95" : ""
                  } ${
                    dragOverIndex === index && draggedIndex !== index
                      ? "ring-2 ring-primary ring-offset-2"
                      : ""
                  }`}
                  draggable
                  onDragStart={(e) => handleDragStart(e, index)}
                  onDragOver={(e) => handleDragOver(e, index)}
                  onDragEnd={handleDragEnd}
                  onDrop={(e) => handleDrop(e, index)}
                >
                  {/* 이미지 클릭시 라이트박스 열기 */}
                  <img
                    src={preview}
                    alt={`업로드 ${index + 1}`}
                    className="w-full h-full object-cover"
                    onClick={() => openLightbox(index)}
                    draggable={false}
                  />
                  {/* 호버시 어두운 오버레이 */}
                  <div className="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors pointer-events-none" />
                  {/* 순서 표시 */}
                  <div className="absolute bottom-2 left-2 px-2 py-0.5 bg-black/50 rounded-full text-white text-xs font-medium">
                    {index + 1}
                  </div>
                  {/* 삭제 버튼 */}
                  <button
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation();
                      openDeleteDialog(index);
                    }}
                    className="absolute top-2 right-2 w-7 h-7 bg-black/50 hover:bg-red-500 rounded-full flex items-center justify-center transition-all shadow-lg"
                  >
                    <X size={14} className="text-white" />
                  </button>
                </div>
              ))}
            </div>
          </div>

          {/* 버튼 */}
          <div className="flex items-center justify-end gap-4">
            <button
              type="button"
              onClick={() => navigate("/admin/schedule")}
              className="px-6 py-3 text-gray-700 hover:bg-gray-100 rounded-xl transition-colors font-medium"
            >
              취소
            </button>
            <button
              type="submit"
              disabled={loading || saving}
              className="flex items-center gap-2 px-6 py-3 bg-primary text-white rounded-xl hover:bg-primary-dark transition-colors font-medium disabled:opacity-50"
            >
              {saving ? (
                <>
                  <span className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
                  저장 중...
                </>
              ) : (
                <>
                  <Save size={18} />
                  {isEditMode ? "수정하기" : "추가하기"}
                </>
              )}
            </button>
          </div>
        </form>
      </div>
    </AdminLayout>
  );
}

export default AdminScheduleForm;
