<template>
  <v-card elevation="2" class="event-calendar">
    <v-card-title v-if="!compact" class="d-flex justify-space-between align-center">
      <div class="d-flex align-center">
        <v-icon class="me-2">mdi-calendar</v-icon>
        <span>Events Calendar</span>
      </div>
      <div v-if="showCreateButton && (isBoard || isAdmin)" class="d-flex gap-2">
        <v-btn
          @click="$emit('create-event')"
          color="primary"
          size="small"
          prepend-icon="mdi-plus"
        >
          Create Event
        </v-btn>
      </div>
    </v-card-title>

    <v-card-text>
      <!-- Mobile view selector -->
      <v-row v-if="$vuetify.display.mobile && !compact" class="mb-4">
        <v-col cols="12">
          <v-btn-toggle
            v-model="mobileView"
            color="primary"
            variant="outlined"
            density="compact"
            mandatory
          >
            <v-btn value="month">
              <v-icon start>mdi-calendar-month</v-icon>
              Month
            </v-btn>
            <v-btn value="list">
              <v-icon start>mdi-format-list-bulleted</v-icon>
              Agenda
            </v-btn>
          </v-btn-toggle>
        </v-col>
      </v-row>

      <!-- Loading state -->
      <v-skeleton-loader
        v-if="loading"
        type="image"
        :height="calendarHeight"
        class="rounded"
      />

      <!-- FullCalendar component -->
      <FullCalendar
        v-else
        ref="fullCalendar"
        :options="calendarOptions"
        class="fc-theme-monacousa"
      />

      <!-- No events message -->
      <v-alert
        v-if="!loading && events.length === 0"
        type="info"
        variant="tonal"
        class="mt-4"
      >
        <v-alert-title>No Events</v-alert-title>
        No events found for the current time period.
      </v-alert>
    </v-card-text>
  </v-card>
</template>

<script setup lang="ts">
import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import listPlugin from '@fullcalendar/list';
import type { Event, FullCalendarEvent } from '~/utils/types';
import { useAuth } from '~/composables/useAuth';

interface Props {
  events?: Event[];
  loading?: boolean;
  compact?: boolean;
  height?: number | string;
  showCreateButton?: boolean;
  initialView?: string;
}

const props = withDefaults(defineProps<Props>(), {
  events: () => [],
  loading: false,
  compact: false,
  height: 600,
  showCreateButton: true,
  initialView: 'dayGridMonth'
});

const emit = defineEmits<{
  'event-click': [event: any];
  'date-click': [date: any];
  'view-change': [view: any];
  'date-range-change': [start: string, end: string];
  'create-event': [];
}>();

const { isBoard, isAdmin } = useAuth();

// Reactive state
const fullCalendar = ref<InstanceType<typeof FullCalendar>>();
const mobileView = ref('month');

// Computed properties
const calendarHeight = computed(() => {
  if (props.compact) return props.height || 300;
  if (typeof props.height === 'number') return props.height;
  return props.height || 600;
});

const currentView = computed(() => {
  if (props.compact) return 'dayGridMonth';
  
  // Mobile responsive view switching
  if (process.client && window.innerWidth < 960) {
    return mobileView.value === 'list' ? 'listWeek' : 'dayGridMonth';
  }
  
  return props.initialView;
});

const transformedEvents = computed((): FullCalendarEvent[] => {
  return props.events.map((event: Event) => transformEventForCalendar(event));
});

// FullCalendar options
const calendarOptions = computed(() => ({
  plugins: [dayGridPlugin, interactionPlugin, listPlugin],
  initialView: currentView.value,
  height: calendarHeight.value,
  headerToolbar: props.compact ? false : {
    left: 'prev,next today',
    center: 'title',
    right: process.client && window.innerWidth < 960 ? 
      'dayGridMonth,listWeek' : 
      'dayGridMonth,dayGridWeek,listWeek'
  },
  events: transformedEvents.value,
  eventClick: handleEventClick,
  dateClick: handleDateClick,
  datesSet: handleDatesSet,
  eventDidMount: handleEventMount,
  dayMaxEvents: props.compact ? 2 : 5,
  eventDisplay: 'block',
  displayEventTime: true,
  eventTimeFormat: {
    hour: '2-digit',
    minute: '2-digit',
    hour12: false
  },
  locale: 'en',
  firstDay: 1, // Monday
  weekends: true,
  navLinks: true,
  selectable: isBoard.value || isAdmin.value,
  selectMirror: true,
  select: handleDateSelect,
  // Mobile optimizations
  aspectRatio: process.client && window.innerWidth < 960 ? 1.0 : 1.35,
  // Responsive behavior
  windowResizeDelay: 100
}));

// Event handlers
function handleEventClick(clickInfo: any) {
  emit('event-click', {
    event: clickInfo.event,
    eventData: clickInfo.event.extendedProps
  });
}

function handleDateClick(dateInfo: any) {
  if (isBoard.value || isAdmin.value) {
    emit('date-click', {
      date: dateInfo.dateStr,
      allDay: dateInfo.allDay
    });
  }
}

function handleDateSelect(selectInfo: any) {
  if (isBoard.value || isAdmin.value) {
    emit('date-click', {
      date: selectInfo.startStr,
      endDate: selectInfo.endStr,
      allDay: selectInfo.allDay
    });
  }
}

