import React, { useState, useCallback } from 'react';
import { exportCalendarToICS } from '../../lib/calendarExport';
import { motion } from 'motion/react';
import {
  VideoFilled,
  FileTextFilled,
  ShareFilled,
  MegaphoneFilled,
  YoutubeFilled,
  InstagramFilled,
  FacebookFilled,
  GlobeFilled,
  TiktokFilled,
  MessageFilled,
  CalendarFilled,
} from '../icons/FilledIcons';
import { SectionWrapper } from '../report/ui/SectionWrapper';
import EditEntryModal from './EditEntryModal';
import type { CalendarData, ContentCategory, CalendarEntry } from '../../types/plan';

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

const contentTypeColors: Record<ContentCategory, { bg: string; text: string; entry: string; border: string; shadow: string }> = {
  video: { bg: 'bg-[#F3F0FF]', text: 'text-[#6C5CE7]', entry: 'bg-[#F3F0FF] border-[#D5CDF5]', border: 'border-[#D5CDF5]', shadow: 'shadow-[2px_3px_8px_rgba(155,138,212,0.15)]' },
  blog: { bg: 'bg-[#EFF0FF]', text: 'text-[#3A3F7C]', entry: 'bg-[#EFF0FF] border-[#C5CBF5]', border: 'border-[#C5CBF5]', shadow: 'shadow-[2px_3px_8px_rgba(122,132,212,0.15)]' },
  social: { bg: 'bg-[#FFF6ED]', text: 'text-[#7C5C3A]', entry: 'bg-[#FFF6ED] border-[#F5E0C5]', border: 'border-[#F5E0C5]', shadow: 'shadow-[2px_3px_8px_rgba(212,168,114,0.15)]' },
  ad: { bg: 'bg-[#FFF0F0]', text: 'text-[#7C3A4B]', entry: 'bg-[#FFF0F0] border-[#F5D5DC]', border: 'border-[#F5D5DC]', shadow: 'shadow-[2px_3px_8px_rgba(212,136,154,0.15)]' },
};

const contentTypeLabels: Record<ContentCategory, string> = {
  video: 'Video',
  blog: 'Blog',
  social: 'Social',
  ad: 'Ad',
};

const contentTypeIcons: Record<ContentCategory, typeof VideoFilled> = {
  video: VideoFilled,
  blog: FileTextFilled,
  social: ShareFilled,
  ad: MegaphoneFilled,
};

// FilledIcon map for channel identification in calendar entries
const channelIconMap: Record<string, typeof VideoFilled> = {
  youtube: YoutubeFilled,
  instagram: InstagramFilled,
  facebook: FacebookFilled,
  blog: FileTextFilled,
  globe: GlobeFilled,
  video: TiktokFilled,
  star: GlobeFilled,
  map: GlobeFilled,
  messagesquare: MessageFilled,
};

// Semantic status colors (no raw green/red per design system)
const statusDotColors: Record<string, string> = {
  draft: 'bg-slate-400',
  approved: 'bg-[#9B8AD4]',
  published: 'bg-[#7A84D4]',
};

const dayHeaders = ['월', '화', '수', '목', '금', '토', '일'];

