<template>
    <component
        :is="parentType"
        :tag="tag"
        :name="name"
        class="sqadhkmv"
        :class="{ noGap: noGap }"
        :data-direction="direction"
        :data-reversed="reversed ? 'true' : 'false'"
    >
        <template v-for="item in effectiveItems" :key="item.key">
            <slot v-if="item.type === 'item'" :item="item.item"></slot>
            <div v-else class="separator">
                <p class="date">
                    <span>
                        <i class="ph-caret-up ph-bold ph-lg icon"></i>
                        {{ item.dateAfter }}
                    </span>
                    <span>
                        {{ item.dateBefore }}
                        <i class="ph-caret-down ph-bold ph-lg icon"></i>
                    </span>
                </p>
            </div>
        </template>
    </component>
</template>
<script lang="ts" setup generic="T">
import { computed, ref, shallowRef, TransitionGroup, watch } from "vue";
import { i18n } from "@/i18n";
import { defaultStore } from "@/store";
import { magTransProperty } from "@/scripts-mag/mag-util";

type Item = { id: string } & ({ createdAt: string } | { created_at: string });
const props = withDefaults(
    defineProps<{
        items: (T & Item)[];
        direction?: "up" | "down";
        reversed?: boolean;
        noGap?: boolean;
    }>(),
    {
        direction: "down",
        reversed: false,
        noGap: false,
    },
);

type ItemType =
    | { type: "separator"; key: string; dateBefore: string; dateAfter: string }
    | { type: "item"; key: string; item: T & Item };

const effectiveItems = shallowRef<ItemType[]>([]);

watch(
    () => props.items,
    (itemsNew) => {
        const listItems: ItemType[] = [];
        for (let i = 0; i < itemsNew.length; i++) {
            listItems.push({
                type: "item",
                key: itemsNew[i].id,
                item: itemsNew[i],
            });

            if (itemsNew.length > i + 1) {
                const dateAfter = getDateText(itemsNew[i]);
                const dateBefore = getDateText(itemsNew[i + 1]);

                if (dateBefore === dateAfter) {
                    continue;
                }

                listItems.push({
                    type: "separator",
                    key: `${itemsNew[i].id}:separator`,
                    dateBefore,
                    dateAfter,
                });
            }
        }

        effectiveItems.value = listItems;
    },
    { deep: true, immediate: true },
);

function getDateText(item: { createdAt: string } | { created_at: string }) {
    const dateTime = new Date(
        magTransProperty(item, "createdAt", "created_at"),
    );
    const date = dateTime.getDate();
    const month = dateTime.getMonth() + 1;
    return i18n.t("monthAndDay", {
        month: month.toString(),
        day: date.toString(),
    });
}

const animationEnabled = ref(defaultStore.state.animation);
watch(
    () => defaultStore.state.animation,
    (val) => (animationEnabled.value = val),
);

const parentType = computed(() =>
    animationEnabled ? TransitionGroup : HTMLDivElement,
);
const tag = computed(() => (animationEnabled ? "div" : null));
const name = computed(() => (animationEnabled ? "list" : null));

defineSlots<{
    default(props: { item: T & Item }): any;
}>();
</script>

<style lang="scss">
.sqadhkmv {
    > *:empty {
        display: none;
    }

    > *:not(:last-child) {
        margin-bottom: var(--margin);
    }

    > .list-move {
        transition: transform 0.7s cubic-bezier(0.23, 1, 0.32, 1);
    }

    > .list-enter-active {
        transition:
            transform 0.7s cubic-bezier(0.23, 1, 0.32, 1),
            opacity 0.7s cubic-bezier(0.23, 1, 0.32, 1);
    }

    &[data-direction="up"] {
        > .list-enter-from {
            opacity: 0;
            transform: translateY(64px);
        }
    }

    &[data-direction="down"] {
        > .list-enter-from {
            opacity: 0;
            transform: translateY(-64px);
        }
    }

    > .separator {
        text-align: center;

        > .date {
            display: inline-block;
            position: relative;
            margin: 0;
            padding: 0 16px;
            line-height: 32px;
            text-align: center;
            font-size: 12px;
            color: var(--dateLabelFg);

            > span {
                &:first-child {
                    margin-right: 8px;

                    > .icon {
                        margin-right: 8px;
                    }
                }

                &:last-child {
                    margin-left: 8px;

                    > .icon {
                        margin-left: 8px;
                    }
                }
            }
        }
    }

    &.noGap {
        > * {
            margin: 0 !important;
            border: none;
            border-radius: 0;
            box-shadow: none;

            &:first-child {
                border-radius: var(--radius) var(--radius) 0 0;
            }
            &:last-child {
                border-radius: 0 0 var(--radius) var(--radius);
            }

            &:not(:last-child) {
                border-bottom: solid 0.5px var(--divider);
            }
        }
    }
}
</style>
