<!-- src/pages/service/ServiceCalendar.vue -->
<template>
  <div class="calendar-page">
    <div class="w-full px-4 md:px-10">
      <!-- Breadcrumbs -->
      <div class="text-sm breadcrumbs mb-4">
        <ul>
          <li><router-link :to="{ name: 'home' }">Home</router-link></li>
          <li><router-link :to="{ name: 'ServiceHome' }">Service</router-link></li>
          <li>Master Calendar</li>
        </ul>
      </div>

      <!-- Page Header -->
      <div class="flex items-center justify-between mb-6">
        <div>
          <h1 class="text-3xl font-bold mb-1">Service Calendar</h1>
          <p class="text-base-content/60">Manage and schedule service calls</p>
        </div>
        <div class="flex gap-3">
          <button @click="goToToday" class="btn btn-ghost btn-sm gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
              <path stroke-linecap="round" stroke-linejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5" />
            </svg>
            Today
          </button>
        </div>
      </div>

      <!-- Calendar Container -->
      <div class="calendar-container bg-gradient-to-br from-neutral to-neutral/80 rounded-xl shadow-strong overflow-hidden">
        <!-- Custom Calendar Header -->
        <div class="calendar-header bg-base-200 px-6 py-4 border-b border-base-300">
          <div class="flex items-center justify-between">
            <!-- Navigation -->
            <div class="flex items-center gap-2">
              <button @click="previousMonth" class="btn btn-ghost btn-sm btn-circle">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5" />
                </svg>
              </button>
              <h2 class="text-2xl font-bold min-w-[200px] text-center">{{ currentMonthYear }}</h2>
              <button @click="nextMonth" class="btn btn-ghost btn-sm btn-circle">
                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-5 h-5">
                  <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" />
                </svg>
              </button>
            </div>

            <!-- View Switcher -->
            <div class="btn-group">
              <button 
                @click="changeView('dayGridMonth')" 
                class="btn btn-sm"
                :class="{ 'btn-active': currentView === 'dayGridMonth' }"
              >
                Month
              </button>
              <button 
                @click="changeView('dayGridWeek')" 
                class="btn btn-sm"
                :class="{ 'btn-active': currentView === 'dayGridWeek' }"
              >
                Week
              </button>
              <button 
                @click="changeView('dayGridDay')" 
                class="btn btn-sm"
                :class="{ 'btn-active': currentView === 'dayGridDay' }"
              >
                Day
              </button>
            </div>

            <!-- Legend -->
            <div class="flex items-center gap-3 flex-wrap">
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-info"></div>
                <span class="text-xs font-medium">Tune-up</span>
              </div>
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-error"></div>
                <span class="text-xs font-medium">No Heat</span>
              </div>
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-success"></div>
                <span class="text-xs font-medium">Fix</span>
              </div>
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-warning"></div>
                <span class="text-xs font-medium">Tank Install</span>
              </div>
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-neutral"></div>
                <span class="text-xs font-medium">Other</span>
              </div>
              <div class="flex items-center gap-1.5">
                <div class="w-3 h-3 rounded-sm bg-accent/60"></div>
                <span class="text-xs font-medium">Holiday</span>
              </div>
            </div>
          </div>
        </div>

        <!-- FullCalendar -->
        <div class="calendar-body p-6">
          <FullCalendar ref="fullCalendar" :key="calendarKey" :options="calendarOptions" />
        </div>
      </div>
    </div>
  </div>

  <!-- Edit Modal -->
  <ServiceEditModal
    v-if="selectedServiceForEdit"
    :service="selectedServiceForEdit"
    @close-modal="closeEditModal"
    @save-changes="handleSaveChanges"
    @delete-service="handleDeleteService"
  />
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import dayjs from 'dayjs';
import FullCalendar from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import { CalendarOptions, EventClickArg, DayCellContentArg } from '@fullcalendar/core';
import ServiceEditModal from './ServiceEditModal.vue';
import { serviceService } from '../../services/serviceService';
import { authService } from '../../services/authService';
import { AxiosResponse, AxiosError, ServiceCall } from '../../types/models';
import { getFederalHolidays, type Holiday } from '../../utils/holidays';
import { notify } from '@kyvg/vue3-notification';

