import {Component, computed, inject, OnInit, signal} from '@angular/core';
import {CommonModule} from '@angular/common';
import {MatTableModule} from '@angular/material/table';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatSortModule, Sort} from '@angular/material/sort';
import {SiteService, StaffPlaytime} from '@api';
import {HeaderComponent} from '@header/header.component';

@Component({
  selector: 'app-staff-pt',
  standalone: true,
  imports: [CommonModule, MatTableModule, MatButtonModule, MatIconModule, MatTooltipModule, MatSortModule, HeaderComponent],
  templateUrl: './staff-pt.component.html',
  styleUrl: './staff-pt.component.scss'
})
export class StaffPtComponent implements OnInit {
  siteService = inject(SiteService);

  staffPt = signal<StaffPlaytime[]>([]);
  sort = signal<Sort>({active: 'playtime', direction: 'desc'} as Sort);
  sortedStaffPt = computed<StaffPlaytime[]>(() => {
    const data = [...this.staffPt()];
    const {active, direction} = this.sort();
    if (!direction || !active) return data;
    const dir = direction === 'asc' ? 1 : -1;
    return data.sort((a, b) => {
      switch (active) {
        case 'staff_member':
          return a.staff_member.localeCompare(b.staff_member) * dir;
        case 'role':
          return a.role.localeCompare(b.role) * dir;
        case 'playtime':
        default:
          return ((a.playtime ?? 0) - (b.playtime ?? 0)) * dir;
      }
    });
  });

  weekStart = signal<Date>(this.getStartOfWeek(new Date()));
  weekEnd = computed(() => this.getEndOfWeek(this.weekStart()));

  todayStart = signal<Date>(this.startOfDay(new Date()));

  displayedColumns = ['staff_member', 'playtime', 'role'];

  ngOnInit(): void {
    this.loadCurrentWeek();
  }

  private loadCurrentWeek() {
    this.loadStaffData(this.weekStart(), this.weekEnd());
  }

  prevWeek() {
    const prev = new Date(this.weekStart());
    prev.setDate(prev.getDate() - 7);
    prev.setHours(0, 0, 0, 0);
    this.weekStart.set(prev);
    this.loadCurrentWeek();
  }

  nextWeek() {
    if (!this.canGoNextWeek()) return;
    const next = new Date(this.weekStart());
    next.setDate(next.getDate() + 7);
    next.setHours(0, 0, 0, 0);
    this.weekStart.set(next);
    this.loadCurrentWeek();
  }

  canGoNextWeek(): boolean {
    const nextWeekStart = new Date(this.weekStart());
    nextWeekStart.setDate(nextWeekStart.getDate() + 7);
    nextWeekStart.setHours(0, 0, 0, 0);
    return nextWeekStart.getTime() <= this.todayStart().getTime();
  }

  weekLabel(): string {
    const start = this.weekStart();
    const end = this.weekEnd();

    const startFmt = start.toLocaleDateString(undefined, {month: 'short', day: 'numeric'});
    const endFmt = end.toLocaleDateString(undefined, {month: 'short', day: 'numeric'});
    const year = end.getFullYear();
    return `Week ${startFmt} – ${endFmt}, ${year}`;
  }

  minutesToHm(mins?: number): string {
    if (mins == null) return '';
    const d = Math.floor(mins / 1440);
    const h = Math.floor((mins % 1440) / 60);
    const m = mins % 60;
    const parts = [];
    if (d > 0) {
      parts.push(`${d}d`);
    }
    if (h > 0 || d > 0) {
      parts.push(`${h}h`);
    }
    if (m > 0 || (h === 0 && d === 0)) {
      parts.push(`${m}m`);
    }
    return parts.join(' ');
  }

  private loadStaffData(from: Date, to: Date) {
    const fromUtc = new Date(from.getTime() - from.getTimezoneOffset() * 60000);
    const toUtc = new Date(to.getTime() - to.getTimezoneOffset() * 60000);

    this.siteService.getStaffPlaytime(fromUtc.toISOString(), toUtc.toISOString())
      .subscribe({
        next: data => this.staffPt.set(data ?? []),
        error: err => console.error('Error getting staff playtime:', err)
      });
  }

  private getStartOfWeek(date: Date): Date {
    const d = new Date(date);
    d.setDate(d.getDate() - d.getDay()); // Sunday start
    d.setHours(0, 0, 0, 0);
    return d;
  }

  private getEndOfWeek(start: Date): Date {
    const d = new Date(start);
    d.setDate(start.getDate() + 6);
    d.setHours(23, 59, 59, 999);
    return d;
  }

  private startOfDay(date: Date): Date {
    const d = new Date(date);
    d.setHours(0, 0, 0, 0);
    return d;
  }
}
