import { Component, computed, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { ApiService } from '../../core/api.service';
import { LangService } from '../../core/lang.service';
import { WizardStateService } from '../../core/wizard-state.service';

interface Opt { value: string; ar: string; en: string; }

@Component({
  selector: 'app-wizard',
  standalone: true,
  imports: [FormsModule],
  template: `
    <section class="wizard">
      <div class="container">
        <div class="steps-bar">
          <div class="steps">
            @for (s of [1,2,3,4,5]; track s) {
              <i [class.on]="s <= step()"></i>
            }
          </div>
          <span class="step-label muted">{{ stepLabel() }}</span>
        </div>

        <div class="card panel fade-in" [attr.key]="step()">
          <!-- 1 — Event -->
          @if (step() === 1) {
            <h2>{{ lang.t('q_event_type') }}</h2>
            <div class="chips">
              @for (o of eventTypes; track o.value) {
                <div class="chip" [class.chip--on]="eventType() === o.value" (click)="eventType.set(o.value)">
                  {{ lang.lang() === 'ar' ? o.ar : o.en }}
                </div>
              }
            </div>
            <div class="field q-gap">
              <label>{{ lang.t('q_attendees') }}</label>
              <input type="number" min="0" [(ngModel)] = "attendees" placeholder="250" />
            </div>
          }

          <!-- 2 — F&B -->
          @if (step() === 2) {
            <h2>{{ lang.t('q_fnb') }}</h2>
            <div class="chips chips--col">
              @for (o of fnbLevels; track o.value) {
                <div class="chip" [class.chip--on]="fnbLevel() === o.value" (click)="fnbLevel.set(o.value)">
                  {{ lang.lang() === 'ar' ? o.ar : o.en }}
                </div>
              }
            </div>
          }

          <!-- 3 — Venue style -->
          @if (step() === 3) {
            <h2>{{ lang.t('q_venue') }}</h2>
            <div class="chips">
              @for (o of venueTypes; track o.value) {
                <div class="chip" [class.chip--on]="venuePref() === o.value" (click)="venuePref.set(o.value)">
                  {{ lang.lang() === 'ar' ? o.ar : o.en }}
                </div>
              }
            </div>
          }

          <!-- 4 — Budget & date -->
          @if (step() === 4) {
            <h2>{{ lang.t('step_budget') }}</h2>
            <label class="grp-label">{{ lang.t('q_budget') }}</label>
            <div class="row">
              <div class="field grow">
                <label>{{ lang.t('budget_from') }}</label>
                <input type="number" min="0" step="1000" [(ngModel)]="budgetMin" placeholder="150000" />
              </div>
              <div class="field grow">
                <label>{{ lang.t('budget_to') }}</label>
                <input type="number" min="0" step="1000" [(ngModel)]="budgetMax" placeholder="250000" />
              </div>
            </div>

            <div class="field date-section">
              <label class="grp-label">{{ lang.t('q_date') }}</label>
              <div class="chips mode-chips">
                <div class="chip" [class.chip--on]="dateMode() === 'specific'" (click)="dateMode.set('specific')">{{ lang.t('date_specific') }}</div>
                <div class="chip" [class.chip--on]="dateMode() === 'flexible'" (click)="dateMode.set('flexible')">{{ lang.t('date_flexible') }}</div>
              </div>

              @if (dateMode() === 'specific') {
                <div class="dates-row">
                  <select [(ngModel)]="selDay" class="sel"><option [ngValue]="null">{{ lang.t('sel_day') }}</option>@for (d of days; track d) {<option [ngValue]="d">{{ d }}</option>}</select>
                  <select [(ngModel)]="selMonth" class="sel"><option [ngValue]="null">{{ lang.t('sel_month') }}</option>@for (m of months; track m.n) {<option [ngValue]="m.n" [disabled]="monthDisabled(m.n, selYear)">{{ lang.lang() === 'ar' ? m.ar : m.en }}</option>}</select>
                  <select [(ngModel)]="selYear" class="sel"><option [ngValue]="null">{{ lang.t('sel_year') }}</option>@for (y of years; track y) {<option [ngValue]="y">{{ y }}</option>}</select>
                  <button class="btn btn--ghost btn--sm" (click)="addDate()" [disabled]="!specificValid()">+ {{ lang.t('add_date') }}</button>
                </div>
                @if (specificPast()) {
                  <p class="muted hint err">{{ lang.t('past_date') }}</p>
                } @else if (dates().length) {
                  <div class="chips date-chips">
                    @for (d of dates(); track d) {
                      <span class="chip chip--on date-chip">{{ prettyDate(d) }} <i class="x" (click)="removeDate(d)">×</i></span>
                    }
                  </div>
                } @else {
                  <p class="muted hint">{{ lang.t('add_dates_hint') }}</p>
                }
              } @else {
                <div class="dates-row">
                  <select [(ngModel)]="flexMonthNum" class="sel"><option [ngValue]="null">{{ lang.t('sel_month') }}</option>@for (m of months; track m.n) {<option [ngValue]="m.n" [disabled]="monthDisabled(m.n, flexYear)">{{ lang.lang() === 'ar' ? m.ar : m.en }}</option>}</select>
                  <select [(ngModel)]="flexYear" class="sel"><option [ngValue]="null">{{ lang.t('sel_year') }}</option>@for (y of years; track y) {<option [ngValue]="y">{{ y }}</option>}</select>
                </div>
                <p class="muted hint">{{ lang.t('flex_hint') }}</p>
              }
            </div>
          }

          <!-- 5 — Contact -->
          @if (step() === 5) {
            <h2>{{ lang.t('q_contact') }}</h2>
            <div class="field">
              <label>{{ lang.t('f_name') }}</label>
              <input type="text" [(ngModel)]="name" />
            </div>
            <div class="row">
              <div class="field grow">
                <label>{{ lang.t('f_phone') }}</label>
                <input type="tel" [ngModel]="phone()" (ngModelChange)="phone.set($event)" placeholder="010…" />
              </div>
              <div class="field grow">
                <label>{{ lang.t('f_email') }}</label>
                <input type="email" [(ngModel)]="email" />
              </div>
            </div>
            <label class="wa-check">
              <input type="checkbox" [checked]="waSame()" (change)="waSame.set($any($event.target).checked)" />
              <span>{{ lang.t('wa_same') }}</span>
            </label>
            @if (!waSame()) {
              <div class="field">
                <label>{{ lang.t('wa_number') }}</label>
                <input type="tel" [(ngModel)]="waPhone" placeholder="010…" />
              </div>
            }
          }

          <div class="nav">
            @if (step() > 1) {
              <button class="btn btn--ghost" (click)="back()" [disabled]="busy()">{{ lang.t('back') }}</button>
            } @else { <span></span> }

            @if (step() < 5) {
              <button class="btn" (click)="next()" [disabled]="busy() || !canNext()">{{ lang.t('next') }}</button>
            } @else {
              <button class="btn btn--gold" (click)="finish()" [disabled]="busy() || !phone()">{{ lang.t('see_matches') }}</button>
            }
          </div>
        </div>
      </div>
    </section>
  `,
  styles: [`
    .wizard { padding: 48px 0 80px; min-height: calc(100vh - 72px); }
    .steps-bar { display: flex; align-items: center; gap: 16px; margin-bottom: 22px; }
    .step-label { font-weight: 600; }
    .panel { padding: 40px; max-width: 720px; margin: 0 auto; }
    .panel h2 { margin-bottom: 24px; }
    .wa-check { display: flex; align-items: center; gap: 9px; margin: 14px 2px 4px; cursor: pointer; font-size: .92rem; color: var(--ink, #2b241d); }
    .wa-check input { width: 17px; height: 17px; accent-color: var(--gold, #c5a44f); }
    .chips--col { flex-direction: column; }
    .chips--col .chip { width: 100%; }
    .q-gap { margin-top: 28px; }
    .date-section { margin-top: 28px; }
    .mode-chips { margin-bottom: 16px; }
    .mode-chips .chip { font-size: .9rem; padding: 10px 18px; }
    .grp-label { display: block; font-weight: 600; font-size: .95rem; margin-bottom: 12px; color: var(--ink); }
    .dates-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
    .dates-row .sel { flex: 1 1 110px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-sm);
      background: var(--cream); font-family: inherit; font-size: 1rem; color: var(--ink); }
    .dates-row .sel:focus { outline: none; border-color: var(--gold); background: #fff; }
    .date-chips { margin-top: 16px; }
    .date-chip { display: inline-flex; align-items: center; gap: 9px; }
    .date-chip .x { cursor: pointer; font-style: normal; font-weight: 700; line-height: 1; opacity: .85; }
    .date-chip .x:hover { opacity: 1; }
    .hint { margin-top: 12px; font-size: .9rem; }
    .hint.err { color: var(--danger); }
    .nav { display: flex; justify-content: space-between; align-items: center; margin-top: 34px; gap: 12px; }
    @media (max-width: 560px) { .panel { padding: 26px 20px; } }
  `],
})
export class WizardComponent {
  lang = inject(LangService);
  private api = inject(ApiService);
  private state = inject(WizardStateService);
  private router = inject(Router);

  step = signal(1);
  busy = signal(false);

  eventType = signal('');
  attendees: number | null = null;
  fnbLevel = signal('');
  venuePref = signal('');
  budgetMin: number | null = null;
  budgetMax: number | null = null;

  // Date step: specific multi-dates OR a flexible whole month (localized pickers)
  dateMode = signal<'specific' | 'flexible'>('specific');
  dates = signal<string[]>([]);
  selDay: number | null = null;
  selMonth: number | null = null;
  selYear: number | null = null;
  flexMonthNum: number | null = null;
  flexYear: number | null = null;
  readonly today = new Date().toISOString().slice(0, 10);

  readonly days = Array.from({ length: 31 }, (_, i) => i + 1);
  readonly years = Array.from({ length: 4 }, (_, i) => new Date().getFullYear() + i);
  readonly months = [
    { n: 1, ar: 'يناير', en: 'January' }, { n: 2, ar: 'فبراير', en: 'February' },
    { n: 3, ar: 'مارس', en: 'March' }, { n: 4, ar: 'أبريل', en: 'April' },
    { n: 5, ar: 'مايو', en: 'May' }, { n: 6, ar: 'يونيو', en: 'June' },
    { n: 7, ar: 'يوليو', en: 'July' }, { n: 8, ar: 'أغسطس', en: 'August' },
    { n: 9, ar: 'سبتمبر', en: 'September' }, { n: 10, ar: 'أكتوبر', en: 'October' },
    { n: 11, ar: 'نوفمبر', en: 'November' }, { n: 12, ar: 'ديسمبر', en: 'December' },
  ];

  name = '';
  phone = signal('');
  email = '';
  waSame = signal(true);
  waPhone = '';

  eventTypes: Opt[] = [
    { value: 'Wedding', ar: 'زفاف', en: 'Wedding' },
    { value: 'Engagement', ar: 'خطوبة', en: 'Engagement' },
    { value: 'Corporate', ar: 'مؤتمر / شركة', en: 'Corporate' },
    { value: 'Birthday', ar: 'عيد ميلاد', en: 'Birthday' },
    { value: 'Other', ar: 'أخرى', en: 'Other' },
  ];
  fnbLevels: Opt[] = [
    { value: 'high_tea', ar: 'شاي راقٍ', en: 'High Tea' },
    { value: 'drinks_only', ar: 'مشروبات فقط', en: 'Drinks only' },
    { value: 'set_menu', ar: 'منيو محدد', en: 'Set menu' },
    { value: 'open_buffet', ar: 'بوفيه مفتوح', en: 'Open buffet' },
    { value: 'custom', ar: 'مخصص', en: 'Custom' },
  ];
  venueTypes: Opt[] = [
    { value: 'open', ar: 'اوبن اير (قاعة مفتوحة)', en: 'Open-air' },
    { value: 'closed', ar: 'مغلقة', en: 'Indoor' },
    { value: 'both', ar: 'لا يهم', en: 'No preference' },
  ];

  private labels = ['step_event', 'step_fnb', 'step_venue', 'step_budget', 'step_contact'];
  stepLabel = computed(() => this.lang.t(this.labels[this.step() - 1]));

  constructor() {
    this.ensureSession();
  }

  private async ensureSession() {
    if (this.state.token()) return;
    this.api.startWizard().subscribe({
      next: (r) => this.state.setSession(r.data.session),
      error: () => {},
    });
  }

  canNext(): boolean {
    switch (this.step()) {
      case 1: return !!this.eventType() && !!this.attendees;
      case 2: return !!this.fnbLevel();
      case 3: return !!this.venuePref();
      default: return true;
    }
  }

  back() { if (this.step() > 1) this.step.update((s) => s - 1); }

  private pad(n: number): string { return String(n).padStart(2, '0'); }

  /** The composed YYYY-MM-DD from the specific-date selects (or null). */
  private specificDate(): string | null {
    if (!this.selDay || !this.selMonth || !this.selYear) return null;
    return `${this.selYear}-${this.pad(this.selMonth)}-${this.pad(this.selDay)}`;
  }
  /** True when the chosen specific date is today-or-future and complete. */
  specificValid(): boolean { const d = this.specificDate(); return !!d && d >= this.today; }
  specificPast(): boolean { const d = this.specificDate(); return !!d && d < this.today; }
  /** Disable past months when the chosen year is the current year. */
  monthDisabled(m: number, year: number | null): boolean {
    const now = new Date();
    return (year ?? now.getFullYear()) === now.getFullYear() && m < now.getMonth() + 1;
  }

  addDate() {
    const d = this.specificDate();
    if (!d || d < this.today) return;
    if (!this.dates().includes(d)) this.dates.set([...this.dates(), d].sort());
    this.selDay = null;
  }
  removeDate(d: string) { this.dates.set(this.dates().filter((x) => x !== d)); }

  prettyDate(d: string): string {
    const [y, m] = d.split('-').map(Number);
    const mo = this.months.find((x) => x.n === m);
    const name = mo ? (this.lang.lang() === 'ar' ? mo.ar : mo.en) : m;
    return `${d.slice(8)} ${name} ${y}`;
  }

  /** The candidate dates to send: the chosen specific dates, or the weekend
   *  (Thu/Fri/Sat) dates of the flexible month so matching has real dates. */
  private candidateDates(): string[] {
    if (this.dateMode() === 'flexible') {
      return this.flexMonthNum && this.flexYear
        ? this.monthWeekends(`${this.flexYear}-${String(this.flexMonthNum).padStart(2, '0')}`)
        : [];
    }
    return this.dates();
  }
  private monthWeekends(ym: string): string[] {
    const [y, m] = ym.split('-').map(Number);
    if (!y || !m) return [];
    const out: string[] = [];
    const last = new Date(y, m, 0).getDate();
    for (let d = 1; d <= last; d++) {
      const wd = new Date(y, m - 1, d).getDay(); // 4 Thu, 5 Fri, 6 Sat
      const ds = `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
      if ((wd === 4 || wd === 5 || wd === 6) && ds >= this.today) {
        out.push(ds);
      }
    }
    return out;
  }

  next() {
    this.save().then(() => this.step.update((s) => Math.min(5, s + 1)));
  }

  finish() {
    this.save().then(() => this.router.navigate(['/results']));
  }

  /** Persist the current answers server-side (progressive capture). */
  private save(): Promise<void> {
    const token = this.state.token();
    if (!token) return Promise.resolve();

    const data: any = { current_step: this.step() };
    if (this.eventType()) data.event_type = this.eventType();
    if (this.attendees) data.attendees = this.attendees;
    if (this.fnbLevel()) data.fnb_level = this.fnbLevel();
    if (this.venuePref()) data.venue_preference = this.venuePref();
    if (this.budgetMin) data.budget_min = this.budgetMin;
    if (this.budgetMax) data.budget_max = this.budgetMax;
    const cds = this.candidateDates();
    if (cds.length) data.candidate_dates = cds;
    if (this.name) data.contact_name = this.name;
    if (this.phone()) data.contact_phone = this.phone();
    if (this.email) data.contact_email = this.email;
    const wa = this.waSame() ? this.phone() : this.waPhone;
    if (wa) data.contact_whatsapp = wa;

    this.busy.set(true);
    return new Promise((resolve) => {
      this.api.updateStep(token, data).subscribe({
        next: (r) => { this.state.setSession(r.data.session); this.busy.set(false); resolve(); },
        error: () => { this.busy.set(false); resolve(); },
      });
    });
  }
}