// Reactive data
const user = ref(null)
const selectedServiceForEdit = ref(null as Partial<ServiceCall> | null)
const fullCalendar = ref()
const calendarKey = ref(0)
const currentView = ref('dayGridMonth')
const holidays = ref<Holiday[]>([])
const currentDate = ref(new Date())

// Computed
const currentMonthYear = computed(() => {
  return currentDate.value.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
})

// Load holidays for current year and next year
const loadHolidays = () => {
  const currentYear = new Date().getFullYear()
  const allHolidays = [
    ...getFederalHolidays(currentYear - 1),
    ...getFederalHolidays(currentYear),
    ...getFederalHolidays(currentYear + 1),
  ]
  holidays.value = allHolidays
}

// Check if a date is a holiday
const isHolidayDate = (dateStr: string): Holiday | undefined => {
  return holidays.value.find(h => h.date === dateStr)
}

// Event handlers
const handleEventClick = (clickInfo: EventClickArg): void => {
  const start = clickInfo.event.start;
  selectedServiceForEdit.value = {
    id: parseInt(clickInfo.event.id),
    scheduled_date: start ? dayjs(start).format('YYYY-MM-DDTHH:mm:ss') : '',
    customer_name: clickInfo.event.title.split(': ')[1] || 'Unknown Customer',
    customer_id: clickInfo.event.extendedProps.customer_id,
    type_service_call: clickInfo.event.extendedProps.type_service_call,
    description: clickInfo.event.extendedProps.description,
    service_cost: clickInfo.event.extendedProps.service_cost,
  };
}

const TYPE_CLASS: Record<number, string> = {
  0: 'event-tune-up',
  1: 'event-no-heat',
  2: 'event-fix',
  3: 'event-tank',
  4: 'event-other',
}

// Fetch and render all events imperatively
const fetchCalendarEvents = async () => {
  try {
    const response = await serviceService.getAll();
    const rawEvents: any[] = response.data?.events || [];

    const serviceEvents = rawEvents.map(ev => ({
      ...ev,
      backgroundColor: undefined,
      borderColor: undefined,
      textColor: undefined,
      classNames: [TYPE_CLASS[ev.extendedProps?.type_service_call] ?? 'event-other'],
    }));

    const holidayEvents = holidays.value.map(holiday => ({
      id: `holiday-${holiday.date}`,
      title: holiday.name,
      start: holiday.date,
      allDay: true,
      display: 'background',
      classNames: ['holiday-event'],
    }));

    const allEvents = [...serviceEvents, ...holidayEvents];
    calendarOptions.value.events = allEvents as any;

    const api = (fullCalendar.value as any)?.getApi();
    if (api) {
      api.removeAllEvents();
      allEvents.forEach((e: any) => api.addEvent(e));
    }
  } catch (err: unknown) {
    console.error("Failed to fetch calendar events:", err);
  }
};

// Calendar navigation
const goToToday = () => {
  const calendarApi = (fullCalendar.value as any).getApi()
  calendarApi.today()
  currentDate.value = calendarApi.getDate()
}

const previousMonth = () => {
  const calendarApi = (fullCalendar.value as any).getApi()
  calendarApi.prev()
  currentDate.value = calendarApi.getDate()
}

const nextMonth = () => {
  const calendarApi = (fullCalendar.value as any).getApi()
  calendarApi.next()
  currentDate.value = calendarApi.getDate()
}

const changeView = (viewName: string) => {
  currentView.value = viewName
  const calendarApi = (fullCalendar.value as any).getApi()
  calendarApi.changeView(viewName)
  currentDate.value = calendarApi.getDate()
}

