import { createChart } from '@sevenweirdpeople/swp-charting';
import { Accordion } from './accordion';

/**
 * Employees Controller
 *
 * Handles content swap between list view and detail view,
 * plus tab switching within each view.
 * Uses History API for browser back/forward navigation.
 */

interface DataPoint {
  x: string;
  y: number | null;
}

interface RevenueSeriesConfig {
  name: string;
  color: string;
  data: DataPoint[];
}

interface RevenueChartData {
  categories: string[];
  series: RevenueSeriesConfig[];
}

interface RevenueUtilizationData {
  categories: string[];
  actual: {
    revenue: DataPoint[];
    utilization: DataPoint[];
  };
  forecast: {
    revenue: DataPoint[];
    utilization: DataPoint[];
  };
}

interface RecentBooking {
  customer: string;
  service: string;
  date: string;
  amount: string;
}

interface CompletedBooking {
  date: string;
  time: string;
  customer: string;
  services: string;
  duration: string;
  amount: string;
  status: string;
  statusClass: string;
}

interface EmployeeStatsData {
  stats: {
    bookingsThisMonth: number;
    bookedServicesValue: string;
    bookedServicesSubtitle: string;
    revenueThisMonth: string;
    returnCustomers: string;
  };
  revenueUtilization: RevenueUtilizationData;
  revenue: RevenueChartData;
  recentBookings: RecentBooking[];
  completedBookings: CompletedBooking[];
}

export class EmployeesController {
  private ratesSync: RatesSyncController | null = null;
  private scheduleController: ScheduleController | null = null;
  private statsController: EmployeeStatsController | null = null;
  private salaryAccordions: Accordion[] = [];
  private listView: HTMLElement | null = null;
  private detailView: HTMLElement | null = null;

  constructor() {
    this.listView = document.getElementById('employees-list-view');
    this.detailView = document.getElementById('employee-detail-view');

    // Only initialize if we're on the employees page
    if (!this.listView) return;

    this.setupListTabs();
    this.setupDetailTabs();
    this.setupChevronNavigation();
    this.setupBackNavigation();
    this.setupHistoryNavigation();
    this.restoreStateFromUrl();
    this.ratesSync = new RatesSyncController();
    this.scheduleController = new ScheduleController();
    this.statsController = new EmployeeStatsController();
    this.setupSalaryTabListener();
  }

  /**
   * Listen for salary tab activation to initialize accordions
   */
  private setupSalaryTabListener(): void {
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;
      const tab = target.closest<HTMLElement>('swp-tab[data-tab="salary"]');

      if (tab) {
        // Small delay to ensure tab content is visible
        setTimeout(() => this.initSalaryAccordions(), 50);
      }
    });
  }

  /**
   * Initialize salary tab accordions
   */
  private initSalaryAccordions(): void {
    if (this.salaryAccordions.length > 0) return;

    const salaryTab = document.querySelector('swp-tab-content[data-tab="salary"]');
    if (salaryTab) {
      salaryTab.querySelectorAll<HTMLElement>('swp-accordion').forEach(accordion => {
        this.salaryAccordions.push(new Accordion(accordion, { singleOpen: true }));
      });
    }
  }

  /**
   * Setup popstate listener for browser back/forward
   */
  private setupHistoryNavigation(): void {
    window.addEventListener('popstate', (e: PopStateEvent) => {
      if (e.state?.employeeKey) {
        this.showDetailViewInternal(e.state.employeeKey);
      } else {
        this.showListViewInternal();
      }
    });
  }

  /**
   * Restore view state from URL on page load
   */
  private restoreStateFromUrl(): void {
    const hash = window.location.hash;
    if (hash.startsWith('#employee-')) {
      const employeeKey = hash.substring(1); // Remove #
      this.showDetailViewInternal(employeeKey);
    }
  }

  /**
   * Setup tab switching for the list view
   */
  private setupListTabs(): void {
    if (!this.listView) return;

    const tabs = this.listView.querySelectorAll<HTMLElement>('swp-tab-bar > swp-tab[data-tab]');

    tabs.forEach(tab => {
      tab.addEventListener('click', () => {
        const targetTab = tab.dataset.tab;
        if (targetTab) {
          this.switchTab(this.listView!, targetTab);
        }
      });
    });
  }

  /**
   * Setup tab switching for the detail view
   */
  private setupDetailTabs(): void {
    if (!this.detailView) return;

    const tabs = this.detailView.querySelectorAll<HTMLElement>('swp-tab-bar > swp-tab[data-tab]');

    tabs.forEach(tab => {
      tab.addEventListener('click', () => {
        const targetTab = tab.dataset.tab;
        if (targetTab) {
          this.switchTab(this.detailView!, targetTab);
        }
      });
    });
  }

  /**
   * Switch to a specific tab within a container
   */
  private switchTab(container: HTMLElement, targetTab: string): void {
    const tabs = container.querySelectorAll<HTMLElement>('swp-tab-bar > swp-tab[data-tab]');
    const contents = container.querySelectorAll<HTMLElement>('swp-tab-content[data-tab]');

    tabs.forEach(t => {
      t.classList.toggle('active', t.dataset.tab === targetTab);
    });

    contents.forEach(content => {
      content.classList.toggle('active', content.dataset.tab === targetTab);
    });
  }

  /**
   * Setup row click to show detail view
   * Ignores clicks on action buttons
   */
  private setupChevronNavigation(): void {
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;

      // Ignore clicks on action buttons
      if (target.closest('swp-icon-btn') || target.closest('swp-table-actions')) {
        return;
      }

      const row = target.closest<HTMLElement>('swp-data-table-row[data-employee-detail]');

      if (row) {
        const employeeKey = row.dataset.employeeDetail;
        if (employeeKey) {
          this.showDetailView(employeeKey);
        }
      }
    });
  }

  /**
   * Setup back button to return to list view
   */
  private setupBackNavigation(): void {
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;
      const backLink = target.closest<HTMLElement>('[data-employee-back]');

      if (backLink) {
        this.showListView();
      }
    });
  }

  /**
   * Show the detail view and hide list view (with history push)
   */
  private showDetailView(employeeKey: string): void {
    // Push state to history
    history.pushState(
      { employeeKey },
      '',
      `#${employeeKey}`
    );
    this.showDetailViewInternal(employeeKey);
  }

  /**
   * Show detail view without modifying history (for popstate)
   */
  private showDetailViewInternal(employeeKey: string): void {
    if (this.listView && this.detailView) {
      // Fade out list view
      this.listView.classList.add('view-fade-out');

      // After fade, switch views
      setTimeout(() => {
        this.listView!.style.display = 'none';
        this.listView!.classList.remove('view-fade-out');

        // Show detail view with fade in
        this.detailView!.style.display = 'block';
        this.detailView!.classList.add('view-fade-out');
        this.detailView!.dataset.employee = employeeKey;

        // Reset to first tab
        this.switchTab(this.detailView!, 'general');

        // Trigger fade in
        requestAnimationFrame(() => {
          this.detailView!.classList.remove('view-fade-out');
        });
      }, 100);
    }
  }

  /**
   * Show the list view and hide detail view (with history push)
   */
  private showListView(): void {
    // Push state to history (clear hash)
    history.pushState(
      {},
      '',
      window.location.pathname
    );
    this.showListViewInternal();
  }

  /**
   * Show list view without modifying history (for popstate)
   */
  private showListViewInternal(): void {
    if (this.listView && this.detailView) {
      // Fade out detail view
      this.detailView.classList.add('view-fade-out');

      // After fade, switch views
      setTimeout(() => {
        this.detailView!.style.display = 'none';
        this.detailView!.classList.remove('view-fade-out');

        // Show list view with fade in
        this.listView!.style.display = 'block';
        this.listView!.classList.add('view-fade-out');

        // Trigger fade in
        requestAnimationFrame(() => {
          this.listView!.classList.remove('view-fade-out');
        });
      }, 100);
    }
  }
}

