/**
 * 축제 봇 추가/수정 다이얼로그
 */
import { useState, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { motion, AnimatePresence } from 'framer-motion';
import { X, ChevronDown, Loader2, PartyPopper } from 'lucide-react';
import { getFestivalBot, createFestivalBot, updateFestivalBot } from '@/api/admin/bots';

// 동기화 간격 옵션 (분 단위)
const INTERVAL_OPTIONS = [
  { value: 60, label: '1시간' },
  { value: 180, label: '3시간' },
  { value: 360, label: '6시간' },
  { value: 720, label: '12시간' },
  { value: 1440, label: '24시간' },
];

const ALL_MONTHS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

/**
 * 커스텀 드롭다운 (Portal 사용)
 */
function Dropdown({ value, options, onChange, placeholder = '선택' }) {
  const [isOpen, setIsOpen] = useState(false);
  const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });
  const buttonRef = useRef(null);
  const menuRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (
        buttonRef.current &&
        !buttonRef.current.contains(event.target) &&
        menuRef.current &&
        !menuRef.current.contains(event.target)
      ) {
        setIsOpen(false);
      }
    };
    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
    }
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [isOpen]);

  useEffect(() => {
    if (isOpen && buttonRef.current) {
      const rect = buttonRef.current.getBoundingClientRect();
      setPosition({ top: rect.bottom + 4, left: rect.left, width: rect.width });
    }
  }, [isOpen]);

  const selectedOption = options.find((opt) => opt.value === value);

  return (
    <div className="relative">
      <button
        ref={buttonRef}
        type="button"
        onClick={() => setIsOpen(!isOpen)}
        className="flex items-center gap-2 w-full px-4 py-2.5 bg-gray-100 hover:bg-gray-200 rounded-lg text-sm transition-colors justify-between"
      >
        <span className={selectedOption ? 'text-gray-900' : 'text-gray-400'}>
          {selectedOption?.label || placeholder}
        </span>
        <ChevronDown
          size={14}
          className={`text-gray-400 transition-transform ${isOpen ? 'rotate-180' : ''}`}
        />
      </button>
      {createPortal(
        <AnimatePresence>
          {isOpen && (
            <motion.div
              ref={menuRef}
              initial={{ opacity: 0, y: -10 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -10 }}
              transition={{ duration: 0.15 }}
              style={{
                position: 'fixed',
                top: position.top,
                left: position.left,
                width: position.width,
                zIndex: 9999,
              }}
              className="bg-white rounded-xl shadow-lg border border-gray-200 py-1 max-h-60 overflow-y-auto"
            >
              {options.map((opt) => (
                <button
                  key={opt.value}
                  type="button"
                  onClick={() => {
                    onChange(opt.value);
                    setIsOpen(false);
                  }}
                  className={`w-full px-4 py-2 text-left hover:bg-gray-50 transition-colors text-sm ${
                    value === opt.value ? 'bg-amber-50 text-amber-600' : ''
                  }`}
                >
                  {opt.label}
                </button>
              ))}
            </motion.div>
          )}
        </AnimatePresence>,
        document.body
      )}
    </div>
  );
}

