import { useNamespace } from '@ibiz-template/vue-util';
import { defineComponent, onUnmounted, ref, watch } from 'vue';
import type { PropType } from 'vue';
import '@ibiz-template/theme/style/components/common/skeleton/skeleton-card/skeleton-card.scss';

export default defineComponent({
  props: {
    active: {
      type: Boolean,
      default: false,
    },
    round: {
      type: Boolean,
      default: false,
    },
    loading: {
      type: Boolean,
      default: true,
    },
    title: {
      type: Boolean,
      default: true,
    },
    paragraph: {
      type: [Boolean, Object] as PropType<boolean | { rows: number }>,
      default: true,
    },
  },
  setup(props, { slots }) {
    const ns = useNamespace('skeleton-card');

    const content = ref<HTMLElement | null>(null);
    const rows = ref<number>(2);

    watch(
      () => props.paragraph,
      value => {
        if (!(typeof value === 'boolean')) {
          rows.value = Math.floor(value.rows > 2 ? value.rows : 2);
        }
      },
    );

    const childHeight = 16;
    const childMarginBottom = 12;
    let observer: ResizeObserver | null = null;

    watch(
      content,
      () => {
        if (content.value && !observer && ResizeObserver) {
          observer = new ResizeObserver(entries => {
            if (typeof props.paragraph === 'boolean') {
              rows.value = Math.floor(
                (entries[0].contentRect.height + childMarginBottom) /
                  (childHeight + childMarginBottom),
              );
            }
          });
          observer.observe(content.value);
        } else if (!content.value && observer) {
          observer.disconnect();
          observer = null;
        }
      },
      { immediate: true },
    );

    onUnmounted(() => {
      if (observer) {
        observer.disconnect();
        observer = null;
      }
    });

    return () => (
      <div
        class={`${props.loading ? ns.b() : ''} ${
          props.loading && props.active ? ns.m('active') : ''
        } ${props.loading && props.round ? ns.m('round') : ''}`.trim()}
      >
        {props.loading && props.title ? (
          <header class={ns.b('header')}>
            <h3 class={ns.be('header', 'title')}></h3>
          </header>
        ) : null}

        {props.loading && props.paragraph ? (
          <main class={ns.b('content')} ref={content as unknown as string}>
            {Array.from({ length: rows.value }).map((_value, i) => (
              <div class={ns.be('content', 'item')} key={i}></div>
            ))}
          </main>
        ) : null}

        {typeof slots.default === 'function' && !props.loading
          ? slots.default()
          : null}
      </div>
    );
  },
});
