import { Component, EventEmitter, Input, Output } from '@angular/core';
import { DateTime } from 'luxon';

const WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

@Component({
  selector: 'calendar-date-calendar',
  standalone: true,
  template: `
    <div class="calendar-nav">
      <button type="button" class="nav-btn" (click)="prevMonth()" aria-label="Previous month">
        ‹
      </button>
      <span class="month">{{ monthLabel }}</span>
      <button type="button" class="nav-btn" (click)="nextMonth()" aria-label="Next month">
        ›
      </button>
    </div>
    <div class="weekdays">
      @for (wd of weekdays; track wd) {
        <span class="weekday">{{ wd }}</span>
      }
    </div>
    <div class="grid">
      @for (day of days; track day.date) {
        <button
          type="button"
          class="day"
          [class.selected]="day.date === selectedDate"
          [class.other]="!day.inMonth"
          [disabled]="day.disabled"
          (click)="select(day.date)"
        >
          {{ day.label }}
        </button>
      }
    </div>
  `,
  styles: [
    `
      .calendar-nav {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 1rem;
      }
      .month {
        font-weight: 600;
        font-size: 1rem;
      }
      .nav-btn {
        width: 36px;
        height: 36px;
        border: 1px solid var(--cal-border, #e2e8f0);
        border-radius: 10px;
        background: var(--cal-surface, #fff);
        font-size: 1.25rem;
        line-height: 1;
        cursor: pointer;
        color: var(--cal-text, #0f172a);
      }
      .nav-btn:hover {
        background: var(--cal-brand-soft, #eef2ff);
        border-color: var(--cal-brand, #4f46e5);
        color: var(--cal-brand, #4f46e5);
      }
      .weekdays {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        gap: 4px;
        margin-bottom: 4px;
      }
      .weekday {
        text-align: center;
        font-size: 0.7rem;
        font-weight: 600;
        color: var(--cal-text-muted, #64748b);
        text-transform: uppercase;
        letter-spacing: 0.04em;
      }
      .grid {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        gap: 4px;
      }
      .day {
        aspect-ratio: 1;
        border: 1px solid transparent;
        background: transparent;
        border-radius: 10px;
        font-size: 0.875rem;
        font-weight: 500;
        cursor: pointer;
        color: var(--cal-text, #0f172a);
      }
      .day:hover:not(:disabled) {
        background: var(--cal-brand-soft, #eef2ff);
        color: var(--cal-brand, #4f46e5);
      }
      .day.selected {
        background: var(--cal-brand, #4f46e5);
        color: #fff;
        font-weight: 600;
      }
      .day.other {
        color: var(--cal-text-muted, #64748b);
        opacity: 0.45;
      }
      .day:disabled {
        opacity: 0.25;
        cursor: not-allowed;
      }
    `,
  ],
})
export class DateCalendarComponent {
  @Input() selectedDate: string | null = null;
  @Input() availableDates: string[] = [];
  @Output() dateChange = new EventEmitter<string>();

  weekdays = WEEKDAYS;
  viewMonth = DateTime.local().startOf('month');

  get monthLabel(): string {
    return this.viewMonth.toFormat('MMMM yyyy');
  }

  get days() {
    // Luxon startOf('week') is Monday; WEEKDAYS headers are Sunday-first.
    // Align the grid to Sunday so dates sit under the correct weekday labels.
    const start = this.viewMonth.minus({ days: this.viewMonth.weekday % 7 });
    return Array.from({ length: 42 }, (_, i) => {
      const dt = start.plus({ days: i });
      const date = dt.toFormat('yyyy-MM-dd');
      const today = DateTime.local().startOf('day');
      return {
        date,
        label: dt.day,
        inMonth: dt.month === this.viewMonth.month,
        disabled:
          dt < today ||
          (this.availableDates.length > 0 && !this.availableDates.includes(date)),
      };
    });
  }

  prevMonth(): void {
    this.viewMonth = this.viewMonth.minus({ months: 1 });
  }

  nextMonth(): void {
    this.viewMonth = this.viewMonth.plus({ months: 1 });
  }

  select(date: string): void {
    this.dateChange.emit(date);
  }
}
