import { IndexedDBContext } from '../storage/IndexedDBContext';
import { DataSeeder } from '../workers/DataSeeder';
import { AuditService } from '../storage/audit/AuditService';
import { CalendarApp } from '../core/CalendarApp';
import { DateService } from '../core/DateService';
import { ResourceService } from '../storage/resources/ResourceService';
import { IEventBus } from '../types/CalendarTypes';
import { CalendarEvents } from '../core/CalendarEvents';

export class DemoApp {
  private container!: HTMLElement;
  private currentView = 'simple';

  constructor(
    private indexedDBContext: IndexedDBContext,
    private dataSeeder: DataSeeder,
    private auditService: AuditService,
    private calendarApp: CalendarApp,
    private dateService: DateService,
    private resourceService: ResourceService,
    private eventBus: IEventBus
  ) {}

  async init(): Promise<void> {
    // Set base date to match mock data (8. december 2025 = mandag)
    this.dateService.setBaseDate(new Date('2025-12-08'));

    // Initialize IndexedDB
    await this.indexedDBContext.initialize();
    console.log('[DemoApp] IndexedDB initialized');

    // Seed data if empty
    await this.dataSeeder.seedIfEmpty();
    console.log('[DemoApp] Data seeding complete');

    this.container = document.querySelector('swp-calendar-container') as HTMLElement;

    // Initialize CalendarApp
    await this.calendarApp.init(this.container);
    console.log('[DemoApp] CalendarApp initialized');

    // Setup demo UI handlers
    this.setupNavigation();
    this.setupDrawerToggle();
    this.setupViewSwitching();
    this.setupWorkweekSelector();
    await this.setupResourceSelector();

    // Listen for calendar status events
    this.setupStatusListeners();

    // Initial render
    this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: this.currentView });
  }

  private setupNavigation(): void {
    document.getElementById('btn-prev')!.onclick = () => {
      this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_PREV);
    };

    document.getElementById('btn-next')!.onclick = () => {
      this.eventBus.emit(CalendarEvents.CMD_NAVIGATE_NEXT);
    };
  }

  private setupViewSwitching(): void {
    const chips = document.querySelectorAll('.view-chip');
    chips.forEach(chip => {
      chip.addEventListener('click', () => {
        chips.forEach(c => c.classList.remove('active'));
        chip.classList.add('active');

        const view = (chip as HTMLElement).dataset.view;
        if (view) {
          this.currentView = view;
          this.updateSelectorVisibility();
          this.eventBus.emit(CalendarEvents.CMD_RENDER, { viewId: view });
        }
      });
    });
  }

  private updateSelectorVisibility(): void {
    const selector = document.querySelector('swp-resource-selector');
    const showSelector = this.currentView === 'picker' || this.currentView === 'day';
    selector?.classList.toggle('hidden', !showSelector);
  }

  private setupDrawerToggle(): void {
    document.getElementById('btn-drawer')!.onclick = () => {
      this.eventBus.emit(CalendarEvents.CMD_DRAWER_TOGGLE);
    };
  }

  private setupWorkweekSelector(): void {
    const workweekSelect = document.getElementById('workweek-select') as HTMLSelectElement;
    workweekSelect?.addEventListener('change', () => {
      const presetId = workweekSelect.value;
      this.eventBus.emit(CalendarEvents.CMD_WORKWEEK_CHANGE, { presetId });
    });
  }

  private async setupResourceSelector(): Promise<void> {
    const resources = await this.resourceService.getAll();
    const container = document.querySelector('.resource-checkboxes') as HTMLElement;
    if (!container) return;

    container.innerHTML = '';

    resources.forEach(r => {
      const label = document.createElement('label');
      label.innerHTML = `
        <input type="checkbox" value="${r.id}" checked>
        ${r.displayName}
      `;
      container.appendChild(label);
    });

    container.addEventListener('change', () => {
      const checked = container.querySelectorAll('input:checked') as NodeListOf<HTMLInputElement>;
      const values = Array.from(checked).map(cb => cb.value);
      this.eventBus.emit(CalendarEvents.CMD_VIEW_UPDATE, { type: 'resource', values });
    });
  }

  private setupStatusListeners(): void {
    this.container.addEventListener('calendar:status:ready', () => {
      console.log('[DemoApp] Calendar ready');
    });

    this.container.addEventListener('calendar:status:rendered', ((e: CustomEvent) => {
      console.log('[DemoApp] Calendar rendered:', e.detail.viewId);
    }) as EventListener);

    this.container.addEventListener('calendar:status:error', ((e: CustomEvent) => {
      console.error('[DemoApp] Calendar error:', e.detail.message);
    }) as EventListener);
  }

}