/**
 * Rates Sync Controller
 *
 * Syncs changes between the rates drawer and the salary tab cards.
 * Uses ID-based lookups:
 * - Checkbox: id="rate-{key}-enabled"
 * - Text input: id="rate-{key}"
 * - Card row: id="card-{key}"
 */
class RatesSyncController {
  private drawer: HTMLElement | null = null;

  constructor() {
    this.drawer = document.getElementById('rates-drawer');

    if (!this.drawer) return;

    this.setupCheckboxListeners();
    this.setupInputListeners();
    this.setupDoubleClickToEdit();
  }

  /**
   * Extract rate key from checkbox ID (e.g., "rate-normal-enabled" → "normal")
   */
  private extractRateKey(checkboxId: string): string | null {
    const match = checkboxId.match(/^rate-(.+)-enabled$/);
    return match ? match[1] : null;
  }

  /**
   * Setup checkbox change listeners in drawer
   */
  private setupCheckboxListeners(): void {
    if (!this.drawer) return;

    this.drawer.addEventListener('change', (e: Event) => {
      const target = e.target as HTMLInputElement;
      if (target.type !== 'checkbox' || !target.id) return;

      const rateKey = this.extractRateKey(target.id);
      if (!rateKey) return;

      const isChecked = target.checked;
      const row = target.closest<HTMLElement>('swp-data-row');
      if (!row) return;

      // Toggle disabled class in drawer row
      const label = row.querySelector('swp-data-label');
      const input = row.querySelector('swp-data-input');
      if (label) label.classList.toggle('disabled', !isChecked);
      if (input) input.classList.toggle('disabled', !isChecked);

      // Toggle visibility in card
      this.toggleCardRow(rateKey, isChecked);

      // If enabling, also sync the current value
      if (isChecked) {
        const textInput = document.getElementById(`rate-${rateKey}`) as HTMLInputElement | null;
        if (textInput) {
          this.syncValueToCard(rateKey, textInput.value);
        }
      }
    });
  }

  /**
   * Setup input change listeners in drawer
   */
  private setupInputListeners(): void {
    if (!this.drawer) return;

    this.drawer.addEventListener('input', (e: Event) => {
      const target = e.target as HTMLInputElement;
      if (target.type !== 'text' || !target.id) return;

      // Extract rate key from input ID (e.g., "rate-normal" → "normal")
      const match = target.id.match(/^rate-(.+)$/);
      if (!match) return;

      const rateKey = match[1];
      // Skip if this matches the checkbox pattern
      if (rateKey.endsWith('-enabled')) return;

      this.syncValueToCard(rateKey, target.value);
    });
  }