export default function ContentCalendar({ data, planId, onEntryUpdate }: ContentCalendarProps) {
  const [weeks, setWeeks] = useState(data.weeks);
  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 state: track which entry is being dragged and from which week
  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);
  }, []);

  // Open modal in create mode for a given week
  const handleAddEntry = useCallback((weekNumber: number) => {
    setCreatingForWeek(weekNumber);
    setEditingEntry({
      id: '__new__',
      dayOfWeek: 0,
      channel: 'YouTube',
      channelIcon: 'youtube',
      contentType: 'video',
      title: '',
      status: 'draft',
    });
  }, []);

  // Drag handlers — move an entry to a different day within the same week
  const handleDragStart = useCallback((entry: CalendarEntry, weekNumber: number) => {
    setDraggedEntry({ entry, weekNumber });
  }, []);

  const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>, weekNumber: number, dayIdx: number) => {
    e.preventDefault(); // required to allow drop
    setDropTargetDay({ weekNumber, dayIdx });
  }, []);

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

  const handleDrop = useCallback((weekNumber: number, dayIdx: number) => {
    if (!draggedEntry || draggedEntry.weekNumber !== weekNumber) return;
    setWeeks((prev) =>
      prev.map((week) =>
        week.weekNumber === weekNumber
          ? {
              ...week,
              entries: week.entries.map((e) =>
                e.id && e.id === draggedEntry.entry.id
                  ? { ...e, dayOfWeek: dayIdx, isManualEdit: true }
                  : e
              ),
            }
          : week
      )
    );
    setDraggedEntry(null);
    setDropTargetDay(null);
  }, [draggedEntry]);

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

  const handleSave = useCallback((updated: CalendarEntry) => {
    if (updated.id === '__new__' && creatingForWeek !== null) {
      // Create mode: append new entry with a generated 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 {
      // Edit mode: update existing entry by 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));
  };

  // Monthly view: flatten all weeks into one 7-day grid
  const renderMonthlyView = () => {
    const allEntries = weeks.flatMap((w) => w.entries);
    const filtered = filterType
      ? allEntries.filter((e) => e.contentType === filterType)
      : allEntries;

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

    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-[#0A1128] 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((entries, dayIdx) => (
            <div
              key={dayIdx}
              className={`min-h-[100px] rounded-xl p-1.5 ${
                entries.length > 0
                  ? 'bg-slate-50/50 border border-slate-100'
                  : 'border border-dashed border-slate-200/60'
              }`}
            >
              {entries.map((entry, entryIdx) => renderEntry(entry, entryIdx))}
            </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?.entry.id === entry.id;

    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-purple-200 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} opacity-60`} />
        </div>
        <p className="text-[11px] text-slate-700 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
            onClick={() => setViewMode('weekly')}
            className={`px-3 py-1.5 text-xs font-medium rounded-lg transition-all ${
              viewMode === 'weekly'
                ? 'bg-white/20 text-white shadow-sm'
                : 'text-white/50 hover:text-white/80'
            }`}
          >
            주간
          </button>
          <button
            onClick={() => setViewMode('monthly')}
            className={`px-3 py-1.5 text-xs font-medium rounded-lg transition-all ${
              viewMode === 'monthly'
                ? 'bg-white/20 text-white shadow-sm'
                : 'text-white/50 hover:text-white/80'
            }`}
          >
            월간
          </button>
        </div>

        {/* iCal Export Button */}
        <button
          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 transition-all"
          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-[#9B8AD4]" />승인
          </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 (
            <motion.button
              key={item.type}
              className={`flex items-center gap-3 px-5 py-3 rounded-2xl border cursor-pointer transition-all ${colors.bg} ${colors.border} ${colors.shadow} ${
                isActive ? 'ring-2 ring-white/40 ring-offset-2 ring-offset-transparent' : ''
              } ${filterType && !isActive ? 'opacity-40' : ''}`}
              onClick={() => toggleFilter(item.type)}
              initial={{ opacity: 0, y: 10 }}
              whileInView={{ opacity: 1, y: 0 }}
              viewport={{ once: true }}
              transition={{ duration: 0.3, delay: i * 0.07 }}
            >
              <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>
            </motion.button>
          );
        })}
        {filterType && (
          <button
            onClick={() => setFilterType(null)}
            className="text-xs text-white/40 hover:text-white/70 px-3 self-center transition-colors"
          >
            × 해제
          </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 (
            <motion.div
              key={week.weekNumber}
              className="bg-white rounded-2xl p-5 mb-4 shadow-[3px_4px_12px_rgba(0,0,0,0.06)]"
              initial={{ opacity: 0, y: 20 }}
              whileInView={{ opacity: 1, y: 0 }}
              viewport={{ once: true }}
              transition={{ duration: 0.4, delay: weekIdx * 0.1 }}
            >
              <p className="text-sm font-bold text-[#0A1128] 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
                          ? 'bg-slate-50/50 border border-slate-100'
                          : 'border border-dashed border-slate-200/60'
                      } ${isDropTarget ? 'ring-2 ring-[#6C5CE7]/40 bg-[#F3F0FF]/20 border-[#D5CDF5]' : ''}`}
                      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
                onClick={() => handleAddEntry(week.weekNumber)}
                className="mt-3 w-full flex items-center justify-center gap-1.5 py-2 rounded-xl border border-dashed border-slate-200 text-xs text-slate-400 hover:text-slate-600 hover:border-slate-300 hover:bg-slate-50/50 transition-all"
                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>
            </motion.div>
          );
        })
      )}

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