import { useState, useEffect } from 'react';
import { useNavigate, Link, useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { formatDate } from '@/utils/date';
import {
  Home,
  ChevronRight,
  Save,
  X,
  Link as LinkIcon,
  MapPin,
  Settings,
  Search,
} from 'lucide-react';
import { Toast, Lightbox } from '@/components/common';
import { AdminLayout, ConfirmDialog, DatePicker, TimePicker } from '@/components/pc/admin';
import {
  LocationSearchDialog,
  MemberSelector,
  ImageUploader,
} from '@/components/pc/admin/schedule';
import { useAdminAuth } from '@/hooks/pc/admin';
import { useToast } from '@/hooks/common';
import * as categoriesApi from '@/api/admin/categories';
import * as schedulesApi from '@/api/admin/schedules';
import { getMembers } from '@/api/public/members';
import { getColorStyle } from '@/utils/color';
import useAuthStore from '@/stores/useAuthStore';

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

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

  // 폼 데이터 (날짜/시간 범위 지원)
  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);

  // 멤버 목록 조회
  const { data: membersData = [] } = useQuery({
    queryKey: ['members'],
    queryFn: getMembers,
    enabled: isAuthenticated,
    staleTime: 5 * 60 * 1000,
  });
  const members = membersData.filter((m) => !m.is_former);

  // 카테고리 목록 조회
  const { data: categories = [] } = useQuery({
    queryKey: ['admin', 'categories'],
    queryFn: categoriesApi.getCategories,
    enabled: isAuthenticated,
    staleTime: 5 * 60 * 1000,
  });

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

  // 장소 검색 다이얼로그 상태
  const [locationDialogOpen, setLocationDialogOpen] = useState(false);

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

  // 첫 번째 카테고리를 기본값으로 설정
  useEffect(() => {
    if (categories.length > 0 && !formData.category && !isEditMode) {
      setFormData((prev) => ({ ...prev, category: categories[0].id }));
    }
  }, [categories, isEditMode]);

  // 수정 모드일 경우 기존 데이터 로드
  useEffect(() => {
    if (isAuthenticated && 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 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 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);
  };

  // 장소 선택 핸들러 (LocationSearchDialog에서 호출)
  const handleLocationSelect = (place) => {
    setFormData({
      ...formData,
      locationName: place.name,
      locationAddress: place.address,
      locationLat: place.lat,
      locationLng: place.lng,
    });
  };

  // 이미지 업로드 핸들러 (ImageUploader에서 호출)
  const handleImagesUploadFromUploader = (files) => {
    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);
    });
  };

  // 이미지 삭제 핸들러 (ImageUploader에서 호출)
  const handleImageDelete = (index) => {
    setDeleteTargetIndex(index);
    setDeleteDialogOpen(true);
  };

  // 이미지 순서 변경 핸들러 (ImageUploader에서 호출)
  const handleImageReorder = (fromIndex, toIndex) => {
    const newPreviews = [...imagePreviews];
    const newImages = [...formData.images];

    const [movedPreview] = newPreviews.splice(fromIndex, 1);
    const [movedImage] = newImages.splice(fromIndex, 1);

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

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

  // 폼 제출
  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 = useAuthStore.getState().token;

      // 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>
          </>
        }
      />

      {/* 장소 검색 다이얼로그 */}
      <LocationSearchDialog
        isOpen={locationDialogOpen}
        onClose={() => setLocationDialogOpen(false)}
        onSelect={handleLocationSelect}
      />

      {/* 이미지 라이트박스 - 공통 컴포넌트 사용 */}
      <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>
                      <DatePicker
                        value={formData.startDate}
                        onChange={(date) => setFormData({ ...formData, startDate: date })}
                        placeholder="시작 날짜 선택"
                        minYear={2017}
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">시작 시간</label>
                      <TimePicker
                        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>
                      <DatePicker
                        value={formData.endDate}
                        onChange={(date) => setFormData({ ...formData, endDate: date })}
                        placeholder="종료 날짜 선택"
                        minYear={2017}
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium text-gray-700 mb-2">종료 시간</label>
                      <TimePicker
                        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>
                    <DatePicker
                      value={formData.startDate}
                      onChange={(date) => setFormData({ ...formData, startDate: date })}
                      minYear={2017}
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-2">시간</label>
                    <TimePicker
                      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>

          {/* 멤버 선택 카드 */}
          <MemberSelector
            members={members}
            selectedIds={formData.members}
            onToggle={toggleMember}
            onToggleAll={toggleAllMembers}
          />

          {/* 다중 이미지 업로드 카드 */}
          <ImageUploader
            previews={imagePreviews}
            onUpload={handleImagesUploadFromUploader}
            onDelete={handleImageDelete}
            onReorder={handleImageReorder}
            onOpenLightbox={openLightbox}
          />

          {/* 버튼 */}
          <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 ScheduleForm;