  /**
   * Toggle card row visibility by ID
   */
  private toggleCardRow(rateKey: string, visible: boolean): void {
    const cardRow = document.getElementById(`card-${rateKey}`);
    if (cardRow) {
      cardRow.style.display = visible ? '' : 'none';
    }
  }

  /**
   * Format number with 2 decimals using Danish locale (comma as decimal separator)
   */
  private formatNumber(value: string): string {
    // Parse the input (handle both dot and comma as decimal separator)
    const normalized = value.replace(',', '.');
    const num = parseFloat(normalized);

    if (isNaN(num)) return value;

    // Format with 2 decimals and comma as decimal separator
    return num.toFixed(2).replace('.', ',');
  }

  /**
   * Sync value from drawer to card by ID
   */
  private syncValueToCard(rateKey: string, value: string): void {
    const cardInput = document.getElementById(`value-${rateKey}`) as HTMLInputElement | null;
    if (!cardInput) return;

    // Get the unit from drawer input container
    const textInput = document.getElementById(`rate-${rateKey}`);
    const inputContainer = textInput?.closest('swp-data-input');
    const unit = inputContainer?.textContent?.trim().replace(value, '').trim() || 'kr';

    // Format with 2 decimals
    const formattedValue = this.formatNumber(value);
    cardInput.value = `${formattedValue} ${unit}`;
  }

  /**
   * Setup double-click on salary card inputs to open drawer and focus field
   */
  private setupDoubleClickToEdit(): void {
    document.addEventListener('dblclick', (e: Event) => {
      const target = e.target as HTMLElement;
      const input = target.closest<HTMLInputElement>('input[id^="value-"]');

      if (!input || !input.id) return;

      // Extract key from value-{key}
      const match = input.id.match(/^value-(.+)$/);
      if (!match) return;

      const rateKey = match[1];
      this.openDrawerAndFocus(rateKey);
    });
  }

  /**
   * Open drawer and focus the corresponding field with highlight
   */
  private openDrawerAndFocus(rateKey: string): void {
    // Open the drawer
    const trigger = document.querySelector<HTMLElement>('[data-drawer-trigger="rates-drawer"]');
    trigger?.click();

    // Wait for drawer to open, then focus field
    requestAnimationFrame(() => {
      const drawerInput = document.getElementById(`rate-${rateKey}`) as HTMLInputElement | null;
      if (!drawerInput) return;

      // Focus the input
      drawerInput.focus();
      drawerInput.select();

      // Add highlight to row
      const row = drawerInput.closest<HTMLElement>('swp-data-row');
      if (row) {
        row.classList.add('focus-highlight');
        // Remove class after animation
        setTimeout(() => row.classList.remove('focus-highlight'), 1000);
      }
    });
  }
}

/**
 * Schedule Controller
 *
 * Handles work schedule (vagtplan) functionality:
 * - Edit mode toggle
 * - Cell selection (single, ctrl+click, shift+click)
 * - Drawer interaction
 * - Time range slider
 * - Status options
 */
class ScheduleController {
  private isEditMode = false;
  private selectedCells: HTMLElement[] = [];
  private anchorCell: HTMLElement | null = null;
  private drawer: HTMLElement | null = null;
  private editBtn: HTMLElement | null = null;
  private scheduleTable: HTMLElement | null = null;

  constructor() {
    this.drawer = document.getElementById('schedule-drawer');
    this.editBtn = document.getElementById('scheduleEditBtn');
    this.scheduleTable = document.getElementById('scheduleTable');

    // Drag scroll works for all schedule scroll containers (Vagtplan + Arbejdstid)
    this.setupDragScroll();

    if (!this.scheduleTable) return;

    this.setupEditModeToggle();
    this.setupCellSelection();
    this.setupStatusOptions();
    this.setupTypeToggle();
    this.setupTimeRangeEvents();
    this.setupDrawerSave();
  }

  /**
   * Setup drag-to-scroll on schedule scroll containers
   */
  private setupDragScroll(): void {
    const scrollContainers = document.querySelectorAll('swp-schedule-scroll');

    scrollContainers.forEach(container => {
      const el = container as HTMLElement;
      let isDown = false;
      let hasDragged = false;
      let startX = 0;
      let scrollLeft = 0;

      const onMouseDown = (e: MouseEvent) => {
        // Don't drag if clicking on interactive elements
        if ((e.target as HTMLElement).closest('swp-btn, input, select')) return;

        isDown = true;
        hasDragged = false;
        startX = e.clientX;
        scrollLeft = el.scrollLeft;
      };

      const onMouseUp = () => {
        isDown = false;
        el.classList.remove('dragging');

        // Reset hasDragged after a short delay to allow click events to check it
        setTimeout(() => { hasDragged = false; }, 0);
      };

      const onMouseMove = (e: MouseEvent) => {
        if (!isDown) return;

        const x = e.clientX;
        const diff = Math.abs(startX - x);

        // Only start dragging after moving 5px (allows clicks/double-clicks)
        if (!hasDragged && diff > 5) {
          hasDragged = true;
          el.classList.add('dragging');
        }

        if (!hasDragged) return;

        e.preventDefault();
        const walk = (startX - x) * 1.5;
        el.scrollLeft = scrollLeft + walk;
      };

      // Prevent click events if we just dragged
      const onClick = (e: MouseEvent) => {
        if (hasDragged) {
          e.preventDefault();
          e.stopPropagation();
        }
      };

      el.addEventListener('mousedown', onMouseDown);
      el.addEventListener('mouseup', onMouseUp);
      el.addEventListener('mouseleave', onMouseUp);
      el.addEventListener('mousemove', onMouseMove);
      el.addEventListener('click', onClick, true); // capture phase
    });
  }

