import { gregorianToJalali, JALALI_DATE_FORMATS, jalaliToGregorian, nowJalali } from '@/utils';
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, OnInit, Output, signal } from '@angular/core';
import { Button, ButtonSeverity } from 'primeng/button';
import { SeasonPickerDialogComponent } from './season-picker-dialog.component';

type SeasonKey = 0 | 1 | 2 | 3;

interface SeasonItem {
  key: SeasonKey;
  label: string;
  severity: ButtonSeverity;
}

@Component({
  selector: 'season-picker',
  templateUrl: 'season-picker.component.html',
  imports: [CommonModule, Button, SeasonPickerDialogComponent],
})
export class SeasonPickerComponent implements OnInit {
  @Input() minYear = 1390;
  @Input() maxYear = Number(nowJalali(JALALI_DATE_FORMATS.YEAR));
  @Input() value!: Date;

  @Output() onChange = new EventEmitter<Date>();

  readonly isOpen = signal(false);
  readonly selectedYear = signal(Number(nowJalali(JALALI_DATE_FORMATS.YEAR)));
  readonly selectedSeason = signal<SeasonKey>(0);

  readonly seasons: SeasonItem[] = [
    { key: 0, label: 'بهار', severity: 'success' },
    { key: 1, label: 'تابستان', severity: 'danger' },
    { key: 2, label: 'پاییز', severity: 'warn' },
    { key: 3, label: 'زمستان', severity: 'info' },
  ];

  readonly years = signal<{ year: number; value: number }[]>([]);

  ngOnInit(): void {
    const year = Number(gregorianToJalali(this.value, JALALI_DATE_FORMATS.YEAR));
    const monthIndex = Number(gregorianToJalali(this.value, JALALI_DATE_FORMATS.MONTH)) - 1;
    const season = Math.floor(monthIndex / 3) as SeasonKey;

    this.selectedYear.set(year);
    this.selectedSeason.set(season);
    this.years.set(
      Array.from({ length: this.maxYear - this.minYear + 1 }, (_, i) => ({
        year: this.minYear + i,
        value: this.minYear + i,
      }))
    );
    this.emitValue();
  }

  currentSeason(): string {
    const season = this.seasons.find((item) => item.key === this.selectedSeason());
    return `${season?.label ?? ''} ${this.selectedYear()}`;
  }

  openPicker(): void {
    this.isOpen.set(true);
  }

  closePicker(): void {
    this.isOpen.set(false);
  }

  prevSeason(): void {
    const index = this.selectedSeason();
    const currentYear = this.selectedYear();
    const nextSeason = index === 0 ? 3 : ((index - 1) as SeasonKey);
    const nextYear = index === 0 ? currentYear - 1 : currentYear;

    // if (!this.isWithinBounds(nextYear, nextSeason)) return;

    this.selectedYear.set(nextYear);
    this.selectedSeason.set(nextSeason);
    this.emitValue();
  }

  nextSeason(): void {
    const index = this.selectedSeason();
    const currentYear = this.selectedYear();
    const nextSeason = index === 3 ? 0 : ((index + 1) as SeasonKey);
    const nextYear = index === 3 ? currentYear + 1 : currentYear;

    this.selectedYear.set(nextYear);
    this.selectedSeason.set(nextSeason);
    this.emitValue();
  }

  submitPicker(value: { year: number; season: number }): void {
    this.selectedYear.set(value.year);
    this.selectedSeason.set(value.season as SeasonKey);
    this.emitValue();
  }

  private isWithinBounds(year: number, season: SeasonKey): boolean {
    if (year < this.minYear || year > this.maxYear) return false;
    // if (year === this.minYear && season < this.minSeason) return false;
    // if (year === this.maxYear && season > this.maxSeason) return false;
    return true;
  }

  private emitValue(): void {
    this.onChange.emit(
      new Date(
        jalaliToGregorian(
          `${this.selectedYear()}/${(this.selectedSeason() * 3 + 1).toString().padStart(2, '0')}/01`
        )
      )
    );
  }
}