// Day cell class names for holidays
const getDayCellClassNames = (arg: any) => {
  // Format date as YYYY-MM-DD
  const year = arg.date.getFullYear()
  const month = String(arg.date.getMonth() + 1).padStart(2, '0')
  const day = String(arg.date.getDate()).padStart(2, '0')
  const dateStr = `${year}-${month}-${day}`
  
  const holiday = isHolidayDate(dateStr)
  
  if (holiday) {
    console.log('Holiday found:', holiday.name, 'on', dateStr)
  }
  
  return holiday ? ['holiday-cell'] : []
}

const eventContent = (arg: any) => {
  const time = arg.timeText || ''
  const title = arg.event.title || ''
  const desc = arg.event.extendedProps?.description || ''
  return {
    html: `<div style="padding:2px 4px">
      ${time ? `<div class="fc-event-time">${time}</div>` : ''}
      <div class="fc-event-title">${title}</div>
      ${desc ? `<div class="fc-event-desc">${desc}</div>` : ''}
    </div>`
  }
}

// Calendar options
const calendarOptions = ref({
  plugins: [dayGridPlugin, interactionPlugin],
  initialView: 'dayGridMonth',
  headerToolbar: false,
  weekends: true,
  height: 'auto',
  events: [],
  eventClick: handleEventClick,
  dayCellClassNames: getDayCellClassNames,
  eventDisplay: 'block',
  displayEventTime: true,
  eventTimeFormat: { hour: 'numeric', minute: '2-digit', meridiem: 'short' },
  eventContent,
} as CalendarOptions)

// Modal handlers
const closeEditModal = () => {
  selectedServiceForEdit.value = null;
}

const handleSaveChanges = async (updatedService: ServiceCall) => {
  try {
    await serviceService.update(updatedService.id, updatedService);
    await fetchCalendarEvents();
    calendarKey.value++;
    closeEditModal();
    notify({ title: 'Saved', text: 'Service call updated.', type: 'success' });
  } catch (error) {
    console.error("Failed to save changes:", error);
    notify({ title: 'Error', text: 'Failed to save service call.', type: 'error' });
  }
}

const handleDeleteService = async (serviceId: number) => {
  try {
    await serviceService.delete(serviceId);
    await fetchCalendarEvents();
    calendarKey.value++;
    closeEditModal();
  } catch (error) {
    console.error("Error deleting event:", error);
  }
}

const userStatus = () => {
  authService.whoami().then((response: AxiosResponse<any>) => {
    if (response.data.ok) {
      user.value = response.data.user;
    }
  })
  .catch(() => {
    user.value = null
  })
}

// Lifecycle
onMounted(async () => {
  userStatus();
  loadHolidays();
  await fetchCalendarEvents();
})
</script>

<style scoped>
.calendar-page {
  @apply min-h-screen;
}

/* ── Grid chrome ── */
:deep(.fc) { @apply font-sans; }

:deep(.fc-theme-standard td),
:deep(.fc-theme-standard th) {
  border-color: hsl(var(--bc) / 0.15) !important;
}

:deep(.fc-scrollgrid) {
  border-color: hsl(var(--bc) / 0.15) !important;
}

:deep(.fc-col-header-cell) {
  background: linear-gradient(135deg, #1e40af 0%, #1d4ed8 100%) !important;
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.85) !important;
  padding: 12px 0;
  border: none !important;
}

:deep(.fc-col-header-cell a) {
  color: rgba(255, 255, 255, 0.85) !important;
  text-decoration: none !important;
}

/* Today column header — brighter white */
:deep(.fc-col-header-cell.fc-day-today) {
  background: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%) !important;
  color: #fff !important;
  box-shadow: inset 0 -3px 0 rgba(255,255,255,0.4);
}

:deep(.fc-col-header-cell.fc-day-today a) {
  color: #fff !important;
}

