import { DOCUMENT, NgStyle } from '@angular/common';
import {
  Component,
  ElementRef,
  EventEmitter,
  Inject,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  Output,
  Renderer2,
  SimpleChanges,
} from '@angular/core';
import { Button } from 'primeng/button';

@Component({
  selector: 'shared-light-bottomsheet',
  templateUrl: './light-bottomsheet.component.html',
  imports: [NgStyle, Button],
  styles: [
    `
      :host {
        position: fixed;
        inset: 0;
        z-index: 1210;
      }

      .light-bottomsheet-mask {
        position: absolute;
        inset: 0;
        background: rgba(15, 23, 42, 0.22);
      }

      .light-bottomsheet-panel {
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        max-height: 90vh;
        display: flex;
        flex-direction: column;
        background: var(--surface-card, #fff);
        border-radius: 12px 12px 0 0;
        box-shadow: none;
        backface-visibility: hidden;
        overflow: hidden;
      }

      .light-bottomsheet-content {
        display: flex;
        flex-direction: column;
        flex: 1;
        min-height: 0;
        // padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
      }

      .light-bottomsheet-body {
        flex: 1;
        min-height: 0;
        overflow: auto;
      }

      .light-bottomsheet-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        padding: 0.75rem 1rem;
      }

      .light-bottomsheet-title {
        margin: 0;
      }

      .light-bottomsheet-close {
        border: 0;
        background: transparent;
        padding: 0.25rem;
        line-height: 1;
        font-size: 1.25rem;
      }
    `,
  ],
  host: {
    '[attr.role]': '"complementary"',
    '[attr.aria-modal]': 'true',
    '[attr.pfocustrap]': 'true',
    '[attr.data-pc-name]': "'drawer'",
    '[attr.data-pc-section]': "'root'",
    '[attr.aria-hidden]': '!visible',
    '[style.display]': 'visible ? "block" : "none"',
    '[style.--sheet-transition]': 'transitionOptions',
  },
})
export class SharedLightBottomsheetComponent implements OnInit, OnDestroy, OnChanges {
  @Input() header = '';
  @Input() visible = false;
  @Output() visibleChange = new EventEmitter<boolean>();

  @Input() modal = true;
  @Input() closable = true;
  @Input() style: Record<string, string> | undefined;
  @Input() mobileDrawerHeight = '90vh';
  @Input() transitionOptions = '130ms cubic-bezier(0.2, 0, 0, 1)';

  @Output() onHide = new EventEmitter<any>();

  private originalParent: Node | null = null;
  private readonly defaultDrawerZIndex = 1102;
  private previousBodyOverflow = '';
  private previousBodyTouchAction = '';

  constructor(
    private readonly elementRef: ElementRef<HTMLElement>,
    private readonly renderer: Renderer2,
    @Inject(DOCUMENT) private readonly document: Document
  ) {}

  ngOnInit() {
    const host = this.elementRef.nativeElement;
    this.originalParent = host.parentNode;
    this.renderer.appendChild(this.document.body, host);
    this.syncZIndex();
    this.toggleBodyScrollLock(this.visible);
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['visible'] && this.visible) {
      this.syncZIndex();
    }
    if (changes['visible']) {
      this.toggleBodyScrollLock(this.visible);
    }
  }

  ngOnDestroy() {
    this.toggleBodyScrollLock(false);
    this.removeDrawer();
  }

  private removeDrawer() {
    const host = this.elementRef.nativeElement;
    if (this.originalParent) {
      this.renderer.appendChild(this.originalParent, host);
    }
  }

  onVisibilityChange(nextValue: boolean) {
    this.visible = nextValue;
    this.visibleChange.emit(nextValue);
    this.toggleBodyScrollLock(nextValue);
    if (nextValue) {
      this.syncZIndex();
    }
    if (!nextValue) {
      this.onHide.emit();
    }
  }

  onMaskClick() {
    if (this.modal && this.closable) {
      this.onVisibilityChange(false);
    }
  }

  private toggleBodyScrollLock(locked: boolean) {
    const body = this.document.body;
    if (!body) return;

    if (locked) {
      if (!this.previousBodyOverflow) {
        this.previousBodyOverflow = body.style.overflow || '';
      }
      if (!this.previousBodyTouchAction) {
        this.previousBodyTouchAction = body.style.touchAction || '';
      }
      this.renderer.setStyle(body, 'overflow', 'hidden');
      this.renderer.setStyle(body, 'touch-action', 'none');
      return;
    }

    this.renderer.setStyle(body, 'overflow', this.previousBodyOverflow);
    this.renderer.setStyle(body, 'touch-action', this.previousBodyTouchAction);
    this.previousBodyOverflow = '';
    this.previousBodyTouchAction = '';
  }

  private syncZIndex() {
    const host = this.elementRef.nativeElement;
    const siblingDrawers = Array.from(
      this.document.body.querySelectorAll('.p-drawer')
    ) as HTMLElement[];
    const drawerZIndexes = siblingDrawers
      .map((drawer) => Number.parseInt(drawer.style.zIndex || '0', 10))
      .filter((zIndex) => Number.isFinite(zIndex) && zIndex > 0);

    const maxDrawerZIndex = drawerZIndexes.length
      ? Math.max(...drawerZIndexes)
      : this.defaultDrawerZIndex;
    this.renderer.setStyle(host, 'z-index', `${maxDrawerZIndex + 1}`);
  }
}
