import { useState, useEffect, useMemo } from 'react';
import {
  ChevronLeft, ChevronRight, Plus, Clock, Video, Bell,
  Loader2, Download, Share2, Globe, Trash2, Edit, X, UserPlus, Send, ExternalLink,
} from 'lucide-react';
import api from '../services/api';
import { useAuth } from '../contexts/AuthContext';
import { useLanguage } from '../contexts/LanguageContext';
import Modal from '../components/Modal';
import DateTimePicker from '../components/DateTimePicker';
import toast from 'react-hot-toast';

const COLORS = ['#6366f1', '#ef4444', '#f59e0b', '#10b981', '#3b82f6', '#8b5cf6', '#ec4899', '#14b8a6'];

export default function Calendar() {
  const { user } = useAuth();
  const { t } = useLanguage();

  const [events, setEvents] = useState([]);
  const [loading, setLoading] = useState(true);
  const [currentDate, setCurrentDate] = useState(new Date());
  const [view, setView] = useState('month'); // month | week
  const [rooms, setRooms] = useState([]);

  // Modal state
  const [showCreate, setShowCreate] = useState(false);
  const [showDetail, setShowDetail] = useState(null);
  const [editingEvent, setEditingEvent] = useState(null);
  const [showShare, setShowShare] = useState(null);
  const [showFedShare, setShowFedShare] = useState(null);

  // Create/Edit form
  const [form, setForm] = useState({
    title: '', description: '', start_time: '', end_time: '',
    room_uid: '', color: '#6366f1', reminder_minutes: null,
  });
  const [saving, setSaving] = useState(false);

  // Share state
  const [shareSearch, setShareSearch] = useState('');
  const [shareResults, setShareResults] = useState([]);
  const [sharedUsers, setSharedUsers] = useState([]);
  const [pendingInvitations, setPendingInvitations] = useState([]);
  const [fedAddress, setFedAddress] = useState('');
  const [fedEmails, setFedEmails] = useState('');
  const [fedSending, setFedSending] = useState(false);

  // Invitations sent right after creating an event
  const [inviteFedAddress, setInviteFedAddress] = useState('');
  const [inviteEmails, setInviteEmails] = useState('');

  // Load events on month change
  useEffect(() => {
    fetchEvents();
  }, [currentDate]);

  useEffect(() => {
    fetchRooms();
  }, []);

  const fetchEvents = async () => {
    try {
      const year = currentDate.getFullYear();
      const month = currentDate.getMonth();
      const from = new Date(year, month - 1, 1).toISOString();
      const to = new Date(year, month + 2, 0).toISOString();
      const res = await api.get(`/calendar/events?from=${from}&to=${to}`);
      setEvents(res.data.events || []);
    } catch {
      toast.error(t('calendar.loadFailed'));
    } finally {
      setLoading(false);
    }
  };

  const fetchRooms = async () => {
    try {
      const res = await api.get('/rooms');
      setRooms(res.data.rooms || []);
    } catch { /* ignore */ }
  };

  // Calendar grid computation
  const calendarDays = useMemo(() => {
    const year = currentDate.getFullYear();
    const month = currentDate.getMonth();
    const firstDay = new Date(year, month, 1);
    const lastDay = new Date(year, month + 1, 0);

    // Start from Monday (ISO week)
    let startOffset = firstDay.getDay() - 1;
    if (startOffset < 0) startOffset = 6;
    const calStart = new Date(year, month, 1 - startOffset);

    const days = [];
    const current = new Date(calStart);
    for (let i = 0; i < 42; i++) {
      days.push(new Date(current));
      current.setDate(current.getDate() + 1);
    }
    return days;
  }, [currentDate]);

  const weekDays = useMemo(() => {
    const year = currentDate.getFullYear();
    const month = currentDate.getMonth();
    const date = currentDate.getDate();
    const dayOfWeek = currentDate.getDay();
    let mondayOffset = dayOfWeek - 1;
    if (mondayOffset < 0) mondayOffset = 6;
    const monday = new Date(year, month, date - mondayOffset);
    const days = [];
    for (let i = 0; i < 7; i++) {
      days.push(new Date(monday.getFullYear(), monday.getMonth(), monday.getDate() + i));
    }
    return days;
  }, [currentDate]);

  const eventsForDay = (day) => {
    const dayStr = toLocalDateStr(day);
    return events.filter(ev => {
      const start = toLocalDateStr(new Date(ev.start_time));
      const end = toLocalDateStr(new Date(ev.end_time));
      return dayStr >= start && dayStr <= end;
    });
  };

  const isToday = (day) => {
    const today = new Date();
    return day.toDateString() === today.toDateString();
  };

  const isCurrentMonth = (day) => {
    return day.getMonth() === currentDate.getMonth();
  };

  const navigatePrev = () => {
    const d = new Date(currentDate);
    if (view === 'month') d.setMonth(d.getMonth() - 1);
    else d.setDate(d.getDate() - 7);
    setCurrentDate(d);
  };

  const navigateNext = () => {
    const d = new Date(currentDate);
    if (view === 'month') d.setMonth(d.getMonth() + 1);
    else d.setDate(d.getDate() + 7);
    setCurrentDate(d);
  };

  const goToToday = () => setCurrentDate(new Date());

  const monthLabel = currentDate.toLocaleString('default', { month: 'long', year: 'numeric' });

  const openCreateForDay = (day) => {
    const start = new Date(day);
    start.setHours(9, 0, 0, 0);
    const end = new Date(day);
    end.setHours(10, 0, 0, 0);

    setForm({
      title: '', description: '',
      start_time: toLocalDateTimeStr(start),
      end_time: toLocalDateTimeStr(end),
      room_uid: '', color: '#6366f1', reminder_minutes: null,
    });
    setInviteFedAddress('');
    setInviteEmails('');
    setEditingEvent(null);
    setShowCreate(true);
  };

  const openEdit = (ev) => {
    setForm({
      title: ev.title,
      description: ev.description || '',
      start_time: toLocalDateTimeStr(new Date(ev.start_time)),
      end_time: toLocalDateTimeStr(new Date(ev.end_time)),
      room_uid: ev.room_uid || '',
      color: ev.color || '#6366f1',
      reminder_minutes: ev.reminder_minutes ?? null,
    });
    setEditingEvent(ev);
    setShowDetail(null);
    setShowCreate(true);
  };

  const isValidFedAddress = (address) => {
    const normalized = address.startsWith('@') ? address.slice(1) : address;
    return normalized.includes('@') && !normalized.endsWith('@');
  };

  // Send invitations for an event; shows a toast per outcome (non-fatal on failure)
  const sendEventInvites = async (eventId, address, emailsStr) => {
    const addr = address.trim();
    if (addr) {
      try {
        await api.post(`/calendar/events/${eventId}/federation`, { to: addr });
        toast.success(t('calendar.fedSent'));
      } catch (err) {
        toast.error(err.response?.data?.error || t('calendar.fedFailed'));
      }
    }
    const emailList = emailsStr.split(',').map(s => s.trim()).filter(Boolean);
    if (emailList.length > 0) {
      try {
        await api.post(`/calendar/events/${eventId}/email`, { emails: emailList });
        toast.success(t('federation.emailSent'));
      } catch (err) {
        toast.error(err.response?.data?.error || t('federation.emailSendFailed'));
      }
    }
  };

  const handleSave = async (e) => {
    e.preventDefault();

    if (!editingEvent && inviteFedAddress.trim() && !isValidFedAddress(inviteFedAddress.trim())) {
      toast.error(t('federation.addressHint'));
      return;
    }

    setSaving(true);
    try {
      const data = {
        ...form,
        start_time: new Date(form.start_time).toISOString(),
        end_time: new Date(form.end_time).toISOString(),
      };

      if (editingEvent) {
        await api.put(`/calendar/events/${editingEvent.id}`, data);
        toast.success(t('calendar.eventUpdated'));
      } else {
        const res = await api.post('/calendar/events', data);
        toast.success(t('calendar.eventCreated'));
        const created = res.data.event;
        if (created && (inviteFedAddress.trim() || inviteEmails.trim())) {
          await sendEventInvites(created.id, inviteFedAddress, inviteEmails);
        }
      }
      setShowCreate(false);
      setEditingEvent(null);
      setInviteFedAddress('');
      setInviteEmails('');
      fetchEvents();
    } catch (err) {
      toast.error(err.response?.data?.error || t('calendar.saveFailed'));
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (ev) => {
    if (!confirm(t('calendar.deleteConfirm'))) return;
    try {
      await api.delete(`/calendar/events/${ev.id}`);
      toast.success(t('calendar.eventDeleted'));
      setShowDetail(null);
      fetchEvents();
    } catch {
      toast.error(t('calendar.deleteFailed'));
    }
  };

  const handleDownloadICS = async (ev) => {
    try {
      const res = await api.get(`/calendar/events/${ev.id}/ics`, { responseType: 'blob' });
      const url = window.URL.createObjectURL(res.data);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${ev.title}.ics`;
      a.click();
      window.URL.revokeObjectURL(url);
      toast.success(t('calendar.icsDownloaded'));
    } catch {
      toast.error(t('calendar.icsFailed'));
    }
  };

  const buildOutlookUrl = (ev) => {
    const start = new Date(ev.start_time);
    const end = new Date(ev.end_time);
    const fmt = (d) => d.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');
    const baseUrl = window.location.origin;
    const location = ev.room_uid ? `${baseUrl}/join/${ev.room_uid}` : '';
    const body = [ev.description || '', location ? `\n\nMeeting: ${location}` : ''].join('');
    const params = new URLSearchParams({
      rru: 'addevent',
      subject: ev.title,
      startdt: start.toISOString(),
      enddt: end.toISOString(),
      body: body.trim(),
      location,
      allday: 'false',
      path: '/calendar/action/compose',
    });
    return `https://outlook.live.com/calendar/0/action/compose?${params.toString()}`;
  };

  const buildGoogleCalUrl = (ev) => {
    const fmt = (d) => new Date(d).toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');
    const baseUrl = window.location.origin;
    const location = ev.room_uid ? `${baseUrl}/join/${ev.room_uid}` : '';
    const details = [ev.description || '', location ? `\nMeeting: ${location}` : ''].join('');
    const params = new URLSearchParams({
      action: 'TEMPLATE',
      text: ev.title,
      dates: `${fmt(ev.start_time)}/${fmt(ev.end_time)}`,
      details: details.trim(),
      location,
    });
    return `https://calendar.google.com/calendar/render?${params.toString()}`;
  };

  // Share functions
  const openShareModal = async (ev) => {
    setShowShare(ev);
    setShareSearch('');
    setShareResults([]);
    setPendingInvitations([]);
    try {
      const res = await api.get(`/calendar/events/${ev.id}`);
      setSharedUsers(res.data.sharedUsers || []);
      setPendingInvitations(res.data.pendingInvitations || []);
    } catch { /* ignore */ }
  };

  const searchUsers = async (query) => {
    setShareSearch(query);
    if (query.length < 2) { setShareResults([]); return; }
    try {
      const res = await api.get(`/rooms/users/search?q=${encodeURIComponent(query)}`);
      const sharedIds = new Set(sharedUsers.map(u => u.id));
      const pendingIds = new Set(pendingInvitations.map(u => u.user_id));
      setShareResults(res.data.users.filter(u => !sharedIds.has(u.id) && !pendingIds.has(u.id)));
    } catch { setShareResults([]); }
  };

  const handleShare = async (userId) => {
    if (!showShare) return;
    try {
      const res = await api.post(`/calendar/events/${showShare.id}/share`, { user_id: userId });
      setSharedUsers(res.data.sharedUsers);
      setPendingInvitations(res.data.pendingInvitations || []);
      setShareSearch('');
      setShareResults([]);
      toast.success(t('calendar.invitationSent'));
    } catch (err) {
      toast.error(err.response?.data?.error || t('calendar.shareFailed'));
    }
  };

  const handleUnshare = async (userId) => {
    if (!showShare) return;
    try {
      const res = await api.delete(`/calendar/events/${showShare.id}/share/${userId}`);
      setSharedUsers(res.data.sharedUsers);
      setPendingInvitations(res.data.pendingInvitations || []);
      toast.success(t('calendar.shareRemoved'));
    } catch { toast.error(t('calendar.shareFailed')); }
  };

  const handleCancelInvitation = async (userId) => {
    if (!showShare) return;
    try {
      const res = await api.delete(`/calendar/events/${showShare.id}/share/${userId}`);
      setSharedUsers(res.data.sharedUsers);
      setPendingInvitations(res.data.pendingInvitations || []);
      toast.success(t('calendar.invitationCancelled'));
    } catch { toast.error(t('calendar.shareFailed')); }
  };

  const handleFedSend = async (e) => {
    e.preventDefault();
    if (!showFedShare) return;
    const hasAddress = fedAddress.trim().length > 0;
    const hasEmails = fedEmails.trim().length > 0;

    if (!hasAddress && !hasEmails) {
      toast.error(t('federation.addressHint'));
      return;
    }

    setFedSending(true);
    try {
      if (hasAddress) {
        // Federation address mode
        if (!isValidFedAddress(fedAddress.trim())) {
          toast.error(t('federation.addressHint'));
          setFedSending(false);
          return;
        }
        await api.post(`/calendar/events/${showFedShare.id}/federation`, { to: fedAddress });
        toast.success(t('calendar.fedSent'));
      } else {
        // Email mode
        const emailList = fedEmails.split(',').map(s => s.trim()).filter(Boolean);
        if (emailList.length === 0) {
          toast.error(t('federation.emailHint'));
          setFedSending(false);
          return;
        }
        await api.post(`/calendar/events/${showFedShare.id}/email`, { emails: emailList });
        toast.success(t('federation.emailSent'));
      }
      setShowFedShare(null);
      setFedAddress('');
      setFedEmails('');
    } catch (err) {
      toast.error(err.response?.data?.error || t(hasAddress ? 'calendar.fedFailed' : 'federation.emailSendFailed'));
    } finally {
      setFedSending(false);
    }
  };

  const dayNames = [
    t('calendar.mon'), t('calendar.tue'), t('calendar.wed'),
    t('calendar.thu'), t('calendar.fri'), t('calendar.sat'), t('calendar.sun'),
  ];

  if (loading) {
    return (
      <div className="flex items-center justify-center py-20" role="status" aria-label={t('common.loading')}>
        <Loader2 size={32} className="animate-spin text-th-accent" />
      </div>
    );
  }

  return (
    <div>
      {/* Header */}
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-th-text">{t('calendar.title')}</h1>
          <p className="text-sm text-th-text-s mt-1">{t('calendar.subtitle')}</p>
        </div>
        <button onClick={() => {
          const now = new Date();
          now.setHours(now.getHours() + 1, 0, 0, 0);
          const end = new Date(now);
          end.setHours(end.getHours() + 1);
          setForm({
            title: '', description: '',
            start_time: toLocalDateTimeStr(now),
            end_time: toLocalDateTimeStr(end),
            room_uid: '', color: '#6366f1',
          });
          setInviteFedAddress('');
          setInviteEmails('');
          setEditingEvent(null);
          setShowCreate(true);
        }} className="btn-primary">
          <Plus size={18} />
          <span className="hidden sm:inline">{t('calendar.newEvent')}</span>
        </button>
      </div>

      {/* Toolbar */}
      <div className="card p-3 mb-4 flex items-center justify-between flex-wrap gap-2">
        <div className="flex items-center gap-2">
          <button onClick={navigatePrev} aria-label={t('common.previous')} className="btn-ghost p-2">
            <ChevronLeft size={18} />
          </button>
          <button onClick={goToToday} className="btn-ghost text-sm px-3 py-1.5">
            {t('calendar.today')}
          </button>
          <button onClick={navigateNext} aria-label={t('common.next')} className="btn-ghost p-2">
            <ChevronRight size={18} />
          </button>
          <h2 className="text-lg font-semibold text-th-text ml-2">{monthLabel}</h2>
        </div>
        <div className="flex items-center bg-th-bg-s rounded-lg border border-th-border p-0.5">
          <button
            onClick={() => setView('month')}
            className={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${
              view === 'month' ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s hover:text-th-text'
            }`}
          >
            {t('calendar.month')}
          </button>
          <button
            onClick={() => setView('week')}
            className={`px-3 py-1.5 rounded-md text-sm font-medium transition-colors ${
              view === 'week' ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s hover:text-th-text'
            }`}
          >
            {t('calendar.week')}
          </button>
        </div>
      </div>

      {/* Calendar Grid */}
      <div className="card overflow-hidden">
        {/* Day headers */}
        <div className="grid grid-cols-7 border-b border-th-border">
          {dayNames.map((name, i) => (
            <div key={i} className="py-2.5 text-center text-xs font-semibold text-th-text-s uppercase tracking-wider border-r border-th-border last:border-r-0">
              {name}
            </div>
          ))}
        </div>

        {/* Days */}
        {view === 'month' ? (
          <div className="grid grid-cols-7">
            {calendarDays.map((day, i) => {
              const dayEvents = eventsForDay(day);
              const today = isToday(day);
              const inMonth = isCurrentMonth(day);
              return (
                <div
                  key={i}
                  onClick={() => openCreateForDay(day)}
                  className={`min-h-[100px] p-1.5 border-r border-b border-th-border last:border-r-0 cursor-pointer hover:bg-th-hover/50 transition-colors
                    ${!inMonth ? 'opacity-40' : ''}`}
                >
                  <div className={`text-xs font-medium mb-1 w-6 h-6 flex items-center justify-center rounded-full
                    ${today ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s'}`}>
                    {day.getDate()}
                  </div>
                  <div className="space-y-0.5">
                    {dayEvents.slice(0, 3).map(ev => (
                      <div
                        key={ev.id}
                        onClick={(e) => { e.stopPropagation(); setShowDetail(ev); }}
                        className="text-[10px] leading-tight px-1.5 py-0.5 rounded-sm truncate text-white font-medium cursor-pointer hover:opacity-80 transition-opacity"
                        style={{ backgroundColor: ev.color || '#6366f1' }}
                        title={ev.title}
                      >
                        {formatTime(ev.start_time)} {ev.title}
                      </div>
                    ))}
                    {dayEvents.length > 3 && (
                      <div className="text-[10px] text-th-text-s font-medium px-1.5">
                        +{dayEvents.length - 3} {t('calendar.more')}
                      </div>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        ) : (
          /* Week view */
          <div className="grid grid-cols-7">
            {weekDays.map((day, i) => {
              const dayEvents = eventsForDay(day);
              const today = isToday(day);
              return (
                <div
                  key={i}
                  onClick={() => openCreateForDay(day)}
                  className="min-h-[300px] p-2 border-r border-b border-th-border last:border-r-0 cursor-pointer hover:bg-th-hover/50 transition-colors"
                >
                  <div className={`text-sm font-medium mb-2 w-7 h-7 flex items-center justify-center rounded-full
                    ${today ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s'}`}>
                    {day.getDate()}
                  </div>
                  <div className="space-y-1">
                    {dayEvents.map(ev => (
                      <div
                        key={ev.id}
                        onClick={(e) => { e.stopPropagation(); setShowDetail(ev); }}
                        className="text-xs px-2 py-1.5 rounded-sm text-white font-medium cursor-pointer hover:opacity-80 transition-opacity"
                        style={{ backgroundColor: ev.color || '#6366f1' }}
                      >
                        <div className="flex items-center gap-1 truncate">
                          {ev.reminder_minutes && <Bell size={9} className="shrink-0 opacity-70" />}
                          <span className="truncate">{ev.title}</span>
                        </div>
                        <div className="opacity-80 text-[10px]">{formatTime(ev.start_time)} - {formatTime(ev.end_time)}</div>
                      </div>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Create/Edit Modal */}
      {showCreate && (
        <Modal title={editingEvent ? t('calendar.editEvent') : t('calendar.createEvent')} onClose={() => { setShowCreate(false); setEditingEvent(null); }}>
          <form onSubmit={handleSave} className="space-y-4">
            <div>
              <label htmlFor="calendar-event-title" className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.eventTitle')} *</label>
              <input
                id="calendar-event-title"
                type="text"
                value={form.title}
                onChange={e => setForm({ ...form, title: e.target.value })}
                className="input-field"
                placeholder={t('calendar.eventTitlePlaceholder')}
                required
              />
            </div>

            <div>
              <label htmlFor="calendar-event-description" className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.description')}</label>
              <textarea
                id="calendar-event-description"
                value={form.description}
                onChange={e => setForm({ ...form, description: e.target.value })}
                className="input-field resize-none"
                rows={2}
                placeholder={t('calendar.descriptionPlaceholder')}
              />
            </div>

            <div className="grid grid-cols-2 gap-4">
              <DateTimePicker
                label={t('calendar.startTime')}
                value={form.start_time}
                onChange={v => setForm({ ...form, start_time: v })}
                required
                icon="calendar"
              />
              <DateTimePicker
                label={t('calendar.endTime')}
                value={form.end_time}
                onChange={v => setForm({ ...form, end_time: v })}
                required
                icon="clock"
                minDate={form.start_time ? new Date(form.start_time) : null}
              />
            </div>
            <div className="flex items-center gap-1.5 -mt-2 text-xs text-th-text-s">
              <Globe size={12} className="shrink-0" />
              <span>{getLocalTimezone()}</span>
            </div>

            <div>
              <label htmlFor="calendar-event-room" className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.linkedRoom')}</label>
              <select
                id="calendar-event-room"
                value={form.room_uid}
                onChange={e => setForm({ ...form, room_uid: e.target.value })}
                className="input-field"
              >
                <option value="">{t('calendar.noRoom')}</option>
                {rooms.map(r => (
                  <option key={r.uid} value={r.uid}>{r.name}</option>
                ))}
              </select>
              <p className="text-xs text-th-text-s mt-1">{t('calendar.linkedRoomHint')}</p>
            </div>

            <div>
              <label htmlFor="calendar-event-reminder" className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.reminderLabel')}</label>
              <div className="relative">
                <Bell size={15} className="absolute left-3 top-1/2 -translate-y-1/2 text-th-text-s pointer-events-none" aria-hidden="true" />
                <select
                  id="calendar-event-reminder"
                  value={form.reminder_minutes ?? ''}
                  onChange={e => setForm({ ...form, reminder_minutes: e.target.value === '' ? null : Number(e.target.value) })}
                  className="input-field pl-9"
                >
                  <option value="">{t('calendar.reminderNone')}</option>
                  <option value="5">{t('calendar.reminder5')}</option>
                  <option value="15">{t('calendar.reminder15')}</option>
                  <option value="30">{t('calendar.reminder30')}</option>
                  <option value="60">{t('calendar.reminder60')}</option>
                  <option value="120">{t('calendar.reminder120')}</option>
                  <option value="1440">{t('calendar.reminder1440')}</option>
                </select>
              </div>
            </div>

            <div>
              <p id="calendar-event-color-label" className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.color')}</p>
              <div role="radiogroup" aria-labelledby="calendar-event-color-label" className="flex gap-2">
                {COLORS.map(c => (
                  <button
                    key={c}
                    type="button"
                    onClick={() => setForm({ ...form, color: c })}
                    role="radio"
                    aria-checked={form.color === c}
                    aria-label={c}
                    className={`w-7 h-7 rounded-full border-2 transition-all ${form.color === c ? 'border-th-text scale-110' : 'border-transparent'}`}
                    style={{ backgroundColor: c }}
                  />
                ))}
              </div>
            </div>

            {!editingEvent && (
              <div className="pt-4 border-t border-th-border space-y-4">
                <div>
                  <p className="text-sm font-medium text-th-text">{t('calendar.inviteSection')}</p>
                  <p className="text-xs text-th-text-s mt-0.5">{t('calendar.inviteSectionHint')}</p>
                </div>

                <div>
                  <label htmlFor="calendar-invite-emails" className="block text-sm font-medium text-th-text mb-1.5">{t('federation.emailLabel')}</label>
                  <input
                    id="calendar-invite-emails"
                    type="text"
                    value={inviteEmails}
                    onChange={e => setInviteEmails(e.target.value)}
                    className="input-field"
                    placeholder={t('federation.emailPlaceholder')}
                  />
                  <p className="text-xs text-th-text-s mt-1">{t('federation.emailHint')}</p>
                </div>

                <div>
                  <label htmlFor="calendar-invite-fed-address" className="block text-sm font-medium text-th-text mb-1.5">{t('federation.addressLabel')}</label>
                  <input
                    id="calendar-invite-fed-address"
                    type="text"
                    value={inviteFedAddress}
                    onChange={e => setInviteFedAddress(e.target.value)}
                    className="input-field"
                    placeholder={t('federation.addressPlaceholder')}
                  />
                  <p className="text-xs text-th-text-s mt-1">{t('federation.addressHint')}</p>
                </div>
              </div>
            )}

            <div className="flex items-center gap-3 pt-4 border-t border-th-border">
              <button type="button" onClick={() => { setShowCreate(false); setEditingEvent(null); }} className="btn-secondary flex-1">
                {t('common.cancel')}
              </button>
              <button type="submit" disabled={saving} className="btn-primary flex-1">
                {saving ? <Loader2 size={18} className="animate-spin" /> : t('common.save')}
              </button>
            </div>
          </form>
        </Modal>
      )}

      {/* Event Detail Modal */}
      {showDetail && (
        <Modal title={showDetail.title} onClose={() => setShowDetail(null)}>
          <div className="space-y-4">
            <div className="flex items-center gap-2 text-sm text-th-text-s">
              <Clock size={14} />
              <span>
                {new Date(showDetail.start_time).toLocaleString()} - {new Date(showDetail.end_time).toLocaleString()}
              </span>
            </div>
            <div className="flex items-center gap-1.5 text-xs text-th-text-s opacity-70 -mt-2">
              <Globe size={12} />
              <span>{getLocalTimezone()}</span>
            </div>

            {showDetail.description && (
              <p className="text-sm text-th-text">{showDetail.description}</p>
            )}

            {showDetail.room_uid && (
              <div className="flex items-center gap-2 text-sm">
                <Video size={14} className="text-th-accent" />
                <a
                  href={`/rooms/${showDetail.room_uid}`}
                  className="text-th-accent hover:underline"
                  onClick={(e) => { e.preventDefault(); window.location.href = `/rooms/${showDetail.room_uid}`; }}
                >
                  {t('calendar.openRoom')}
                </a>
              </div>
            )}

            {showDetail.federated_from && (
              <div className="flex items-center gap-2 text-xs text-th-text-s">
                <Globe size={12} />
                <span>{t('calendar.federatedFrom')}: {showDetail.federated_from}</span>
              </div>
            )}

            {showDetail.federated_join_url && (
              <a
                href={showDetail.federated_join_url}
                target="_blank"
                rel="noopener noreferrer"
                className="btn-primary text-sm w-full justify-center"
              >
                <Video size={14} />
                {t('calendar.joinFederatedMeeting')}
              </a>
            )}

            {showDetail.organizer_name && (
              <div className="text-xs text-th-text-s">
                {t('calendar.organizer')}: {showDetail.organizer_name}
              </div>
            )}

            {/* Actions */}
            <div className="flex flex-wrap items-center gap-2 pt-4 border-t border-th-border">
              <a
                href={buildOutlookUrl(showDetail)}
                target="_blank"
                rel="noopener noreferrer"
                className="btn-ghost text-xs py-1.5 px-3 inline-flex items-center gap-1.5 no-underline"
              >
                <ExternalLink size={14} />
                {t('calendar.addToOutlook')}
              </a>
              <a
                href={buildGoogleCalUrl(showDetail)}
                target="_blank"
                rel="noopener noreferrer"
                className="btn-ghost text-xs py-1.5 px-3 inline-flex items-center gap-1.5 no-underline"
              >
                <ExternalLink size={14} />
                {t('calendar.addToGoogleCalendar')}
              </a>
              <button onClick={() => handleDownloadICS(showDetail)} className="btn-ghost text-xs py-1.5 px-3">
                <Download size={14} />
                {t('calendar.downloadICS')}
              </button>

              {showDetail.is_owner && (
                <>
                  <button onClick={() => openEdit(showDetail)} className="btn-ghost text-xs py-1.5 px-3">
                    <Edit size={14} />
                    {t('common.edit')}
                  </button>
                  <button onClick={() => openShareModal(showDetail)} className="btn-ghost text-xs py-1.5 px-3">
                    <Share2 size={14} />
                    {t('calendar.share')}
                  </button>
                  <button onClick={() => { setShowFedShare(showDetail); setShowDetail(null); }} className="btn-ghost text-xs py-1.5 px-3">
                    <Globe size={14} />
                    {t('calendar.sendFederated')}
                  </button>
                  <button onClick={() => handleDelete(showDetail)} className="btn-ghost text-xs py-1.5 px-3 text-th-error hover:text-th-error">
                    <Trash2 size={14} />
                    {t('common.delete')}
                  </button>
                </>
              )}
            </div>
          </div>
        </Modal>
      )}

      {/* Share Modal */}
      {showShare && (
        <Modal title={t('calendar.shareEvent')} onClose={() => setShowShare(null)}>
          <div className="space-y-4">
            <div className="relative">
              <UserPlus size={18} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-th-text-s" />
              <input
                type="text"
                value={shareSearch}
                onChange={e => searchUsers(e.target.value)}
                className="input-field pl-11"
                placeholder={t('room.shareSearchPlaceholder')}
              />
              {shareResults.length > 0 && (
                <div className="absolute z-10 w-full mt-1 bg-th-card border border-th-border rounded-lg shadow-lg max-h-48 overflow-y-auto">
                  {shareResults.map(u => (
                    <button
                      key={u.id}
                      onClick={() => handleShare(u.id)}
                      className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-th-hover transition-colors text-left"
                    >
                      <div
                        className="w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-bold shrink-0"
                        style={{ backgroundColor: u.avatar_color || '#6366f1' }}
                      >
                        {(u.display_name || u.name).split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)}
                      </div>
                      <div className="min-w-0">
                        <div className="text-sm font-medium text-th-text truncate">{u.display_name || u.name}</div>
                        <div className="text-xs text-th-text-s truncate">{u.email}</div>
                      </div>
                    </button>
                  ))}
                </div>
              )}
            </div>

            {pendingInvitations.length > 0 && (
              <div className="space-y-2">
                <p className="text-xs font-semibold text-th-text-s uppercase tracking-wider">{t('calendar.pendingInvitations')}</p>
                {pendingInvitations.map(u => (
                  <div key={u.user_id} className="flex items-center justify-between gap-3 p-3 bg-th-bg-s rounded-lg border border-th-border border-dashed">
                    <div className="flex items-center gap-3 min-w-0">
                      <div
                        className="w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-bold shrink-0"
                        style={{ backgroundColor: u.avatar_color || '#6366f1' }}
                      >
                        {(u.display_name || u.name).split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)}
                      </div>
                      <div className="min-w-0">
                        <div className="text-sm font-medium text-th-text truncate">{u.display_name || u.name}</div>
                        <div className="text-xs text-th-warning">{t('calendar.invitationPending')}</div>
                      </div>
                    </div>
                    <button onClick={() => handleCancelInvitation(u.user_id)} className="p-1.5 rounded-lg hover:bg-th-hover text-th-text-s hover:text-th-error transition-colors">
                      <X size={16} />
                    </button>
                  </div>
                ))}
              </div>
            )}

            {sharedUsers.length > 0 && (
              <div className="space-y-2">
                {pendingInvitations.length > 0 && (
                  <p className="text-xs font-semibold text-th-text-s uppercase tracking-wider">{t('calendar.accepted')}</p>
                )}
                {sharedUsers.map(u => (
                  <div key={u.id} className="flex items-center justify-between gap-3 p-3 bg-th-bg-s rounded-lg border border-th-border">
                    <div className="flex items-center gap-3 min-w-0">
                      <div
                        className="w-8 h-8 rounded-full flex items-center justify-center text-white text-xs font-bold shrink-0"
                        style={{ backgroundColor: u.avatar_color || '#6366f1' }}
                      >
                        {(u.display_name || u.name).split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)}
                      </div>
                      <div className="min-w-0">
                        <div className="text-sm font-medium text-th-text truncate">{u.display_name || u.name}</div>
                        <div className="text-xs text-th-text-s truncate">{u.email}</div>
                      </div>
                    </div>
                    <button onClick={() => handleUnshare(u.id)} className="p-1.5 rounded-lg hover:bg-th-hover text-th-text-s hover:text-th-error transition-colors">
                      <X size={16} />
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        </Modal>
      )}

      {/* Federation/Email Share Modal */}
      {showFedShare && (
        <Modal title={t('calendar.sendFederatedTitle')} onClose={() => { setShowFedShare(null); setFedAddress(''); setFedEmails(''); }}>
          <p className="text-sm text-th-text-s mb-4">{t('calendar.sendFederatedDesc')}</p>
          <form onSubmit={handleFedSend} className="space-y-4">
            <div>
              <label htmlFor="calendar-fed-share-address" className="block text-sm font-medium text-th-text mb-1.5">{t('federation.addressLabel')}</label>
              <input
                id="calendar-fed-share-address"
                type="text"
                value={fedAddress}
                onChange={e => { setFedAddress(e.target.value); if (e.target.value) setFedEmails(''); }}
                className="input-field"
                placeholder={t('federation.addressPlaceholder')}
                disabled={fedEmails.trim().length > 0}
              />
              <p className="text-xs text-th-text-s mt-1">{t('federation.addressHint')}</p>
            </div>

            <div className="flex items-center gap-3 my-2">
              <div className="flex-1 border-t border-th-border" />
              <span className="text-xs text-th-text-s uppercase">{t('common.or')}</span>
              <div className="flex-1 border-t border-th-border" />
            </div>

            <div>
              <label htmlFor="calendar-fed-share-emails" className="block text-sm font-medium text-th-text mb-1.5">{t('federation.emailLabel')}</label>
              <input
                id="calendar-fed-share-emails"
                type="text"
                value={fedEmails}
                onChange={e => { setFedEmails(e.target.value); if (e.target.value) setFedAddress(''); }}
                className="input-field"
                placeholder={t('federation.emailPlaceholder')}
                disabled={fedAddress.trim().length > 0}
              />
              <p className="text-xs text-th-text-s mt-1">{t('federation.emailHint')}</p>
            </div>

            <div className="flex items-center gap-3 pt-2 border-t border-th-border">
              <button type="button" onClick={() => { setShowFedShare(null); setFedAddress(''); setFedEmails(''); }} className="btn-secondary flex-1">
                {t('common.cancel')}
              </button>
              <button type="submit" disabled={fedSending || (!fedAddress.trim() && !fedEmails.trim())} className="btn-primary flex-1">
                {fedSending ? <Loader2 size={16} className="animate-spin" /> : <Send size={16} />}
                {t('calendar.send')}
              </button>
            </div>
          </form>
        </Modal>
      )}
    </div>
  );
}

// Helpers
function toLocalDateStr(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  return `${y}-${m}-${d}`;
}

function toLocalDateTimeStr(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, '0');
  const d = String(date.getDate()).padStart(2, '0');
  const h = String(date.getHours()).padStart(2, '0');
  const min = String(date.getMinutes()).padStart(2, '0');
  return `${y}-${m}-${d}T${h}:${min}`;
}

function formatTime(dateStr) {
  const d = new Date(dateStr);
  return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}

function getLocalTimezone() {
  try {
    return Intl.DateTimeFormat().resolvedOptions().timeZone;
  } catch {
    const offset = -new Date().getTimezoneOffset();
    const sign = offset >= 0 ? '+' : '-';
    const h = String(Math.floor(Math.abs(offset) / 60)).padStart(2, '0');
    const m = String(Math.abs(offset) % 60).padStart(2, '0');
    return `UTC${sign}${h}:${m}`;
  }
}