  /**
   * Setup edit mode toggle button
   */
  private setupEditModeToggle(): void {
    this.editBtn?.addEventListener('click', () => {
      this.isEditMode = !this.isEditMode;
      document.body.classList.toggle('schedule-edit-mode', this.isEditMode);

      if (this.editBtn) {
        const icon = this.editBtn.querySelector('i');
        const text = this.editBtn.childNodes[this.editBtn.childNodes.length - 1];

        if (this.isEditMode) {
          icon?.classList.replace('ph-pencil-simple', 'ph-check');
          if (text && text.nodeType === Node.TEXT_NODE) {
            text.textContent = ' Færdig';
          }
          this.openDrawer();
          this.showEmptyState();
        } else {
          icon?.classList.replace('ph-check', 'ph-pencil-simple');
          if (text && text.nodeType === Node.TEXT_NODE) {
            text.textContent = ' Rediger';
          }
          this.closeDrawer();
          this.clearSelection();
        }
      }
    });
  }

  /**
   * Setup cell click selection
   */
  private setupCellSelection(): void {
    if (!this.scheduleTable) return;

    const dayCells = this.scheduleTable.querySelectorAll<HTMLElement>('swp-schedule-cell.day');

    dayCells.forEach(cell => {
      // Double-click to enter edit mode
      cell.addEventListener('dblclick', () => {
        if (!this.isEditMode) {
          this.isEditMode = true;
          document.body.classList.add('schedule-edit-mode');

          if (this.editBtn) {
            const icon = this.editBtn.querySelector('i');
            const text = this.editBtn.childNodes[this.editBtn.childNodes.length - 1];
            icon?.classList.replace('ph-pencil-simple', 'ph-check');
            if (text && text.nodeType === Node.TEXT_NODE) {
              text.textContent = ' Færdig';
            }
          }

          this.openDrawer();
          this.clearSelection();
          cell.classList.add('selected');
          this.selectedCells = [cell];
          this.anchorCell = cell;
          this.updateDrawerFields();
        }
      });

      // Click selection in edit mode
      cell.addEventListener('click', (e: MouseEvent) => {
        if (!this.isEditMode) return;

        if (e.shiftKey && this.anchorCell) {
          // Shift+click: range selection
          this.selectRange(this.anchorCell, cell);
        } else if (e.ctrlKey || e.metaKey) {
          // Ctrl/Cmd+click: toggle selection
          if (cell.classList.contains('selected')) {
            cell.classList.remove('selected');
            this.selectedCells = this.selectedCells.filter(c => c !== cell);
          } else {
            cell.classList.add('selected');
            this.selectedCells.push(cell);
            this.anchorCell = cell;
          }
        } else {
          // Single click: replace selection
          this.clearSelection();
          cell.classList.add('selected');
          this.selectedCells = [cell];
          this.anchorCell = cell;
        }

        this.updateDrawerFields();
      });
    });
  }

  /**
   * Select a range of cells between anchor and target
   */
  private selectRange(anchor: HTMLElement, target: HTMLElement): void {
    if (!this.scheduleTable) return;

    const allDayCells = Array.from(this.scheduleTable.querySelectorAll<HTMLElement>('swp-schedule-cell.day'));
    const anchorIdx = allDayCells.indexOf(anchor);
    const targetIdx = allDayCells.indexOf(target);

    // Calculate grid positions (7 columns for days)
    const anchorRow = Math.floor(anchorIdx / 7);
    const anchorCol = anchorIdx % 7;
    const targetRow = Math.floor(targetIdx / 7);
    const targetCol = targetIdx % 7;

    const minRow = Math.min(anchorRow, targetRow);
    const maxRow = Math.max(anchorRow, targetRow);
    const minCol = Math.min(anchorCol, targetCol);
    const maxCol = Math.max(anchorCol, targetCol);

    this.clearSelection();

    allDayCells.forEach((c, idx) => {
      const row = Math.floor(idx / 7);
      const col = idx % 7;
      if (row >= minRow && row <= maxRow && col >= minCol && col <= maxCol) {
        c.classList.add('selected');
        this.selectedCells.push(c);
      }
    });
  }

  /**
   * Clear all selected cells
   */
  private clearSelection(): void {
    this.selectedCells.forEach(c => c.classList.remove('selected'));
    this.selectedCells = [];
  }

  /**
   * Get initials from name
   */
  private getInitials(name: string): string {
    return name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
  }

  /**
   * Show empty state in drawer
   */
  private showEmptyState(): void {
    const employeeDisplay = document.getElementById('scheduleFieldEmployee');
    const avatar = document.getElementById('scheduleFieldAvatar');
    const employeeName = document.getElementById('scheduleFieldEmployeeName');
    const dateField = document.getElementById('scheduleFieldDate');
    const weekdayField = document.getElementById('scheduleFieldWeekday');
    const drawerBody = this.drawer?.querySelector('swp-drawer-body') as HTMLElement;
    const drawerFooter = this.drawer?.querySelector('swp-drawer-footer') as HTMLElement;

    if (employeeDisplay) employeeDisplay.classList.add('empty');
    if (employeeDisplay) employeeDisplay.classList.remove('multi');
    if (avatar) avatar.textContent = '?';
    if (employeeName) employeeName.textContent = 'Vælg celle...';
    if (dateField) dateField.textContent = '—';
    if (weekdayField) weekdayField.textContent = '—';
    if (drawerBody) {
      drawerBody.style.opacity = '0.5';
      drawerBody.style.pointerEvents = 'none';
    }
    if (drawerFooter) drawerFooter.style.display = 'none';
  }

