import { Component, computed, inject } from '@angular/core';

import { findMenu } from '../../../../../../core/services/menu.utils';
import { TenantService } from '../../../../../../core/services/tenant.service';
import { MenuContentSectionComponent } from '../../../../components/menu-content-section/menu-content-section.component';
import {
  LocationMapComponent,
  MapLocation,
} from '../../../../../../shared/components/location-map/location-map.component';

type ContactLocation = {
  id: string;
  label: string;
  addresses: ContactAddress[];
};

type ContactAddress = {
  id: string;
  label: string;
  address: string;
  coordinates: [number, number];
};

type ContactContent = {
  whatsappUrl: string | null;
  whatsappLabel: string | null;
  phone: string | null;
  locations: ContactLocation[];
  mapLocations: MapLocation[];
};

@Component({
  selector: 'app-contact-page',
  imports: [LocationMapComponent, MenuContentSectionComponent],
  templateUrl: './contact-page.html',
  styleUrl: './contact-page.scss',
})
export class ContactPage {
  private readonly tenantService = inject(TenantService);

  protected readonly markerColor = computed(
    () => this.tenantService.tenant()?.primary_color ?? '#6376f3',
  );

  protected readonly contact = computed(() =>
    this.parseContactContent(
      findMenu(this.tenantService.tenant()?.menues ?? [], 'help.contact')?.static_content,
    ),
  );

  protected phoneUrl(phone: string): string {
    const normalizedPhone = phone.replace(/[^\d+]/g, '');
    return `tel:${normalizedPhone}`;
  }

  private parseContactContent(value: unknown): ContactContent {
    const empty: ContactContent = {
      whatsappUrl: null,
      whatsappLabel: null,
      phone: null,
      locations: [],
      mapLocations: [],
    };

    if (!this.isRecord(value)) {
      return empty;
    }

    const whatsapp = this.isRecord(value['whatsapp']) ? value['whatsapp'] : null;
    const locations = this.parseLocations(value['locations']).slice(0, 1);

    return {
      whatsappUrl: whatsapp ? this.stringValue(whatsapp['whatsapp_url']) : null,
      whatsappLabel: whatsapp ? this.stringValue(whatsapp['whatsapp_label']) : null,
      phone: this.stringValue(value['phone']),
      locations,
      mapLocations: locations.flatMap((location) =>
        location.addresses.map(
          (address): MapLocation => ({
            id: address.id,
            label: address.label,
            latitude: address.coordinates[0],
            longitude: address.coordinates[1],
            address: address.address,
          }),
        ),
      ),
    };
  }

  private parseLocations(value: unknown): ContactLocation[] {
    return this.recordEntries(value).flatMap(([id, item]): ContactLocation[] => {
      if (!this.isRecord(item)) {
        return [];
      }

      const label = this.stringValue(item['label']);
      const addresses: ContactAddress[] = Array.isArray(item['addresses'])
        ? item['addresses'].flatMap((address, index): ContactAddress[] => {
            if (!this.isRecord(address)) {
              return [];
            }

            const addressLabel = this.stringValue(address['label']);
            const addressText = this.stringValue(address['address']);
            const coordinates = address['coordinates'];

            if (
              !addressLabel ||
              !addressText ||
              !Array.isArray(coordinates) ||
              coordinates.length !== 2 ||
              typeof coordinates[0] !== 'number' ||
              typeof coordinates[1] !== 'number'
            ) {
              return [];
            }

            return [
              {
                id: `${id}-${index}`,
                label: addressLabel,
                address: addressText,
                coordinates: [coordinates[0], coordinates[1]],
              },
            ];
          })
        : [];

      return label && addresses.length > 0 ? [{ id, label, addresses }] : [];
    });
  }

  private recordEntries(value: unknown): [string, unknown][] {
    if (Array.isArray(value)) {
      return value.map((item, index) => [String(index), item]);
    }

    return this.isRecord(value) ? Object.entries(value) : [];
  }

  private stringValue(value: unknown): string | null {
    return typeof value === 'string' && value.trim() ? value.trim() : null;
  }

  private isRecord(value: unknown): value is Record<string, unknown> {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
  }
}
