import React, { useState, useCallback } from 'react';
import { exportCalendarToICS } from '@/features/plan/lib/calendarExport';
import { GlobeFilled, CalendarFilled } from '@/shared/icons/FilledIcons';
import { SectionWrapper } from '@/features/report/components/ui/SectionWrapper';
import { Button } from '@/shared/ui/button';
import EditEntryModal from './EditEntryModal';
import {
  contentTypeColors,
  contentTypeIcons,
  channelIconMap,
  statusDotColors,
  dayHeaders,
} from '../data/contentCalendarConstants';
import type { CalendarData, ContentCategory, CalendarEntry } from '@/features/plan/types/plan';

interface ContentCalendarProps {
  data: CalendarData;
  planId?: string;
  onEntryUpdate?: (entryId: string, updates: Partial<CalendarEntry>) => void;
}

export default function ContentCalendar({ data, planId, onEntryUpdate }: ContentCalendarProps) {
  // 마운트 시 id 없는 항목에 자동 id 부여 (드래그 식별용)
  const [weeks, setWeeks] = useState(() =>
    data.weeks.map((week) => ({
      ...week,
      entries: week.entries.map((e, i) => ({
        ...e,
        id: e.id ?? `auto-${week.weekNumber}-${i}`,
      })),
    })),
  );
  const [editingEntry, setEditingEntry] = useState<CalendarEntry | null>(null);
  const [creatingForWeek, setCreatingForWeek] = useState<number | null>(null);
  const [filterType, setFilterType] = useState<ContentCategory | null>(null);
  const [viewMode, setViewMode] = useState<'weekly' | 'monthly'>('weekly');
  // DnD 상태: 어떤 항목을 어느 주차에서 드래그 중인지 추적
  const [draggedEntry, setDraggedEntry] = useState<{ entry: CalendarEntry; weekNumber: number } | null>(null);
  const [dropTargetDay, setDropTargetDay] = useState<{ weekNumber: number; dayIdx: number } | null>(null);

  const handleEntryClick = useCallback((entry: CalendarEntry) => {
    setCreatingForWeek(null);
    setEditingEntry(entry);
  }, []);

  // 특정 주차에 대해 생성 모드로 모달 열기
  const handleAddEntry = useCallback((weekNumber: number) => {
    setCreatingForWeek(weekNumber);
    setEditingEntry({
      id: '__new__',
      dayOfWeek: 0,
      channel: 'YouTube',
      channelIcon: 'youtube',
      contentType: 'video',
      title: '',
      status: 'draft',
    });
  }, []);

  // 드래그 핸들러 — 같은 주차 내 다른 요일로 항목 이동
  const handleDragStart = useCallback((entry: CalendarEntry, weekNumber: number) => {
    setDraggedEntry({ entry, weekNumber });
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>, weekNumber: number, dayIdx: number) => {
    e.preventDefault(); // drop 허용을 위해 필요
    setDropTargetDay({ weekNumber, dayIdx });
  }, []);

  const handleDragLeave = useCallback(() => {
    setDropTargetDay(null);
  }, []);

  const handleDrop = useCallback((weekNumber: number, dayIdx: number) => {
    const draggedId = draggedEntry?.entry.id;
    if (!draggedEntry || !draggedId) return;
    const sourceWeek = draggedEntry.weekNumber;
    setWeeks((prev) =>
      prev.map((week) => {
        // 같은 주차 내 이동
        if (sourceWeek === weekNumber && week.weekNumber === weekNumber) {
          return {
            ...week,
            entries: week.entries.map((e) =>
              e.id === draggedId ? { ...e, dayOfWeek: dayIdx, isManualEdit: true } : e,
            ),
          };
        }
        // 다른 주차로 이동 — 원본에서 제거
        if (week.weekNumber === sourceWeek) {
          return { ...week, entries: week.entries.filter((e) => e.id !== draggedId) };
        }
        // 다른 주차로 이동 — 대상에 추가
        if (week.weekNumber === weekNumber) {
          return {
            ...week,
            entries: [
              ...week.entries,
              { ...draggedEntry.entry, dayOfWeek: dayIdx, isManualEdit: true },
            ],
          };
        }
        return week;
      }),
    );
    setDraggedEntry(null);
    setDropTargetDay(null);
  }, [draggedEntry]);

  // 월간 뷰 드롭: 주차는 유지하고 요일만 변경
  const handleDropMonthly = useCallback((dayIdx: number) => {
    const draggedId = draggedEntry?.entry.id;
    if (!draggedEntry || !draggedId) return;
    setWeeks((prev) =>
      prev.map((week) => ({
        ...week,
        entries: week.entries.map((e) =>
          e.id === draggedId ? { ...e, dayOfWeek: dayIdx, isManualEdit: true } : e,
        ),
      })),
    );
    setDraggedEntry(null);
    setDropTargetDay(null);
  }, [draggedEntry]);

  const handleDragEnd = useCallback(() => {
    setDraggedEntry(null);
    setDropTargetDay(null);
  }, []);

  const handleSave = useCallback((updated: CalendarEntry) => {
    if (updated.id === '__new__' && creatingForWeek !== null) {
      // 생성 모드: 새로 생성된 id로 항목 추가
      const newEntry: CalendarEntry = {
        ...updated,
        id: `entry-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
      };
      setWeeks((prev) =>
        prev.map((week) =>
          week.weekNumber === creatingForWeek
            ? { ...week, entries: [...week.entries, newEntry] }
            : week
        )
      );
      setCreatingForWeek(null);
    } else {
      // 편집 모드: id로 기존 항목 업데이트
      setWeeks((prev) =>
        prev.map((week) => ({
          ...week,
          entries: week.entries.map((e) =>
            e.id && e.id === updated.id ? updated : e
          ),
        }))
      );
      if (onEntryUpdate && updated.id) {
        onEntryUpdate(updated.id, updated);
      }
    }
    setEditingEntry(null);
  }, [onEntryUpdate, creatingForWeek]);

  const handleClose = useCallback(() => {
    setEditingEntry(null);
    setCreatingForWeek(null);
  }, []);

  const toggleFilter = (type: ContentCategory) => {
    setFilterType((prev) => (prev === type ? null : type));
  };

  // 월간 뷰: 모든 주차를 하나의 7일 그리드로 평탄화. 카드 드래그/드롭 지원 (주차 유지, 요일만 변경).
  const renderMonthlyView = () => {
    const all = weeks.flatMap((w) =>
      w.entries.map((entry) => ({ entry, weekNumber: w.weekNumber })),
    );
    const filtered = filterType ? all.filter(({ entry }) => entry.contentType === filterType) : all;

    const dayCells: { entry: CalendarEntry; weekNumber: number }[][] = Array.from({ length: 7 }, () => []);
    for (const item of filtered) {
      if (item.entry.dayOfWeek >= 0 && item.entry.dayOfWeek <= 6) {
        dayCells[item.entry.dayOfWeek].push(item);
      }
    }

    return (
      <div className="bg-white rounded-2xl p-5 shadow-[3px_4px_12px_rgba(0,0,0,0.06)]">
        <p className="text-sm font-bold text-brand-navy mb-3">월간 종합</p>
        <div className="grid grid-cols-7 gap-2">
          {dayHeaders.map((day) => (
            <div key={day} className="text-xs text-slate-400 uppercase tracking-wide text-center mb-1 font-medium">
              {day}
            </div>
          ))}
          {dayCells.map((cell, dayIdx) => {
            const isDropTarget = dropTargetDay?.weekNumber === -1 && dropTargetDay.dayIdx === dayIdx;
            return (
              <div
                key={dayIdx}
                className={`min-h-[100px] rounded-xl p-1.5 transition-all ${
                  cell.length > 0 ? '' : 'border border-dashed border-slate-200'
                } ${isDropTarget ? 'ring-2 ring-brand-purple-vivid/40 bg-brand-tint-purple border-brand-tint-lavender' : ''}`}
                onDragOver={(e) => handleDragOver(e, -1, dayIdx)}
                onDragLeave={handleDragLeave}
                onDrop={() => handleDropMonthly(dayIdx)}
              >
                {cell.map(({ entry, weekNumber }, entryIdx) => renderEntry(entry, entryIdx, weekNumber))}
              </div>
            );
          })}
        </div>
      </div>
    );
  };

  const renderEntry = (entry: CalendarEntry, entryIdx: number, weekNumber?: number) => {
    const colors = contentTypeColors[entry.contentType];
    const ContentIcon = contentTypeIcons[entry.contentType];
    const ChannelIcon = channelIconMap[entry.channelIcon] ?? GlobeFilled;
    const statusDot = statusDotColors[entry.status ?? 'draft'];
    const isDragging = draggedEntry !== null && draggedEntry.entry === entry;

    return (
      <div
        key={entry.id ?? entryIdx}
        className={`${colors.entry} border rounded-lg p-1.5 mb-1 last:mb-0 cursor-grab active:cursor-grabbing hover:ring-2 hover:ring-brand-purple-vivid/30 hover:shadow-lg shadow-sm transition-all group relative ${isDragging ? 'opacity-40' : ''}`}
        draggable={weekNumber !== undefined}
        onDragStart={weekNumber !== undefined ? () => handleDragStart(entry, weekNumber) : undefined}
        onDragEnd={weekNumber !== undefined ? handleDragEnd : undefined}
        onClick={() => handleEntryClick(entry)}
      >
        <div className="flex items-center gap-1 mb-0.5">
          <span className={`w-1.5 h-1.5 rounded-full ${statusDot} flex-shrink-0`} />
          <ChannelIcon size={10} className={colors.text} />
          <ContentIcon size={10} className={colors.text} />
        </div>
        <p className="text-[11px] font-medium text-brand-navy leading-tight line-clamp-2">
          {entry.title}
        </p>
        {entry.description && (
          <p className="text-[9px] text-slate-400 leading-tight mt-0.5 line-clamp-1 hidden group-hover:block">
            {entry.description}
          </p>
        )}
      </div>
    );
  };

  return (
    <SectionWrapper
      id="content-calendar"
      title="Content Calendar"
      subtitle="콘텐츠 캘린더 (월간)"
      dark
    >
      {/* Toolbar: View Toggle + Status Legend */}
      <div className="flex items-center justify-between mb-6 flex-wrap gap-2" data-no-print>
        {/* View toggle — styled for dark section bg */}
        <div className="flex bg-white/10 rounded-xl p-0.5">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={() => setViewMode('weekly')}
            className={`px-3 py-1.5 text-xs font-medium rounded-lg ${
              viewMode === 'weekly'
                ? 'bg-white/20 text-white shadow-sm hover:bg-white/20 hover:text-white'
                : 'text-white/50 hover:text-white/80 hover:bg-transparent'
            }`}
          >
            주간
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={() => setViewMode('monthly')}
            className={`px-3 py-1.5 text-xs font-medium rounded-lg ${
              viewMode === 'monthly'
                ? 'bg-white/20 text-white shadow-sm hover:bg-white/20 hover:text-white'
                : 'text-white/50 hover:text-white/80 hover:bg-transparent'
            }`}
          >
            월간
          </Button>
        </div>

        {/* iCal Export Button */}
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => exportCalendarToICS(weeks)}
          className="flex items-center gap-1.5 px-3 py-1.5 rounded-xl bg-white/10 hover:bg-white/20 text-white/70 hover:text-white text-xs font-medium"
          data-no-print
        >
          <CalendarFilled size={12} />
          캘린더 내보내기
        </Button>

        {/* Status legend with design-system colors */}
        <div className="flex gap-3 text-[10px] text-white/50">
          <span className="flex items-center gap-1">
            <span className="w-1.5 h-1.5 rounded-full bg-slate-400" />초안
          </span>
          <span className="flex items-center gap-1">
            <span className="w-1.5 h-1.5 rounded-full bg-brand-purple-soft" />승인
          </span>
          <span className="flex items-center gap-1">
            <span className="w-1.5 h-1.5 rounded-full bg-[#7A84D4]" />게시됨
          </span>
        </div>
      </div>

      {/* Monthly Summary — compact counter pills (click to filter) */}
      <div className="flex flex-wrap gap-3 mb-8">
        {data.monthlySummary.map((item, i) => {
          const colors = contentTypeColors[item.type];
          const Icon = contentTypeIcons[item.type];
          const isActive = filterType === item.type;
          return (
            <Button
              type="button"
              variant="ghost"
              key={item.type}
              className={`flex items-center gap-3 px-5 py-3 h-auto rounded-2xl border cursor-pointer ${colors.bg} ${colors.border} ${colors.shadow} hover:${colors.bg} ${
                isActive ? 'ring-2 ring-white/40 ring-offset-2 ring-offset-transparent' : ''
              } ${filterType && !isActive ? 'opacity-40' : ''}`}
              onClick={() => toggleFilter(item.type)}
            >
              <Icon size={16} className={`${colors.text} opacity-70`} />
              <div className="flex flex-col items-start">
                <span className={`text-2xl font-bold leading-none ${colors.text}`}>{item.count}</span>
                <span className={`text-xs font-medium ${colors.text} opacity-70 mt-0.5`}>{item.label}</span>
              </div>
            </Button>
          );
        })}
        {filterType && (
          <Button
            type="button"
            variant="ghost"
            size="sm"
            onClick={() => setFilterType(null)}
            className="text-xs text-white/40 hover:text-white/70 hover:bg-transparent px-3 self-center"
          >
            × 해제
          </Button>
        )}
      </div>

      {/* Calendar Content */}
      {viewMode === 'monthly' ? (
        renderMonthlyView()
      ) : (
        /* Weekly Calendar Grid */
        weeks.map((week, weekIdx) => {
          const dayCells: CalendarEntry[][] = Array.from({ length: 7 }, () => []);
          for (const entry of week.entries) {
            if (filterType && entry.contentType !== filterType) continue;
            const dayIndex = entry.dayOfWeek;
            if (dayIndex >= 0 && dayIndex <= 6) {
              dayCells[dayIndex].push(entry);
            }
          }

          return (
            <div
              key={week.weekNumber}
              className="bg-white rounded-2xl p-5 mb-4 shadow-[3px_4px_12px_rgba(0,0,0,0.06)]"
            >
              <p className="text-sm font-bold text-brand-navy mb-3">{week.label}</p>

              <div className="grid grid-cols-7 gap-2">
                {dayHeaders.map((day) => (
                  <div
                    key={day}
                    className="text-xs text-slate-400 uppercase tracking-wide text-center mb-1 font-medium"
                  >
                    {day}
                  </div>
                ))}

                {dayCells.map((entries, dayIdx) => {
                  const isDropTarget = dropTargetDay?.weekNumber === week.weekNumber && dropTargetDay?.dayIdx === dayIdx;
                  return (
                    <div
                      key={dayIdx}
                      className={`min-h-[80px] rounded-xl p-1.5 transition-all ${
                        entries.length > 0
                          ? ''
                          : 'border border-dashed border-slate-200'
                      } ${isDropTarget ? 'ring-2 ring-brand-purple-vivid/40 bg-brand-tint-purple border-brand-tint-lavender' : ''}`}
                      onDragOver={(e) => handleDragOver(e, week.weekNumber, dayIdx)}
                      onDragLeave={handleDragLeave}
                      onDrop={() => handleDrop(week.weekNumber, dayIdx)}
                    >
                      {entries.map((entry, entryIdx) => renderEntry(entry, entryIdx, week.weekNumber))}
                    </div>
                  );
                })}
              </div>

              {/* Add Entry Button */}
              <Button
                type="button"
                variant="outline"
                onClick={() => handleAddEntry(week.weekNumber)}
                className="mt-3 w-full flex items-center justify-center gap-1.5 py-2 h-auto rounded-xl border-dashed border-slate-200 text-xs text-slate-400 hover:text-slate-600 hover:border-slate-300 hover:bg-slate-50/50 shadow-none"
                data-no-print
              >
                <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
                  <path strokeLinecap="round" strokeLinejoin="round" d="M12 5v14M5 12h14" />
                </svg>
                콘텐츠 추가
              </Button>
            </div>
          );
        })
      )}

      {/* Edit Modal */}
      {editingEntry && (
        <EditEntryModal
          entry={editingEntry}
          onSave={handleSave}
          onClose={handleClose}
        />
      )}
    </SectionWrapper>
  );
}