  /**
   * Show edit state in drawer
   */
  private showEditState(): void {
    const drawerBody = this.drawer?.querySelector('swp-drawer-body') as HTMLElement;
    const drawerFooter = this.drawer?.querySelector('swp-drawer-footer') as HTMLElement;

    if (drawerBody) {
      drawerBody.style.opacity = '1';
      drawerBody.style.pointerEvents = 'auto';
    }
    if (drawerFooter) drawerFooter.style.display = 'flex';
  }

  /**
   * Update drawer fields based on selected cells
   */
  private updateDrawerFields(): void {
    if (this.selectedCells.length === 0) {
      this.showEmptyState();
      return;
    }

    this.showEditState();

    const employeeDisplay = document.getElementById('scheduleFieldEmployee');
    const avatar = document.getElementById('scheduleFieldAvatar');
    const employeeName = document.getElementById('scheduleFieldEmployeeName');
    const dateField = document.getElementById('scheduleFieldDate');
    const weekdayField = document.getElementById('scheduleFieldWeekday');

    employeeDisplay?.classList.remove('empty', 'multi');

    if (this.selectedCells.length === 1) {
      const cell = this.selectedCells[0];
      const name = cell.dataset.employee || '';
      const date = cell.dataset.date || '';
      const dayName = this.getDayName(cell.dataset.day || '');

      if (employeeName) employeeName.textContent = name;
      if (avatar) avatar.textContent = this.getInitials(name);
      if (dateField) dateField.textContent = this.formatDate(date);
      if (weekdayField) weekdayField.textContent = dayName;

      this.prefillFormFromCell(cell);
    } else {
      const employees = [...new Set(this.selectedCells.map(c => c.dataset.employee))];
      const days = [...new Set(this.selectedCells.map(c => c.dataset.day))];

      if (employees.length === 1) {
        if (employeeName) employeeName.textContent = employees[0] || '';
        if (avatar) avatar.textContent = this.getInitials(employees[0] || '');
        if (dateField) dateField.textContent = `${this.selectedCells.length} dage valgt`;
      } else {
        if (employeeName) employeeName.textContent = `${this.selectedCells.length} valgt`;
        if (avatar) avatar.textContent = String(this.selectedCells.length);
        employeeDisplay?.classList.add('multi');
        if (dateField) dateField.textContent = `${employees.length} medarbejdere, ${days.length} dage`;
      }

      if (days.length === 1) {
        if (weekdayField) weekdayField.textContent = this.getDayName(days[0] || '');
      } else {
        if (weekdayField) weekdayField.textContent = 'Flere dage';
      }

      this.resetFormToDefault();
    }
  }

  /**
   * Format ISO date to display format
   */
  private formatDate(isoDate: string): string {
    const date = new Date(isoDate);
    return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;
  }

  /**
   * Get full day name from short name
   */
  private getDayName(shortName: string): string {
    const dayMap: Record<string, string> = {
      'Man': 'Mandag', 'Tir': 'Tirsdag', 'Ons': 'Onsdag',
      'Tor': 'Torsdag', 'Fre': 'Fredag', 'Lør': 'Lørdag', 'Søn': 'Søndag'
    };
    return dayMap[shortName] || shortName;
  }

  /**
   * Prefill form from cell data
   */
  private prefillFormFromCell(cell: HTMLElement): void {
    const timeBadge = cell.querySelector('swp-time-badge');
    if (!timeBadge) return;

    let status = 'work';
    if (timeBadge.classList.contains('off')) status = 'off';
    else if (timeBadge.classList.contains('vacation')) status = 'vacation';
    else if (timeBadge.classList.contains('sick')) status = 'sick';

    // Update status options
    document.querySelectorAll('#scheduleStatusOptions swp-status-option').forEach(opt => {
      opt.classList.toggle('selected', (opt as HTMLElement).dataset.status === status);
    });

    // Show/hide time row
    const timeRow = document.getElementById('scheduleTimeRow');
    if (timeRow) timeRow.style.display = status === 'work' ? 'flex' : 'none';

    // Parse time if work status
    if (status === 'work') {
      const timeText = timeBadge.textContent?.trim() || '';
      const timeMatch = timeText.match(/(\d{2}:\d{2})\s*-\s*(\d{2}:\d{2})/);
      if (timeMatch) {
        this.setTimeRange(timeMatch[1], timeMatch[2]);
      }
    }

    // Reset type to template
    document.querySelectorAll('#scheduleTypeOptions swp-toggle-option').forEach(opt => {
      opt.classList.toggle('selected', (opt as HTMLElement).dataset.value === 'template');
    });
    const repeatGroup = document.getElementById('scheduleRepeatGroup');
    if (repeatGroup) repeatGroup.style.display = 'block';
  }