function FestivalBotDialog({ isOpen, onClose, botId = null, onSuccess }) {
  const queryClient = useQueryClient();
  const isEdit = !!botId;

  // 폼 상태
  const [name, setName] = useState('');
  const [searchUrl, setSearchUrl] = useState('');
  const [interval, setInterval] = useState(360);
  const [activeMonths, setActiveMonths] = useState(ALL_MONTHS);
  const [submitting, setSubmitting] = useState(false);

  const allMonthsSelected = activeMonths.length === ALL_MONTHS.length;
  const toggleMonth = (m) =>
    setActiveMonths((prev) =>
      prev.includes(m) ? prev.filter((x) => x !== m) : [...prev, m].sort((a, b) => a - b)
    );
  const toggleAllMonths = () =>
    setActiveMonths(allMonthsSelected ? [] : [...ALL_MONTHS]);

  // 축제 봇 상세 조회 (수정 모드)
  const { data: bot, isLoading: botLoading } = useQuery({
    queryKey: ['admin', 'festival-bot', botId],
    queryFn: () => getFestivalBot(botId),
    enabled: isOpen && !!botId,
    staleTime: 0,
  });

  // 다이얼로그 열릴 때 데이터 설정
  useEffect(() => {
    if (!isOpen) return;

    if (bot) {
      // 수정 모드
      setName(bot.name || '');
      setSearchUrl(bot.search_url || '');
      setInterval(bot.cron_interval || 360);
      // active_months: null(전체) → 전체 선택, 배열이면 그대로
      setActiveMonths(
        Array.isArray(bot.active_months) && bot.active_months.length > 0
          ? bot.active_months
          : [...ALL_MONTHS]
      );
    } else if (!botId) {
      // 추가 모드 (기본: 전체 월 = 항상 실행)
      setName('');
      setSearchUrl('');
      setInterval(360);
      setActiveMonths([...ALL_MONTHS]);
    }
  }, [isOpen, bot, botId]);

  // 제출
  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!name.trim() || !searchUrl.trim()) return;

    setSubmitting(true);
    try {
      const data = {
        name: name.trim(),
        search_url: searchUrl.trim(),
        cron_interval: interval,
        // 전체 선택(또는 미선택)은 제한 없음(null)으로 저장
        active_months: allMonthsSelected ? null : activeMonths,
      };

      if (isEdit) {
        await updateFestivalBot(botId, data);
      } else {
        await createFestivalBot(data);
      }

      queryClient.invalidateQueries({ queryKey: ['admin', 'bots'] });
      queryClient.invalidateQueries({ queryKey: ['admin', 'festival-bot'] });

      onSuccess?.();
      onClose();
    } catch (error) {
      console.error('봇 저장 실패:', error);
      alert(error.message || '봇 저장에 실패했습니다.');
    } finally {
      setSubmitting(false);
    }
  };

  return createPortal(
    <AnimatePresence>
      {isOpen && (
        <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"
        >
          <motion.div
            initial={{ scale: 0.95, opacity: 0 }}
            animate={{ scale: 1, opacity: 1 }}
            exit={{ scale: 0.95, opacity: 0 }}
            className="bg-white rounded-2xl w-full max-w-lg mx-4 shadow-xl max-h-[90vh] overflow-hidden flex flex-col"
            onClick={(e) => e.stopPropagation()}
          >
            {/* 헤더 */}
            <div className="flex items-center justify-between px-6 py-4 border-b border-gray-100">
              <div className="flex items-center gap-3">
                <div className="w-10 h-10 rounded-lg bg-amber-50 flex items-center justify-center">
                  <PartyPopper size={20} className="text-amber-500" />
                </div>
                <h2 className="text-lg font-bold text-gray-900">
                  {isEdit ? '축제 봇 수정' : '축제 봇 추가'}
                </h2>
              </div>
              <button
                onClick={onClose}
                className="p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
              >
                <X size={20} />
              </button>
            </div>

            {/* 본문 */}
            {botLoading ? (
              <div className="flex-1 flex items-center justify-center p-12">
                <Loader2 size={32} className="animate-spin text-amber-500" />
              </div>
            ) : (
              <form onSubmit={handleSubmit} className="flex-1 overflow-y-auto p-6 space-y-5">
                {/* 봇 이름 */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1.5">
                    봇 이름
                  </label>
                  <input
                    type="text"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                    placeholder="대학 축제 봇"
                    className="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500/20 focus:border-amber-500"
                  />
                </div>

                {/* 검색 URL */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1.5">
                    크롤링 URL
                  </label>
                  <input
                    type="url"
                    value={searchUrl}
                    onChange={(e) => setSearchUrl(e.target.value)}
                    placeholder="https://memogipost.tistory.com/search/프로미스나인"
                    className="w-full px-4 py-2.5 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500/20 focus:border-amber-500"
                  />
                  <p className="text-xs text-gray-400 mt-1">
                    축제 정보를 수집할 검색 페이지 URL을 입력하세요
                  </p>
                </div>

                {/* 동기화 간격 */}
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1.5">
                    동기화 간격
                  </label>
                  <Dropdown
                    value={interval}
                    options={INTERVAL_OPTIONS}
                    onChange={setInterval}
                    placeholder="간격 선택"
                  />
                </div>

                {/* 활성 월 */}
                <div>
                  <div className="flex items-center justify-between mb-1.5">
                    <label className="text-sm font-medium text-gray-700">활성 월</label>
                    <button
                      type="button"
                      onClick={toggleAllMonths}
                      className="text-xs font-medium text-amber-600 hover:text-amber-700"
                    >
                      {allMonthsSelected ? '전체 해제' : '전체 선택'}
                    </button>
                  </div>
                  <div className="grid grid-cols-6 gap-1.5">
                    {ALL_MONTHS.map((m) => {
                      const on = activeMonths.includes(m);
                      return (
                        <button
                          key={m}
                          type="button"
                          onClick={() => toggleMonth(m)}
                          className={`py-2 rounded-lg text-sm font-medium transition-colors ${
                            on
                              ? 'bg-amber-500 text-white'
                              : 'bg-gray-100 text-gray-400 hover:bg-gray-200'
                          }`}
                        >
                          {m}월
                        </button>
                      );
                    })}
                  </div>
                  <p className="text-xs text-gray-400 mt-1.5">
                    선택한 월에만 봇이 실행됩니다. 전체 선택 시 항상 실행됩니다.
                  </p>
                </div>
              </form>
            )}

            {/* 푸터 */}
            <div className="flex justify-end gap-3 px-6 py-4 border-t border-gray-100 bg-gray-50">
              <button
                type="button"
                onClick={onClose}
                disabled={submitting}
                className="px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-200 rounded-lg transition-colors disabled:opacity-50"
              >
                취소
              </button>
              <button
                type="submit"
                onClick={handleSubmit}
                disabled={!name.trim() || !searchUrl.trim() || submitting || botLoading}
                className="px-4 py-2.5 bg-amber-500 text-white rounded-lg hover:bg-amber-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
              >
                {submitting && <Loader2 size={16} className="animate-spin" />}
                {isEdit ? '수정' : '추가'}
              </button>
            </div>
          </motion.div>
        </motion.div>
      )}
    </AnimatePresence>,
    document.body
  );
}

export default FestivalBotDialog;