function handleDatesSet(dateInfo: any) {
  emit('view-change', {
    view: dateInfo.view.type,
    start: dateInfo.start,
    end: dateInfo.end
  });
  
  emit('date-range-change', 
    dateInfo.start.toISOString(), 
    dateInfo.end.toISOString()
  );
}

function handleEventMount(mountInfo: any) {
  // Add custom styling or tooltips
  const event = mountInfo.event;
  const el = mountInfo.el;
  
  // Add tooltip with event details
  el.setAttribute('title', `${event.title}\n${event.extendedProps.location || 'No location'}`);
  
  // Add custom classes based on event properties
  if (event.extendedProps.is_paid) {
    el.classList.add('fc-paid-event');
  }
  
  if (event.extendedProps.user_rsvp?.rsvp_status === 'confirmed') {
    el.classList.add('fc-user-rsvp');
  }
}

// Transform event data for FullCalendar
function transformEventForCalendar(event: Event): FullCalendarEvent {
  const eventTypeColors = {
    'meeting': { bg: '#2196f3', border: '#1976d2' },
    'social': { bg: '#4caf50', border: '#388e3c' },
    'fundraiser': { bg: '#ff9800', border: '#f57c00' },
    'workshop': { bg: '#9c27b0', border: '#7b1fa2' },
    'board-only': { bg: '#a31515', border: '#8b1212' }
  };
  
  const colors = eventTypeColors[event.event_type] || 
    { bg: '#757575', border: '#424242' };

  return {
    id: event.id,
    title: event.title,
    start: event.start_datetime,
    end: event.end_datetime,
    backgroundColor: colors.bg,
    borderColor: colors.border,
    textColor: '#ffffff',
    extendedProps: {
      description: event.description,
      location: event.location,
      event_type: event.event_type,
      is_paid: event.is_paid === 'true',
      cost_members: event.cost_members,
      cost_non_members: event.cost_non_members,
      max_attendees: event.max_attendees ? parseInt(event.max_attendees) : null,
      current_attendees: event.current_attendees || 0,
      user_rsvp: event.user_rsvp,
      visibility: event.visibility,
      creator: event.creator,
      status: event.status
    }
  };
}

// Public methods
function getCalendarApi() {
  return fullCalendar.value?.getApi();
}

function refetchEvents() {
  const api = getCalendarApi();
  if (api) {
    api.refetchEvents();
  }
}

function changeView(viewType: string) {
  const api = getCalendarApi();
  if (api) {
    api.changeView(viewType);
  }
}

function gotoDate(date: string | Date) {
  const api = getCalendarApi();
  if (api) {
    api.gotoDate(date);
  }
}

// Watch for mobile view changes
watch(mobileView, (newView) => {
  const viewType = newView === 'list' ? 'listWeek' : 'dayGridMonth';
  changeView(viewType);
});

// Expose methods to parent components
defineExpose({
  getCalendarApi,
  refetchEvents,
  changeView,
  gotoDate
});
</script>

<style scoped>
.event-calendar :deep(.fc) {
  font-family: 'Roboto', sans-serif;
}

.event-calendar :deep(.fc-theme-standard .fc-scrollgrid) {
  border-color: rgba(0, 0, 0, 0.12);
}

.event-calendar :deep(.fc-theme-standard td),
.event-calendar :deep(.fc-theme-standard th) {
  border-color: rgba(0, 0, 0, 0.12);
}

.event-calendar :deep(.fc-button-primary) {
  background-color: #a31515;
  border-color: #a31515;
  font-weight: 500;
  text-transform: none;
}

.event-calendar :deep(.fc-button-primary:hover) {
  background-color: #8b1212;
  border-color: #8b1212;
}

.event-calendar :deep(.fc-button-primary:disabled) {
  background-color: rgba(163, 21, 21, 0.5);
  border-color: rgba(163, 21, 21, 0.5);
}

.event-calendar :deep(.fc-today-button) {
  font-weight: 500;
  text-transform: none;
}

.event-calendar :deep(.fc-toolbar-title) {
  font-size: 1.25rem;
  font-weight: 600;
  color: #a31515;
}

.event-calendar :deep(.fc-day-today) {
  background-color: rgba(163, 21, 21, 0.05) !important;
}

.event-calendar :deep(.fc-event) {
  border-radius: 4px;
  font-weight: 500;
  font-size: 0.875rem;
  cursor: pointer;
}

.event-calendar :deep(.fc-event:hover) {
  opacity: 0.85;
}

.event-calendar :deep(.fc-paid-event) {
  border-left: 4px solid #ff9800 !important;
}

.event-calendar :deep(.fc-user-rsvp) {
  box-shadow: 0 0 0 2px #4caf50;
}

.event-calendar :deep(.fc-list-event-title) {
  font-weight: 500;
}

.event-calendar :deep(.fc-list-event-time) {
  font-weight: 600;
  color: #a31515;
}

/* Mobile optimizations */
@media (max-width: 600px) {
  .event-calendar :deep(.fc-toolbar) {
    flex-direction: column;
    gap: 8px;
  }
  
  .event-calendar :deep(.fc-toolbar-chunk) {
    display: flex;
    justify-content: center;
  }
  
  .event-calendar :deep(.fc-button-group) {
    display: flex;
  }
  
  .event-calendar :deep(.fc-button) {
    padding: 4px 8px;
    font-size: 0.75rem;
  }
  
  .event-calendar :deep(.fc-toolbar-title) {
    font-size: 1.1rem;
    text-align: center;
  }
}
</style>