  /**
   * Reset form to default values
   */
  private resetFormToDefault(): void {
    document.querySelectorAll('#scheduleStatusOptions swp-status-option').forEach(opt => {
      opt.classList.toggle('selected', (opt as HTMLElement).dataset.status === 'work');
    });

    const timeRow = document.getElementById('scheduleTimeRow');
    if (timeRow) timeRow.style.display = 'flex';

    this.setTimeRange('09:00', '17:00');

    document.querySelectorAll('#scheduleTypeOptions swp-toggle-option').forEach(opt => {
      opt.classList.toggle('selected', (opt as HTMLElement).dataset.value === 'template');
    });

    const repeatGroup = document.getElementById('scheduleRepeatGroup');
    if (repeatGroup) repeatGroup.style.display = 'block';

    const noteField = document.getElementById('scheduleFieldNote') as HTMLInputElement;
    if (noteField) noteField.value = '';
  }

  /**
   * Setup status options click handlers
   */
  private setupStatusOptions(): void {
    document.querySelectorAll('#scheduleStatusOptions swp-status-option').forEach(option => {
      option.addEventListener('click', () => {
        document.querySelectorAll('#scheduleStatusOptions swp-status-option').forEach(o =>
          o.classList.remove('selected')
        );
        option.classList.add('selected');

        const status = (option as HTMLElement).dataset.status;
        const timeRow = document.getElementById('scheduleTimeRow');
        if (timeRow) timeRow.style.display = status === 'work' ? 'flex' : 'none';

        this.updateSelectedCellsStatus();
      });
    });
  }

  /**
   * Setup type toggle (single/repeat)
   */
  private setupTypeToggle(): void {
    document.querySelectorAll('#scheduleTypeOptions swp-toggle-option').forEach(option => {
      option.addEventListener('click', () => {
        document.querySelectorAll('#scheduleTypeOptions swp-toggle-option').forEach(o =>
          o.classList.remove('selected')
        );
        option.classList.add('selected');

        const isTemplate = (option as HTMLElement).dataset.value === 'template';
        const repeatGroup = document.getElementById('scheduleRepeatGroup');
        if (repeatGroup) repeatGroup.style.display = isTemplate ? 'block' : 'none';
      });
    });
  }

  /**
   * Convert slider value to time string
   */
  private valueToTime(value: number): string {
    const totalMinutes = (value * 15) + (6 * 60);
    const hours = Math.floor(totalMinutes / 60);
    const minutes = totalMinutes % 60;
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
  }

  /**
   * Convert time string to slider value
   */
  private timeToValue(timeStr: string): number {
    const [hours, minutes] = timeStr.split(':').map(Number);
    const totalMinutes = hours * 60 + minutes;
    return Math.round((totalMinutes - 6 * 60) / 15);
  }

  /**
   * Set time range slider values
   * Triggers 'input' event to let ControlsController update the display
   */
  private setTimeRange(startTime: string, endTime: string): void {
    const timeRange = document.getElementById('scheduleTimeRange');
    if (!timeRange) return;

    const startInput = timeRange.querySelector<HTMLInputElement>('.range-start');
    const endInput = timeRange.querySelector<HTMLInputElement>('.range-end');

    if (startInput) {
      startInput.value = String(this.timeToValue(startTime));
      startInput.dispatchEvent(new Event('input', { bubbles: true }));
    }
    if (endInput) {
      endInput.value = String(this.timeToValue(endTime));
      endInput.dispatchEvent(new Event('input', { bubbles: true }));
    }
  }

  /**
   * Setup time range event listener
   * ControlsController handles the slider UI; we just listen for changes
   */
  private setupTimeRangeEvents(): void {
    const timeRange = document.getElementById('scheduleTimeRange');
    timeRange?.addEventListener('timerange:change', () => {
      this.updateSelectedCellsTime();
    });
  }

  /**
   * Update selected cells with current time
   */
  private updateSelectedCellsTime(): void {
    const selectedStatus = document.querySelector('#scheduleStatusOptions swp-status-option.selected') as HTMLElement;
    const status = selectedStatus?.dataset.status || 'work';

    if (status !== 'work') return;

    const timeRange = document.getElementById('scheduleTimeRange');
    if (!timeRange) return;

    const startInput = timeRange.querySelector<HTMLInputElement>('.range-start');
    const endInput = timeRange.querySelector<HTMLInputElement>('.range-end');
    if (!startInput || !endInput) return;

    const startTime = this.valueToTime(parseInt(startInput.value));
    const endTime = this.valueToTime(parseInt(endInput.value));
    const formattedTime = `${startTime} - ${endTime}`;

    this.selectedCells.forEach(cell => {
      const timeDisplay = cell.querySelector('swp-time-badge');
      if (timeDisplay && !timeDisplay.classList.contains('off') &&
          !timeDisplay.classList.contains('vacation') &&
          !timeDisplay.classList.contains('sick')) {
        timeDisplay.textContent = formattedTime;
      }
    });
  }

