import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ProjectEditorFacade } from '../facade/project-editor.facade';
import { TranslatePipe } from '../../../i18n/translate.pipe';
import { TranslateService } from '../../../i18n/translate.service';
import { NavigationItemConfig } from '../../../shared/models/config';
import { ButtonComponent } from '../../../shared/ui/button/button.component';
import { InputComponent } from '../../../shared/ui/input/input.component';
import { SectionCardComponent } from '../../../shared/ui/section-card/section-card.component';
import { ToggleComponent } from '../../../shared/ui/toggle/toggle.component';
import { LocaleTabsComponent } from '../../../shared/ui/locale-tabs/locale-tabs.component';
import { SelectComponent, SelectOption } from '../../../shared/ui/select/select.component';
import { EmptyStateComponent } from '../../../shared/ui/empty-state/empty-state.component';
import { ContentManagementFacade } from '../../content-management/facade/content-management.facade';

@Component({
  selector: 'app-project-editor-navigation-section',
  standalone: true,
  imports: [FormsModule, TranslatePipe, ButtonComponent, InputComponent, SectionCardComponent, ToggleComponent, LocaleTabsComponent, SelectComponent, EmptyStateComponent],
  templateUrl: './navigation-section.component.html',
  styleUrls: ['./section.shared.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProjectEditorNavigationSectionComponent {
  private readonly facade = inject(ProjectEditorFacade);
  private readonly contentFacade = inject(ContentManagementFacade);
  private readonly translate = inject(TranslateService);
  readonly bootstrap = this.facade.bootstrap;
  readonly fieldError = (key: string): string | null => {
    const messageKey = this.facade.fieldError(key);
    return messageKey ? this.translate.t(messageKey) : null;
  };

  readonly pageOptions = computed<SelectOption[]>(() =>
    this.contentFacade.pages(this.bootstrap()).map(page => ({ value: page.id, label: page.title || page.id })),
  );
  readonly selectedPageId = signal<Record<'header' | 'footer', string>>({ header: '', footer: '' });

  updateSelectedPage(target: 'header' | 'footer', pageId: string): void {
    this.selectedPageId.set({ ...this.selectedPageId(), [target]: pageId });
  }

  insertPageLink(target: 'header' | 'footer'): void {
    const pageId = this.selectedPageId()[target];
    if (!pageId) {
      return;
    }
    this.facade.addStaticPageNavLink(target, pageId);
    this.updateSelectedPage(target, '');
  }

  isStaticPageLink(item: NavigationItemConfig): boolean {
    return item.type === 'staticPage';
  }

  readonly supportedLocales = computed(() => this.bootstrap()?.tenant.supportedLocales ?? []);
  readonly defaultLocale = computed(() => this.bootstrap()?.tenant.defaultLocale ?? '');
  readonly activeLocale = signal<string | null>(null);

  readonly headerLinks = computed(() => this.sorted(this.bootstrap()?.navigation.header ?? []));
  readonly footerLinks = computed<NavigationItemConfig[] | null>(() => {
    const footer = this.bootstrap()?.navigation.footer ?? [];
    if (footer.length === 0) {
      return [];
    }
    return 'items' in footer[0] ? null : this.sorted(footer as NavigationItemConfig[]);
  });

  onActiveLocaleChange(locale: string): void {
    this.activeLocale.set(locale);
  }

  /** Display label used for the row heading — a stable identifier, not tied to the active locale. */
  labelOf(item: NavigationItemConfig): string {
    if (this.isStaticPageLink(item) && !item.label) {
      // A static-page link has no editable label of its own - the resolver
      // derives it from the linked page's title at render time - so fall
      // back to the page id rather than showing a blank row heading.
      return item.key ?? '';
    }
    if (typeof item.label === 'string' || !item.label) {
      return item.label ?? '';
    }
    const defaultLocale = this.bootstrap()?.localization.defaultLocale ?? 'en';
    return item.label[defaultLocale] ?? Object.values(item.label)[0] ?? '';
  }

  /** Editable label for the currently active locale tab. Falls back to an empty string
   *  when this locale has no translation yet, so switching locales lets you fill it in. */
  editableLabel(item: NavigationItemConfig): string {
    const locale = this.activeLocale() ?? this.defaultLocale();
    if (!item.label) {
      return '';
    }
    if (typeof item.label === 'string') {
      return locale === this.defaultLocale() ? item.label : '';
    }
    return item.label[locale] ?? '';
  }

  addLink(target: 'header' | 'footer'): void {
    this.facade.addNavLink(target);
  }

  removeLink(target: 'header' | 'footer', id: string): void {
    this.facade.removeNavLink(target, id);
  }

  move(target: 'header' | 'footer', id: string, direction: -1 | 1): void {
    this.facade.reorderNavLink(target, id, direction);
  }

  updateLabel(target: 'header' | 'footer', id: string, value: string): void {
    const locale = this.activeLocale() ?? this.defaultLocale();
    this.facade.updateNavLinkLabel(target, id, value, locale);
  }

  updateRoute(target: 'header' | 'footer', id: string, value: string): void {
    this.facade.updateNavLink(target, id, { route: value });
  }

  updateVisible(target: 'header' | 'footer', id: string, value: boolean): void {
    this.facade.updateNavLink(target, id, { visible: value });
  }

  private sorted(items: NavigationItemConfig[]): NavigationItemConfig[] {
    return [...items].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
  }
}
