/*
 * Copyright (C) 2022 StApps
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */
import {Component, Input, OnInit} from '@angular/core';
import {
  getICalExport,
  getNativeCalendarExport,
  ICalEvent,
  serializeICal,
  toICal,
  toICalUpdates,
} from './ical/ical';
import moment from 'moment';
import {Share} from '@capacitor/share';
import {Directory, Encoding, Filesystem} from '@capacitor/filesystem';
import {Device} from '@capacitor/device';
import {CalendarService} from './calendar.service';
import {Dialog} from '@capacitor/dialog';
import {SCDateSeries} from '@openstapps/core';
import {ThingTranslateService} from '../../translation/thing-translate.service';
import {TranslateService} from '@ngx-translate/core';
import {NewShareData, NewShareNavigator} from './new-share';

interface ICalInfo {
  title: string;
  events: ICalEvent[];
  cancelledEvents: ICalEvent[];
}

@Component({
  selector: 'add-event-review-modal',
  templateUrl: 'add-event-review-modal.html',
  styleUrls: ['add-event-review-modal.scss'],
})
export class AddEventReviewModalComponent implements OnInit {
  moment = moment;

  @Input() dismissAction: () => void;

  @Input() dateSeries: SCDateSeries[];

  iCalEvents: ICalInfo[];

  includeCancelled = true;

  isWeb = true;

  constructor(
    readonly calendarService: CalendarService,
    readonly translator: ThingTranslateService,
    readonly translateService: TranslateService,
  ) {}

  ngOnInit() {
    Device.getInfo().then(it => {
      this.isWeb = it.platform === 'web';
    });

    this.iCalEvents = this.dateSeries.map(event => ({
      title: this.translator.translator.translatedAccess(event).event?.name ?? 'error',
      events: toICal(event, this.translator.translator, {
        allowRRuleExceptions: true,
        excludeCancelledEvents: false,
      }),
      cancelledEvents: toICalUpdates(event, this.translator.translator),
    }));
  }

  async toCalendar() {
    await Dialog.confirm({
      title: this.translateService.instant('schedule.toCalendar.reviewModal.dialogs.toCalendarConfirm.TITLE'),
      message: this.translateService.instant(
        'schedule.toCalendar.reviewModal.dialogs.toCalendarConfirm.DESCRIPTION',
      ),
    });

    await this.calendarService.syncEvents(
      getNativeCalendarExport(this.dateSeries, this.translator.translator),
    );

    this.dismissAction();
  }

  async download() {
    const blob = new Blob(
      [serializeICal(getICalExport(this.dateSeries, this.translator.translator, this.includeCancelled))],
      {
        type: 'text/calendar',
      },
    );
    const url = window.URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = `${this.dateSeries.length === 1 ? this.dateSeries[0].event.name : 'stapps_calendar'}.ics`;
    a.click();
  }

  async export() {
    const info = await Device.getInfo();

    if (info.platform === 'web') {
      const blob = new Blob(
        [serializeICal(getICalExport(this.dateSeries, this.translator.translator, this.includeCancelled))],
        {
          type: 'text/calendar',
        },
      );
      const file = new File([blob], 'calendar.ics', {type: blob.type});
      const shareData: NewShareData = {
        files: [file],
        title: this.translateService.instant('schedule.toCalendar.reviewModal.shareData.TITLE'),
        text: this.translateService.instant('schedule.toCalendar.reviewModal.shareData.TEXT'),
      };

      if (!(navigator as unknown as NewShareNavigator).canShare) {
        return Dialog.alert({
          title: this.translateService.instant('schedule.toCalendar.reviewModal.dialogs.cannotShare.TITLE'),
          message: this.translateService.instant(
            'schedule.toCalendar.reviewModal.dialogs.cannotShare.DESCRIPTION',
          ),
        });
      }

      if (!(navigator as unknown as NewShareNavigator).canShare(shareData)) {
        return Dialog.alert({
          title: this.translateService.instant(
            'schedule.toCalendar.reviewModal.dialogs.unsupportedFileType.TITLE',
          ),
          message: this.translateService.instant(
            'schedule.toCalendar.reviewModal.dialogs.unsupportedFileType.DESCRIPTION',
          ),
        });
      }
      try {
        await (navigator as unknown as NewShareNavigator).share(shareData);
      } catch (error) {
        console.log(error);
        return Dialog.alert({
          title: this.translateService.instant('schedule.toCalendar.reviewModal.dialogs.failedShare.TITLE'),
          message: this.translateService.instant(
            'schedule.toCalendar.reviewModal.dialogs.failedShare.DESCRIPTION',
          ),
        });
      }
    } else {
      const result = await Filesystem.writeFile({
        path: `${
          this.dateSeries.length === 1
            ? this.dateSeries[0].event.name
            : this.translateService.instant('schedule.toCalendar.reviewModal.shareData.FILE_TYPE')
        }.ics`,
        data: serializeICal(
          getICalExport(this.dateSeries, this.translator.translator, this.includeCancelled),
        ),
        encoding: Encoding.UTF8,
        directory: Directory.Cache,
      });

      await Share.share({
        title: this.translateService.instant('schedule.toCalendar.reviewModal.shareData.TITLE'),
        text: this.translateService.instant('schedule.toCalendar.reviewModal.shareData.TEXT'),
        url: result.uri,
        dialogTitle: this.translateService.instant('schedule.toCalendar.reviewModal.shareData.TITLE'),
      });
    }
  }
}