  /**
   * Update selected cells with current status
   */
  private updateSelectedCellsStatus(): void {
    const selectedStatus = document.querySelector('#scheduleStatusOptions swp-status-option.selected') as HTMLElement;
    const status = selectedStatus?.dataset.status || 'work';

    const timeRange = document.getElementById('scheduleTimeRange');
    const startInput = timeRange?.querySelector<HTMLInputElement>('.range-start');
    const endInput = timeRange?.querySelector<HTMLInputElement>('.range-end');

    const startTime = startInput ? this.valueToTime(parseInt(startInput.value)) : '09:00';
    const endTime = endInput ? this.valueToTime(parseInt(endInput.value)) : '17:00';

    this.selectedCells.forEach(cell => {
      const timeDisplay = cell.querySelector('swp-time-badge');
      if (!timeDisplay) return;

      timeDisplay.classList.remove('off', 'off-override', 'vacation', 'sick');

      switch (status) {
        case 'work':
          timeDisplay.textContent = `${startTime} - ${endTime}`;
          break;
        case 'off':
          timeDisplay.classList.add('off');
          timeDisplay.textContent = '—';
          break;
        case 'vacation':
          timeDisplay.classList.add('vacation');
          timeDisplay.textContent = 'Ferie';
          break;
        case 'sick':
          timeDisplay.classList.add('sick');
          timeDisplay.textContent = 'Syg';
          break;
      }
    });
  }

  /**
   * Setup drawer save button
   */
  private setupDrawerSave(): void {
    const saveBtn = document.getElementById('scheduleDrawerSave');
    saveBtn?.addEventListener('click', () => {
      // Changes are already applied in real-time
      this.clearSelection();
      this.showEmptyState();
    });
  }

  /**
   * Open the schedule drawer (no overlay - user can still interact with table)
   */
  private openDrawer(): void {
    const container = document.querySelector('swp-tab-content[data-tab="schedule"] swp-page-container') as HTMLElement;
    const table = document.getElementById('scheduleTable');

    // Gem nuværende padding FØR klasser tilføjes
    const startPadding = container ? getComputedStyle(container).paddingRight : '0px';

    // Lås tabelbredde før drawer åbner for at undgå "hop"
    if (table) {
      const rect = table.getBoundingClientRect();
      table.style.width = `${rect.width}px`;
    }

    // Tilføj klasser med det samme (maxWidth og margin ændres instant)
    this.drawer?.classList.add('open');
    document.body.classList.add('schedule-drawer-open');

    // Animate kun padding fra gemt værdi
    if (container) {
      container.animate([
        { paddingRight: startPadding },
        { paddingRight: '420px' }
      ], {
        duration: 200,
        easing: 'ease',
        fill: 'forwards'
      });
    }
  }

  /**
   * Close the schedule drawer
   */
  private closeDrawer(): void {
    // Luk drawer med det samme (visuelt)
    this.drawer?.classList.remove('open');

    const container = document.querySelector('swp-tab-content[data-tab="schedule"] swp-page-container') as HTMLElement;
    const table = document.getElementById('scheduleTable');

    if (container) {
      const animation = container.getAnimations()[0];
      if (animation) {
        // Afspil animationen baglæns
        animation.reverse();
        animation.onfinish = () => {
          animation.cancel();
          // Fjern klasser og låst bredde når animation er færdig
          document.body.classList.remove('schedule-drawer-open');
          if (table) {
            table.style.width = '';
          }
        };
        return; // Exit early - cleanup happens in onfinish
      }
    }

    // Ingen animation, fjern klasser og låst bredde med det samme
    document.body.classList.remove('schedule-drawer-open');
    if (table) {
      table.style.width = '';
    }
  }
}

/**
 * Employee Stats Controller
 *
 * Handles the Statistics tab:
 * - Loads data from JSON
 * - Initializes charts
 * - Populates tables
 */
class EmployeeStatsController {
  private data: EmployeeStatsData | null = null;
  private dataPromise: Promise<void> | null = null;
  private chartsInitialized = false;
  private revenueUtilizationChart: ReturnType<typeof createChart> | null = null;
  private revenueChart: ReturnType<typeof createChart> | null = null;

  constructor() {
    this.setupTabListener();
  }

  /**
   * Listen for stats tab activation
   */
  private setupTabListener(): void {
    document.addEventListener('click', (e: Event) => {
      const target = e.target as HTMLElement;
      const tab = target.closest<HTMLElement>('swp-tab[data-tab="stats"]');

      if (tab) {
        this.initializeStats();
      }
    });
  }

  /**
   * Initialize stats when tab is shown
   */
  private initializeStats(): void {
    this.loadData().then(() => {
      if (!this.chartsInitialized) {
        this.populateStats();
        this.initializeCharts();
        this.populateTables();
        this.chartsInitialized = true;
      }
    });
  }

  /**
   * Load data from JSON file (cached)
   */
  private loadData(): Promise<void> {
    if (this.dataPromise) return this.dataPromise;

    this.dataPromise = (async () => {
      try {
        const response = await fetch('/data/employee-stats-data.json');
        if (!response.ok) return;
        this.data = await response.json() as EmployeeStatsData;
      } catch {
        console.error('Failed to load employee stats data');
      }
    })();

    return this.dataPromise;
  }

  /**
   * Populate stat card values
   */
  private populateStats(): void {
    if (!this.data) return;

    const { stats } = this.data;

    const bookingsEl = document.getElementById('statBookingsMonth');
    const bookedValueEl = document.getElementById('statBookedValue');
    const bookedSubtitleEl = document.getElementById('statBookedSubtitle');
    const revenueEl = document.getElementById('statRevenueMonth');
    const returnEl = document.getElementById('statReturnCustomers');

    if (bookingsEl) bookingsEl.textContent = String(stats.bookingsThisMonth);
    if (bookedValueEl) bookedValueEl.textContent = stats.bookedServicesValue;
    if (bookedSubtitleEl) bookedSubtitleEl.textContent = stats.bookedServicesSubtitle;
    if (revenueEl) revenueEl.textContent = stats.revenueThisMonth;
    if (returnEl) returnEl.textContent = stats.returnCustomers;
  }

