import {
    Directive,
    ElementRef,
    Inject,
    Input,
    OnChanges,
    Optional,
} from '@angular/core';
import { BodyScrollService } from '@shared/services/body-scroll.service';
import { WINDOW } from '@shared/services/window.token';

@Directive({
    selector: '[scrollTo]',
})
export class ScrollToDirective implements OnChanges {
    @Input('scrollTo') shouldScroll = false;
    @Input('scrollToDelay') delay = 0;

    constructor(
        private elementRef: ElementRef<HTMLElement>,
        private bodyScroll: BodyScrollService,
        @Optional() private container?: ScrollContainerDirective,
    ) {}

    private get element() {
        return this.elementRef.nativeElement;
    }

    private get parent(): HTMLElement | undefined {
        return this.container?.element.nativeElement;
    }

    ngOnChanges(): void {
        if (!this.shouldScroll) {
            return;
        }

        setTimeout(() => {
            if (this.parent) {
                this.parent.scrollTo(this.getScrollToOptions());
            } else {
                this.bodyScroll.scrollToElement(this.element);
            }
        }, this.delay);
    }

    private getScrollToOptions(): ScrollToOptions {
        return {
            top: this.element.offsetTop - this.parent.clientHeight / 2,
            left: 0,
            behavior: 'smooth',
        };
    }
}

@Directive({
    selector: '[scrollUp]',
})
export class ScrollUpDirective {
    constructor(@Inject(WINDOW) private window$: Window) {}
    ngAfterViewInit() {
        this.window$.scrollTo(0, 0);
        this.window$.document?.getElementsByTagName('body')[0]?.scrollTo(0, 0);
    }
}
@Directive({
    selector: '[scrollContainer]',
})
export class ScrollContainerDirective {
    constructor(public element: ElementRef<HTMLElement>) {}
}
