import {Directive, HostListener, Input} from '@angular/core';
import {SCPlaceWithoutReferences, SCThings, SCThingWithoutReferences} from '@openstapps/core';
import {Device} from '@capacitor/device';
import {ActionSheetController, ActionSheetOptions, ToastController} from '@ionic/angular/standalone';
import {TranslateService} from '@ngx-translate/core';
import {ThingTranslateService} from '../../translation/thing-translate.service';
import {Clipboard} from '@capacitor/clipboard';
import {PositionService} from './position.service';

/**
 * A button that provides navigation options to the user via an action sheet
 * @example
 * <ion-button shape="round" [geoNavigation]="place">
 *  <ion-icon name="directions" slot="start"></ion-icon>
 *  <ion-label>{{'map.directions.TITLE' | translate}}</ion-label>
 * </ion-button>
 */
@Directive({
  selector: '[geoNavigation]',
  standalone: true,
})
export class GeoNavigationDirective {
  @Input({required: true}) geoNavigation: SCThingWithoutReferences &
    Pick<SCPlaceWithoutReferences, 'geo' | 'address'>;

  constructor(
    private actionSheetController: ActionSheetController,
    private translateService: TranslateService,
    private thingTranslate: ThingTranslateService,
    private toastController: ToastController,
    private positionService: PositionService,
  ) {}

  @HostListener('click', ['$event'])
  async presentActionSheet(event: Event) {
    event.stopPropagation();
    const {operatingSystem} = await Device.getInfo();
    const [lon, lat] = this.geoNavigation.geo.point.coordinates;

    const supportedMapProviders =
      operatingSystem === 'mac' || operatingSystem === 'ios'
        ? ['OSM_ROUTING', 'APPLE_MAPS', 'GOOGLE_MAPS']
        : ['OSM_ROUTING', 'GOOGLE_MAPS'];
    const address = this.geoNavigation.address
      ? this.translateService.instant(
          'map.directions.ADDRESS',
          this.thingTranslate.get(this.geoNavigation as SCThings, 'address'),
        )
      : `${lat}, ${lon}`;

    const options: ActionSheetOptions = {
      header: this.translateService.instant('map.directions.TITLE_LONG', {
        name: this.thingTranslate.get(this.geoNavigation as SCThings, 'name'),
      }),
      subHeader: address,
      buttons: [
        {
          text: this.translateService.instant('map.directions.COPY_ADDRESS'),
          role: 'selected',
          handler: async () => {
            await Clipboard.write({string: address});
            this.toastController
              .create({
                message: this.translateService.instant('map.directions.ADDRESS_COPIED'),
                duration: 500,
              })
              .then(toast => toast.present());
          },
        },
        ...supportedMapProviders.map(provider => ({
          text: this.translateService.instant(`map.directions.${provider}.TITLE`),
          handler: () => {
            const url: string = this.translateService.instant(`map.directions.${provider}.URL`, {
              lat,
              lon,
              posLat: this.positionService.position?.latitude ?? 0,
              posLon: this.positionService.position?.longitude ?? 0,
            });
            window.open(url.replace(/&?\w+=0,0/, ''), '_blank', 'noreferrer');
          },
        })),
        {
          text: this.translateService.instant('abort'),
          role: 'cancel',
        },
      ],
    };

    const actionSheet = await this.actionSheetController.create(options);
    await actionSheet.present();
  }
}
