/**
 * Kasse Controller
 *
 * Handles tab switching, cash calculations, and form interactions
 * for the Kasse (Cash Register) page.
 */

export class KasseController {
  // Base values (from system - would come from server in real app)
  private readonly startBalance = 2000;
  private readonly cashSales = 3540;

  constructor() {
    this.setupTabs();
    this.setupCashCalculation();
    this.setupCheckboxSelection();
    this.setupApprovalCheckbox();
    this.setupDateFilters();
    this.setupRowToggle();
    this.setupDraftRowClick();
  }

  /**
   * Setup tab switching functionality
   */
  private setupTabs(): void {
    const tabs = document.querySelectorAll<HTMLElement>('swp-tab[data-tab]');

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

  /**
   * Switch to a specific tab by name
   */
  private switchToTab(targetTab: string): void {
    const tabs = document.querySelectorAll<HTMLElement>('swp-tab[data-tab]');
    const contents = document.querySelectorAll<HTMLElement>('swp-tab-content[data-tab]');
    const statsBars = document.querySelectorAll<HTMLElement>('swp-kasse-stats[data-for-tab]');

    // Update tab states
    tabs.forEach(t => {
      if (t.dataset.tab === targetTab) {
        t.classList.add('active');
      } else {
        t.classList.remove('active');
      }
    });

    // Update content visibility
    contents.forEach(content => {
      if (content.dataset.tab === targetTab) {
        content.classList.add('active');
      } else {
        content.classList.remove('active');
      }
    });

    // Update stats bar visibility
    statsBars.forEach(stats => {
      if (stats.dataset.forTab === targetTab) {
        stats.classList.add('active');
      } else {
        stats.classList.remove('active');
      }
    });
  }

  /**
   * Setup cash calculation with real-time updates
   */
  private setupCashCalculation(): void {
    const payoutsInput = document.getElementById('payouts') as HTMLInputElement;
    const toBankInput = document.getElementById('toBank') as HTMLInputElement;
    const actualCashInput = document.getElementById('actualCash') as HTMLInputElement;

    if (!payoutsInput || !toBankInput || !actualCashInput) return;

    const calculate = () => this.calculateCash(payoutsInput, toBankInput, actualCashInput);

    payoutsInput.addEventListener('input', calculate);
    toBankInput.addEventListener('input', calculate);
    actualCashInput.addEventListener('input', calculate);

    // Initial calculation
    calculate();
  }

  /**
   * Calculate expected cash and difference
   */
  private calculateCash(
    payoutsInput: HTMLInputElement,
    toBankInput: HTMLInputElement,
    actualCashInput: HTMLInputElement
  ): void {
    const payouts = this.parseNumber(payoutsInput.value);
    const toBank = this.parseNumber(toBankInput.value);
    const actual = this.parseNumber(actualCashInput.value);

    // Expected = start + sales - payouts - to bank
    const expectedCash = this.startBalance + this.cashSales - payouts - toBank;

    const expectedElement = document.getElementById('expectedCash');
    if (expectedElement) {
      expectedElement.textContent = this.formatNumber(expectedCash);
    }

    // Calculate and display difference
    this.updateDifference(actual, expectedCash, actualCashInput.value);
  }

  /**
   * Update difference box with color coding
   */
  private updateDifference(actual: number, expected: number, rawValue: string): void {
    const box = document.getElementById('differenceBox');
    const value = document.getElementById('differenceValue');
    if (!box || !value) return;

    const diff = actual - expected;

    // Remove all state classes
    box.classList.remove('positive', 'negative', 'neutral');

    if (actual === 0 && rawValue === '') {
      // No input yet
      value.textContent = '– kr';
      box.classList.add('neutral');
    } else if (diff > 0) {
      // More cash than expected
      value.textContent = '+' + this.formatNumber(diff) + ' kr';
      box.classList.add('positive');
    } else if (diff < 0) {
      // Less cash than expected
      value.textContent = this.formatNumber(diff) + ' kr';
      box.classList.add('negative');
    } else {
      // Exact match
      value.textContent = '0,00 kr';
      box.classList.add('neutral');
    }
  }

  /**
   * Setup checkbox selection for table rows
   */
  private setupCheckboxSelection(): void {
    const selectAll = document.getElementById('selectAll') as HTMLInputElement;
    const rowCheckboxes = document.querySelectorAll<HTMLInputElement>('.row-select');
    const exportBtn = document.getElementById('exportBtn') as HTMLButtonElement;
    const selectionCount = document.getElementById('selectionCount');

    if (!selectAll || !exportBtn || !selectionCount) return;

    const updateSelection = () => {
      const checked = document.querySelectorAll<HTMLInputElement>('.row-select:checked');
      const count = checked.length;

      selectionCount.textContent = count === 0 ? '0 valgt' : `${count} valgt`;
      exportBtn.disabled = count === 0;

      // Update select all state
      selectAll.checked = count === rowCheckboxes.length && count > 0;
      selectAll.indeterminate = count > 0 && count < rowCheckboxes.length;
    };

    selectAll.addEventListener('change', () => {
      rowCheckboxes.forEach(cb => cb.checked = selectAll.checked);
      updateSelection();
    });

    rowCheckboxes.forEach(cb => {
      cb.addEventListener('change', updateSelection);
      // Stop click from bubbling to row
      cb.addEventListener('click', e => e.stopPropagation());
    });
  }

  /**
   * Setup approval checkbox to enable/disable approve button
   */
  private setupApprovalCheckbox(): void {
    const checkbox = document.getElementById('confirmCheckbox') as HTMLInputElement;
    const approveBtn = document.getElementById('approveBtn') as HTMLButtonElement;

    if (!checkbox || !approveBtn) return;

    checkbox.addEventListener('change', () => {
      approveBtn.disabled = !checkbox.checked;
    });
  }

  /**
   * Setup date filter defaults (last 30 days)
   */
  private setupDateFilters(): void {
    const dateFrom = document.getElementById('dateFrom') as HTMLInputElement;
    const dateTo = document.getElementById('dateTo') as HTMLInputElement;

    if (!dateFrom || !dateTo) return;

    const today = new Date();
    const thirtyDaysAgo = new Date(today);
    thirtyDaysAgo.setDate(today.getDate() - 30);

    dateTo.value = this.formatDateISO(today);
    dateFrom.value = this.formatDateISO(thirtyDaysAgo);
  }

  /**
   * Format number as Danish currency
   */
  private formatNumber(num: number): string {
    return num.toLocaleString('da-DK', {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
  }

  /**
   * Parse Danish number format
   */
  private parseNumber(str: string): number {
    if (!str) return 0;
    return parseFloat(str.replace(/\./g, '').replace(',', '.')) || 0;
  }

  /**
   * Format date as ISO string (YYYY-MM-DD)
   */
  private formatDateISO(date: Date): string {
    return date.toISOString().split('T')[0];
  }

  /**
   * Setup row toggle for expandable details
   */
  private setupRowToggle(): void {
    const rows = document.querySelectorAll<HTMLElement>('swp-kasse-table-row[data-id]:not(.draft-row)');

    rows.forEach(row => {
      const rowId = row.getAttribute('data-id');
      if (!rowId) return;

      const detail = document.querySelector<HTMLElement>(`swp-kasse-row-detail[data-for="${rowId}"]`);
      if (!detail) return;

      row.addEventListener('click', (e) => {
        // Don't toggle if clicking on checkbox
        if ((e.target as HTMLElement).closest('input[type="checkbox"]')) return;

        const icon = row.querySelector('swp-row-toggle i');
        const isExpanded = row.classList.contains('expanded');

        // Close other expanded rows
        document.querySelectorAll('swp-kasse-table-row.expanded').forEach(r => {
          if (r !== row) {
            const otherId = r.getAttribute('data-id');
            if (otherId) {
              const otherDetail = document.querySelector<HTMLElement>(`swp-kasse-row-detail[data-for="${otherId}"]`);
              const otherIcon = r.querySelector('swp-row-toggle i');
              if (otherDetail && otherIcon) {
                this.collapseRow(r, otherDetail, otherIcon as HTMLElement);
              }
            }
          }
        });

        // Toggle current row
        if (isExpanded) {
          this.collapseRow(row, detail, icon);
        } else {
          this.expandRow(row, detail, icon);
        }
      });
    });
  }

  /**
   * Expand a row with animation
   */
  private expandRow(row: Element, detail: HTMLElement, icon: Element | null): void {
    row.classList.add('expanded');
    detail.classList.add('expanded');

    // Animate icon rotation
    icon?.animate([
      { transform: 'rotate(0deg)' },
      { transform: 'rotate(90deg)' }
    ], {
      duration: 200,
      easing: 'ease-out',
      fill: 'forwards'
    });

    // Animate detail expansion
    const content = detail.querySelector('swp-row-detail-content') as HTMLElement;
    if (content) {
      const height = content.offsetHeight;
      detail.animate([
        { height: '0px', opacity: 0 },
        { height: `${height}px`, opacity: 1 }
      ], {
        duration: 250,
        easing: 'ease-out',
        fill: 'forwards'
      });
    }
  }

  /**
   * Collapse a row with animation
   */
  private collapseRow(row: Element, detail: HTMLElement, icon: Element | null): void {
    // Animate icon rotation
    icon?.animate([
      { transform: 'rotate(90deg)' },
      { transform: 'rotate(0deg)' }
    ], {
      duration: 200,
      easing: 'ease-out',
      fill: 'forwards'
    });

    // Animate detail collapse
    const content = detail.querySelector('swp-row-detail-content') as HTMLElement;
    if (content) {
      const height = content.offsetHeight;
      const animation = detail.animate([
        { height: `${height}px`, opacity: 1 },
        { height: '0px', opacity: 0 }
      ], {
        duration: 200,
        easing: 'ease-out',
        fill: 'forwards'
      });

      animation.onfinish = () => {
        row.classList.remove('expanded');
        detail.classList.remove('expanded');
      };
    } else {
      row.classList.remove('expanded');
      detail.classList.remove('expanded');
    }
  }

  /**
   * Setup draft row click to navigate to Kasseafstemning tab
   */
  private setupDraftRowClick(): void {
    const draftRow = document.querySelector<HTMLElement>('swp-kasse-table-row.draft-row');
    if (!draftRow) return;

    draftRow.style.cursor = 'pointer';
    draftRow.addEventListener('click', (e) => {
      // Don't navigate if clicking on checkbox
      if ((e.target as HTMLElement).closest('input[type="checkbox"]')) return;

      this.switchToTab('afstemning');
    });
  }
}