  /**
   * Initialize charts
   */
  private initializeCharts(): void {
    if (!this.data) return;

    this.revenueUtilizationChart = this.initRevenueUtilizationChart();
    this.revenueChart = this.initRevenueChart();
  }

  /**
   * Initialize revenue & utilization chart (dual-axis: bars + lines)
   */
  private initRevenueUtilizationChart(): ReturnType<typeof createChart> | null {
    const el = document.getElementById('employeeRevenueUtilizationChart');
    if (!el || !this.data?.revenueUtilization) return null;

    const data = this.data.revenueUtilization;

    return createChart(el, {
      height: 300,
      xAxis: { categories: data.categories },
      yAxis: [
        { min: 0, max: 50000, format: (v: number) => `${(v / 1000).toFixed(0)}k` },  // Left: Revenue
        { min: 0, max: 100, format: (v: number) => `${v}%` }                         // Right: Utilization
      ],
      series: [
        // Actual revenue (solid bars)
        {
          name: 'Omsætning',
          color: '#3b82f6',
          type: 'bar',
          yAxisIndex: 0,
          unit: 'kr',
          data: data.actual.revenue,
          bar: { radius: 2 }
        },
        // Forecast revenue (transparent bars)
        {
          name: 'Omsætning (forecast)',
          color: '#3b82f6',
          type: 'bar',
          yAxisIndex: 0,
          unit: 'kr',
          data: data.forecast.revenue,
          bar: { radius: 2, opacity: 0.35 }
        },
        // Actual utilization (solid line)
        {
          name: 'Belægning',
          color: '#00897b',
          type: 'line',
          yAxisIndex: 1,
          unit: '%',
          data: data.actual.utilization,
          line: { width: 2.5 },
          point: { radius: 0 },
          showArea: false
        },
        // Forecast utilization (dashed line)
        {
          name: 'Belægning (forecast)',
          color: '#00897b',
          type: 'line',
          yAxisIndex: 1,
          unit: '%',
          data: data.forecast.utilization,
          line: { width: 2.5, dashArray: '4 4' },
          point: { radius: 0 },
          showArea: false
        }
      ],
      legend: false
    });
  }

  /**
   * Initialize revenue chart (line chart with area gradient)
   */
  private initRevenueChart(): ReturnType<typeof createChart> | null {
    const el = document.getElementById('employeeRevenueChart');
    if (!el || !this.data?.revenue) return null;

    const data = this.data.revenue;

    return createChart(el, {
      height: 200,
      xAxis: { categories: data.categories },
      yAxis: { format: (v: number) => `${(v / 1000).toFixed(0)}k` },
      series: data.series.map(s => ({
        name: s.name,
        color: s.color,
        data: s.data,
        showArea: true,
        area: { gradient: { startOpacity: 0.3, endOpacity: 0.05 } }
      })),
      legend: false
    });
  }

  /**
   * Populate tables with data
   */
  private populateTables(): void {
    if (!this.data) return;

    this.populateRecentBookings();
    this.populateCompletedBookings();
  }

  /**
   * Populate recent bookings table
   */
  private populateRecentBookings(): void {
    if (!this.data) return;

    const table = document.getElementById('recentBookingsTable');
    if (!table) return;

    // Remove existing rows (keep header)
    const existingRows = table.querySelectorAll('swp-data-table-row');
    existingRows.forEach(row => row.remove());

    // Add new rows
    this.data.recentBookings.forEach(booking => {
      const row = document.createElement('swp-data-table-row');
      row.innerHTML = `
        <swp-data-table-cell>${booking.customer}</swp-data-table-cell>
        <swp-data-table-cell>${booking.service}</swp-data-table-cell>
        <swp-data-table-cell>${booking.date}</swp-data-table-cell>
        <swp-data-table-cell>${booking.amount}</swp-data-table-cell>
      `;
      table.appendChild(row);
    });
  }

  /**
   * Populate completed bookings table
   */
  private populateCompletedBookings(): void {
    if (!this.data) return;

    const table = document.getElementById('completedBookingsTable');
    if (!table) return;

    // Remove existing rows (keep header)
    const existingRows = table.querySelectorAll('swp-data-table-row');
    existingRows.forEach(row => row.remove());

    // Add new rows
    this.data.completedBookings.forEach(booking => {
      const row = document.createElement('swp-data-table-row');
      row.innerHTML = `
        <swp-data-table-cell>${booking.date}</swp-data-table-cell>
        <swp-data-table-cell>${booking.time}</swp-data-table-cell>
        <swp-data-table-cell>${booking.customer}</swp-data-table-cell>
        <swp-data-table-cell>${booking.services}</swp-data-table-cell>
        <swp-data-table-cell>${booking.duration}</swp-data-table-cell>
        <swp-data-table-cell>${booking.amount}</swp-data-table-cell>
        <swp-data-table-cell>
          <swp-status-badge class="${booking.statusClass}">${booking.status}</swp-status-badge>
        </swp-data-table-cell>
      `;
      table.appendChild(row);
    });
  }
}