:deep(.fc-daygrid-day) {
  @apply transition-colors duration-150;
  border-color: hsl(var(--bc) / 0.15) !important;
}

:deep(.fc-daygrid-day:hover) {
  background-color: hsl(var(--b2)) !important;
}

/* ── Day number ── */
:deep(.fc-daygrid-day-number) {
  @apply text-base-content/70 font-medium text-sm p-2;
}

:deep(.fc-daygrid-day-frame) {
  @apply min-h-[130px];
}

:deep(.fc-daygrid-day-top) {
  @apply flex justify-start;
}

/* ── TODAY — full box highlight ── */
:deep(.fc-day-today) {
  background-color: rgba(59, 130, 246, 0.18) !important;
  border: 2px solid rgba(59, 130, 246, 0.55) !important;
}

:deep(.fc-day-today .fc-daygrid-day-number) {
  background-color: #3b82f6 !important;
  color: #fff !important;
  @apply font-bold rounded-full text-sm;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 4px;
  padding: 0;
}

/* ── Weekends ── */
:deep(.fc-day-sat),
:deep(.fc-day-sun) {
  background-color: hsl(var(--b2)) !important;
}

:deep(.fc-day-sat .fc-daygrid-day-number),
:deep(.fc-day-sun .fc-daygrid-day-number) {
  @apply opacity-60;
}

:deep(.fc-col-header-cell.fc-day-sat),
:deep(.fc-col-header-cell.fc-day-sun) {
  color: rgba(255, 255, 255, 0.5) !important;
}

/* ── Event base ── */
:deep(.fc-event) {
  @apply rounded mb-0.5 cursor-pointer transition-opacity duration-150 shadow-sm;
  border-left-width: 3px !important;
  border-top: none !important;
  border-right: none !important;
  border-bottom: none !important;
}

:deep(.fc-event:hover) { @apply opacity-90; }

:deep(.fc-event-main) {
  @apply px-1.5 py-0.5;
}

:deep(.fc-event-time) {
  @apply font-bold text-xs opacity-90;
  display: block;
}

:deep(.fc-event-title) {
  @apply text-xs font-semibold;
  white-space: normal;
  word-break: break-word;
  line-height: 1.3;
}

:deep(.fc-event-desc) {
  @apply text-xs opacity-80 mt-0.5;
  white-space: normal;
  word-break: break-word;
  line-height: 1.3;
}

/* ── Per-type colors ── */
:deep(.event-tune-up) {
  background-color: hsl(var(--in) / 0.18) !important;
  border-left-color: hsl(var(--in)) !important;
  color: hsl(var(--in)) !important;
}

:deep(.event-no-heat) {
  background-color: hsl(var(--er) / 0.18) !important;
  border-left-color: hsl(var(--er)) !important;
  color: hsl(var(--er)) !important;
}

:deep(.event-fix) {
  background-color: hsl(var(--su) / 0.18) !important;
  border-left-color: hsl(var(--su)) !important;
  color: hsl(var(--su)) !important;
}

:deep(.event-tank) {
  background-color: hsl(var(--wa) / 0.18) !important;
  border-left-color: hsl(var(--wa)) !important;
  color: hsl(var(--wac)) !important;
}

:deep(.event-other) {
  background-color: hsl(var(--n) / 0.25) !important;
  border-left-color: hsl(var(--n)) !important;
  color: hsl(var(--nc)) !important;
}

/* ── Holidays ── */
:deep(.holiday-cell) {
  background-color: hsl(var(--a) / 0.08) !important;
}

:deep(.holiday-cell .fc-daygrid-day-number) {
  color: hsl(var(--a)) !important;
}

:deep(.fc-bg-event.holiday-event) {
  background-color: hsl(var(--a) / 0.12) !important;
  opacity: 1 !important;
}

/* ── Toolbar (hidden — custom header used) ── */
:deep(.fc-toolbar) { @apply hidden; }
</style>