import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
import { ProjectEditorFacade } from '../facade/project-editor.facade';
import { TranslatePipe } from '../../../i18n/translate.pipe';
import { TranslateService } from '../../../i18n/translate.service';
import { InputComponent } from '../../../shared/ui/input/input.component';
import { ButtonComponent } from '../../../shared/ui/button/button.component';
import { FormFieldComponent } from '../../../shared/ui/form-field/form-field.component';
import { SectionCardComponent } from '../../../shared/ui/section-card/section-card.component';
import { KeyValueEditorComponent } from '../../../shared/ui/key-value-editor/key-value-editor.component';
import { ImageFieldComponent } from '../../../shared/ui/image-field/image-field.component';
import { IconComponent } from '../../../shared/ui/icon/icon.component';
import { FooterColumnConfig, FooterLinkConfig, FooterPaymentIconConfig, FooterSocialLinkConfig } from '../../../shared/models/config';
import { isValidHttpUrl } from '../schema/validators/primitives';
import { ContentPageService } from '../../content-management/services/content-page.service';

@Component({
  selector: 'app-project-editor-footer-section',
  standalone: true,
  imports: [
    FormsModule,
    DragDropModule,
    TranslatePipe,
    InputComponent,
    ButtonComponent,
    FormFieldComponent,
    SectionCardComponent,
    KeyValueEditorComponent,
    ImageFieldComponent,
    IconComponent
  ],
  templateUrl: './footer-section.component.html',
  styleUrls: ['./section.shared.scss', './footer-section.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProjectEditorFooterSectionComponent {
  private readonly facade = inject(ProjectEditorFacade);
  private readonly translate = inject(TranslateService);
  private readonly contentPageService = inject(ContentPageService);

  readonly bootstrap = this.facade.bootstrap;
  readonly fieldError = (key: string): string | null => {
    const messageKey = this.facade.fieldError(key);
    return messageKey ? this.translate.t(messageKey) : null;
  };

  /** Existing static pages, offered as the primary way to link a footer column - stays correct if a page's route changes later. */
  readonly availablePages = computed(() => this.contentPageService.normalizePages(this.bootstrap()?.staticPages));

  readonly copyrightValue = computed(() => {
    const value = this.bootstrap()?.footer?.copyrightText;
    return typeof value === 'string' ? value : '';
  });
  readonly paymentIconRows = computed<FooterPaymentIconConfig[]>(() => this.bootstrap()?.footer?.paymentIcons ?? []);
  readonly socialLinkRows = computed<FooterSocialLinkConfig[]>(() => this.bootstrap()?.footer?.socialLinks ?? []);
  readonly columns = computed<FooterColumnConfig[]>(() => this.bootstrap()?.footer?.columns ?? []);
  readonly additionalPhones = computed<string[]>(() => this.bootstrap()?.company.contacts.additionalPhones ?? []);
  readonly additionalEmails = computed<string[]>(() => this.bootstrap()?.company.contacts.additionalEmails ?? []);

  readonly createPaymentIconRow = (): FooterPaymentIconConfig => ({ src: '', alt: '' });
  readonly createSocialLinkRow = (): FooterSocialLinkConfig => ({ id: `social-${Date.now()}`, label: '', url: '' });

  updateCompanyName(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, companyName: value } })); }
  updateAddress(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, address: { ...current.company.address, street: value } } })); }
  updatePhone(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, phone: value } }, branding: { ...current.branding, supportPhone: value } })); }
  updateEmail(value: string): void { this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, email: value } }, branding: { ...current.branding, supportEmail: value } })); }
  updateCopyright(value: string): void { this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, copyrightText: value } })); }

  updateLogo(value: string): void {
    this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, logoUrl: value } }));
  }

  onPaymentIconsChange(rows: FooterPaymentIconConfig[]): void {
    this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, paymentIcons: rows } }));
  }

  updatePaymentIconSrc(index: number, src: string): void {
    const rows = this.paymentIconRows().map((row, i) => (i === index ? { ...row, src } : row));
    this.onPaymentIconsChange(rows);
  }

  updatePaymentIconAlt(index: number, alt: string): void {
    const rows = this.paymentIconRows().map((row, i) => (i === index ? { ...row, alt } : row));
    this.onPaymentIconsChange(rows);
  }

  onSocialLinksChange(rows: FooterSocialLinkConfig[]): void {
    this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, socialLinks: rows } }));
  }

  updateSocialLinkLabel(index: number, label: string): void {
    const rows = this.socialLinkRows().map((row, i) => (i === index ? { ...row, label } : row));
    this.onSocialLinksChange(rows);
  }

  updateSocialLinkUrl(index: number, url: string): void {
    const rows = this.socialLinkRows().map((row, i) => (i === index ? { ...row, url } : row));
    this.onSocialLinksChange(rows);
  }

  isValidUrl(url: string): boolean {
    return !url || isValidHttpUrl(url);
  }

  // --- Footer columns (replaces the old comma-separated static-page-keys input) ---

  private setColumns(columns: FooterColumnConfig[]): void {
    this.facade.updateBootstrap(current => ({ ...current, footer: { ...current.footer, columns } }));
  }

  addColumn(): void {
    this.setColumns([...this.columns(), { id: `col-${Date.now()}`, title: '', links: [] }]);
  }

  removeColumn(columnId: string): void {
    this.setColumns(this.columns().filter(column => column.id !== columnId));
  }

  updateColumnTitle(columnId: string, title: string): void {
    this.setColumns(this.columns().map(column => column.id === columnId ? { ...column, title } : column));
  }

  dropColumn(event: CdkDragDrop<FooterColumnConfig[]>): void {
    const columns = [...this.columns()];
    moveItemInArray(columns, event.previousIndex, event.currentIndex);
    this.setColumns(columns);
  }

  /** Keyboard-operable fallback for the drag-and-drop column reorder above (WCAG 2.1.1). */
  moveColumn(columnId: string, direction: -1 | 1): void {
    const columns = [...this.columns()];
    const index = columns.findIndex(column => column.id === columnId);
    const targetIndex = index + direction;
    if (index === -1 || targetIndex < 0 || targetIndex >= columns.length) {
      return;
    }
    moveItemInArray(columns, index, targetIndex);
    this.setColumns(columns);
  }

  addLink(columnId: string): void {
    const link: FooterLinkConfig = { id: `link-${Date.now()}`, label: '', pageKey: this.availablePages()[0]?.id ?? '', url: '' };
    this.setColumns(this.columns().map(column => column.id === columnId ? { ...column, links: [...column.links, link] } : column));
  }

  removeLink(columnId: string, linkId: string): void {
    this.setColumns(this.columns().map(column => column.id === columnId ? { ...column, links: column.links.filter(link => link.id !== linkId) } : column));
  }

  updateLink(columnId: string, linkId: string, patch: Partial<FooterLinkConfig>): void {
    this.setColumns(this.columns().map(column => column.id === columnId
      ? { ...column, links: column.links.map(link => link.id === linkId ? { ...link, ...patch } : link) }
      : column));
  }

  dropLink(columnId: string, event: CdkDragDrop<FooterLinkConfig[]>): void {
    const column = this.columns().find(c => c.id === columnId);
    if (!column) {
      return;
    }
    const links = [...column.links];
    moveItemInArray(links, event.previousIndex, event.currentIndex);
    this.setColumns(this.columns().map(c => c.id === columnId ? { ...c, links } : c));
  }

  /** Keyboard-operable fallback for the drag-and-drop link reorder above (WCAG 2.1.1). */
  moveLink(columnId: string, linkId: string, direction: -1 | 1): void {
    const column = this.columns().find(c => c.id === columnId);
    if (!column) {
      return;
    }
    const links = [...column.links];
    const index = links.findIndex(link => link.id === linkId);
    const targetIndex = index + direction;
    if (index === -1 || targetIndex < 0 || targetIndex >= links.length) {
      return;
    }
    moveItemInArray(links, index, targetIndex);
    this.setColumns(this.columns().map(c => c.id === columnId ? { ...c, links } : c));
  }

  linkSourceMode(link: FooterLinkConfig): 'page' | 'custom' {
    return link.pageKey ? 'page' : 'custom';
  }

  setLinkSourceMode(columnId: string, linkId: string, mode: 'page' | 'custom'): void {
    if (mode === 'page') {
      this.updateLink(columnId, linkId, { pageKey: this.availablePages()[0]?.id ?? '', url: '' });
    } else {
      this.updateLink(columnId, linkId, { pageKey: '' });
    }
  }

  // --- Multiple phones/emails ---

  private setAdditionalPhones(phones: string[]): void {
    this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, additionalPhones: phones } } }));
  }

  private setAdditionalEmails(emails: string[]): void {
    this.facade.updateBootstrap(current => ({ ...current, company: { ...current.company, contacts: { ...current.company.contacts, additionalEmails: emails } } }));
  }

  addPhone(): void {
    this.setAdditionalPhones([...this.additionalPhones(), '']);
  }

  updatePhoneAt(index: number, value: string): void {
    this.setAdditionalPhones(this.additionalPhones().map((phone, i) => i === index ? value : phone));
  }

  removePhoneAt(index: number): void {
    this.setAdditionalPhones(this.additionalPhones().filter((_, i) => i !== index));
  }

  addEmail(): void {
    this.setAdditionalEmails([...this.additionalEmails(), '']);
  }

  updateEmailAt(index: number, value: string): void {
    this.setAdditionalEmails(this.additionalEmails().map((email, i) => i === index ? value : email));
  }

  removeEmailAt(index: number): void {
    this.setAdditionalEmails(this.additionalEmails().filter((_, i) => i !== index));
  }
}
