import {ChangeDetectionStrategy, Component, ElementRef, Input} from '@angular/core';
import {SCIdCard} from '@openstapps/core';
import {ThingTranslateModule} from '../../translation/thing-translate.module';
import {AsyncPipe, TitleCasePipe} from '@angular/common';
import {IntervalIsNowPipe, ToDateIntervalPipe} from '../../util/in-range.pipe';
import {TranslateModule} from '@ngx-translate/core';
import {AnimationController, ModalController} from '@ionic/angular/standalone';
import {ScreenBrightness} from '@capacitor-community/screen-brightness';
import {ScreenOrientation} from '@capacitor/screen-orientation';
import {Capacitor} from '@capacitor/core';
import {iosDuration, iosEasing, mdDuration, mdEasing} from 'src/app/animation/easings';

@Component({
  selector: 'stapps-id-card',
  templateUrl: 'id-card.html',
  styleUrls: ['id-card.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [
    ThingTranslateModule,
    IntervalIsNowPipe,
    ToDateIntervalPipe,
    AsyncPipe,
    TranslateModule,
    TitleCasePipe,
  ],
})
export class IdCardComponent {
  @Input({required: true}) item: SCIdCard;

  constructor(
    private modalController: ModalController,
    private animationController: AnimationController,
    private elementRef: ElementRef,
  ) {}

  async presentFullscreen() {
    const top = await this.modalController.getTop();
    const mode = document.querySelector('ion-app')!.getAttribute('mode');
    if (top) return;

    if (window.innerWidth >= 768) return;

    if (Capacitor.isNativePlatform()) {
      const orientation = await ScreenOrientation.orientation();
      ScreenOrientation.lock({orientation: 'portrait'});
      if (orientation.type.startsWith('landscape')) {
        await new Promise(resolve => setTimeout(resolve, 500));
      }
    }

    const img: HTMLImageElement = this.elementRef.nativeElement.querySelector('img')!;

    const safeArea = (location: string) =>
      Number(img.computedStyleMap().get(`--ion-safe-area-${location}`)!.toString().replace(/px$/, ''));
    const safeAreaTop = safeArea('top');
    const safeAreaBottom = safeArea('bottom');
    const safeAreaLeft = safeArea('left');
    const safeAreaRight = safeArea('right');

    const windowWidth = window.innerWidth - safeAreaLeft - safeAreaRight;
    const windowHeight = window.innerHeight - safeAreaTop - safeAreaBottom;

    const isLandscape = windowWidth > windowHeight;
    const nativeBounds = img.getBoundingClientRect();
    const imageAspect = nativeBounds.width / nativeBounds.height;
    const imgWidth = Math.min(windowHeight, windowWidth * imageAspect);
    const imgHeight = imgWidth / imageAspect;
    const fullscreenWidth = isLandscape ? imgHeight : imgWidth;
    const fullscreenHeight = isLandscape ? imgWidth : imgHeight;

    const scale = fullscreenWidth / windowWidth;
    const animation = (modal: HTMLElement, leave = false) => {
      const root = modal.shadowRoot!;

      const sourceAnimation = this.animationController
        .create()
        .addElement(this.elementRef.nativeElement)
        .fromTo('opacity', 0, 0);
      const backdrop =
        'linear-gradient(to bottom,' +
        'transparent 16px,' +
        'rgba(0, 0, 0, 0.3) 20%,' +
        'rgba(0, 0, 0, 0.3) 80%,' +
        'transparent 100%)';
      const wrapperAnimation = this.animationController
        .create()
        .beforeStyles({'--background': 'transparent', 'margin': '0'})
        .addElement(root.querySelector('.modal-wrapper')!)
        .fromTo('transform', 'scale(1)', 'scale(1)')
        .fromTo('opacity', '1', '1');
      const backdropAnimation = this.animationController
        .create()
        .beforeStyles({background: backdrop, filter: 'blur(16px)'})
        .addElement(root.querySelector('ion-backdrop')!)
        .fromTo('opacity', leave ? 1 : 0, leave ? 0 : 1);

      const small =
        `translate(${nativeBounds.left - safeAreaLeft}px, ${nativeBounds.top - safeAreaTop}px) ` +
        `scale(${nativeBounds.width / windowWidth}) ` +
        `rotate(0) `;
      const large =
        `translate(${windowWidth - (windowWidth - fullscreenHeight) / 2}px, ${
          (windowHeight - fullscreenWidth) / 2
        }px)` +
        `scale(${scale}) ` +
        `rotate(${isLandscape ? 0 : 90}deg) `;
      const cardAnimation = this.animationController
        .create()
        .addElement(modal.querySelector('stapps-id-card')!)
        .beforeStyles({
          'transform-origin': 'top left',
          'filter': 'drop-shadow(0 0 16px rgba(0, 0, 0, 0.1))',
        })
        .fromTo('transform', leave ? large : small, leave ? small : large);

      return this.animationController
        .create()
        .addElement(modal)
        .easing(mode === 'ios' ? iosEasing : mdEasing)
        .duration(2 * (mode === 'ios' ? iosDuration : mdDuration))
        .addAnimation([wrapperAnimation, backdropAnimation, cardAnimation, sourceAnimation]);
    };

    const modal = await this.modalController.create({
      component: IdCardComponent,
      backdropDismiss: true,
      mode: 'md',
      componentProps: {
        item: this.item,
      },
      presentingElement: this.elementRef.nativeElement,
      enterAnimation: base => animation(base),
      leaveAnimation: base => animation(base, true),
    });

    const dismiss = () => modal.dismiss();
    window.addEventListener('click', dismiss);
    modal.addEventListener('didDismiss', () => window.removeEventListener('click', dismiss));

    if (Capacitor.isNativePlatform()) {
      const brightness = (await ScreenBrightness.getBrightness()).brightness;
      ScreenBrightness.setBrightness({brightness: 1});
      modal.addEventListener('didDismiss', () => {
        ScreenOrientation.unlock();
        ScreenBrightness.setBrightness({brightness: brightness === 1 ? 0.5 : brightness});
      });
    }

    await modal.present();
  }
}
