<script setup lang="ts">
import { ref, onBeforeMount, computed, defineAsyncComponent } from "vue";
import type { Task } from "@/types";
import { getTasks, createTask, deleteTask } from "@/api/tasks";
import {
    CirclePlusIcon,
    ArrowDownUpIcon,
    Settings2Icon,
    CircleCheckBigIcon,
    CheckCheckIcon,
    SearchIcon,
    Share2Icon
} from "@lucide/vue";
const TaskItem = defineAsyncComponent(
    () => import("@/components/TaskItem.vue"),
);
import { taskCompleted, sortTasks } from "@/lib/tasks";
import { SortType } from "@/enums";
import { booleanCookieRef, enumCookieRef } from "@/lib/cookies";
import { useAlertStore } from "@/stores/alerts";
import { useI18n } from "vue-i18n";
import { onBeforeRouteUpdate, useRoute } from "vue-router";
import { shareLink } from "@/lib/share";

const route = useRoute();

const list = ref<string | null>(null);
const loading = ref<boolean>(true);
const taskInput = ref<string>("");
const tasks = ref<Task[]>([]);

const sortType = enumCookieRef<SortType>("sSortType", SortType.CREATED_AT);
const sortReverse = booleanCookieRef("sortReverse", false);
const showLastChecked = booleanCookieRef("showLastChecked", false);
const showNextReset = booleanCookieRef("showNextReset", false);
const separateCompleted = booleanCookieRef("separateCompleted", true);

const completedCount = computed<number>(
    () => tasks.value.filter(taskCompleted).length,
);
const taskCount = computed<number>(() => tasks.value.length);
const hasCompleted = computed<boolean>(() => completedCount.value > 0);
const empty = computed<boolean>(() => taskCount.value === 0);
const allCompleted = computed<boolean>(
    () => taskCount.value === completedCount.value,
);

const i18n = useI18n();

const { alertSuccess, alertError, alertWarning } = useAlertStore();

function fetchTasks() {
    if (list.value) {
        getTasks(list.value)
            .then((data: Task[]) => {
                tasks.value = data;
                reSortTasks();
                loading.value = false;
                setTimeout(fetchTasks, 10000);
            })
            .catch(() => {
                if (tasks.value.length !== 0) {
                    alertWarning(i18n.t("alerts.task_refresh_error"));
                } else {
                    alertError(i18n.t("alerts.task_fetch_error"));
                }
            });
    }
}

function reSortTasks() {
    tasks.value = sortTasks(tasks.value, sortType.value, sortReverse.value);
    updateTitle();
}

function onNewTask() {
    if (taskInput.value.trim() && list.value && !loading.value) {
        createTask(list.value, {
            name: taskInput.value.trim(),
            reset_cron: null,
        })
            .then((data: Task) => {
                tasks.value.push(data);
                reSortTasks();
                alertSuccess(i18n.t("alerts.task_created"));
            })
            .catch(() => {
                alertError(i18n.t("alerts.task_create_error"));
            })
            .finally(() => {
                taskInput.value = "";
            });
    }
}

function onCloneTask(task: Task) {
    if (list.value) {
        createTask(list.value, {
            name: task.name,
            reset_cron: task.reset_cron,
        })
            .then((data: Task) => {
                tasks.value.push(data);
                alertSuccess(i18n.t("alerts.task_cloned"));
            })
            .catch(() => {
                alertError(i18n.t("alerts.task_create_error"));
            });
    }
}

function onDeleteTask(task: Task) {
    deleteTask(task.id)
        .then(() => {
            alertSuccess(i18n.t("alerts.task_deleted"));
        })
        .catch(() => {
            alertError(i18n.t("alerts.task_delete_error"));
        });

    tasks.value.splice(tasks.value.indexOf(task), 1);
}

function onChangeSortType() {
    reSortTasks();
}

function onChangeSortReverse() {
    reSortTasks();
}

function onShare() {
    shareLink(
        `Tout Doux - ${list.value ?? ''}`,
        i18n.t('share_text'),
        `${document.location.href.split('?')[0] ?? ''}?lang=${i18n.locale.value}`
    )
        .then((viaShare) => {
            if (!viaShare) {
                alertSuccess(i18n.t("alerts.share_clipboard"));
            }
        })
        .catch(() => {
            alertError(i18n.t("alerts.share_error"))
        });
}

function updateTitle() {
    if (list.value !== null) {
        document.title = `Tout Doux - ${list.value} (${completedCount.value.toFixed(0)}/${taskCount.value.toFixed(0)})`
    }
}

onBeforeMount(() => {
    list.value = (route.params.list as string).slice(0, 128);
    fetchTasks();
});

onBeforeRouteUpdate((to) => {
    list.value = (to.params.list as string).slice(0, 128);
    fetchTasks();
});
</script>

<template>
    <div class="list-row italic text-sm font-extralight self-center">
        {{ list }}
        <span v-if="taskCount">({{ completedCount }} / {{ taskCount }})</span>
    </div>
    <ul class="list">
        <template v-for="(task, i) in tasks" :key="task.id">
            <li v-if="tasks[i] && (!separateCompleted || !taskCompleted(task))">
                <task-item
                    v-model="tasks[i]"
                    :show-last-checked="showLastChecked"
                    :show-next-reset="showNextReset"
                    @updated="updateTitle"
                    @clone="onCloneTask"
                    @delete="onDeleteTask"
                />
            </li>
        </template>
        <li
            v-if="!loading && empty"
            class="list-row italic text-xl font-extralight self-center"
        >
            <span
                ><search-icon class="inline" />
                <span v-html="$t('empty_hint')"></span
            ></span>
        </li>
        <li
            v-else-if="!loading && allCompleted && separateCompleted"
            class="list-row italic text-xl font-extralight self-center"
        >
            <span
                ><check-check-icon class="inline" />
                <span v-html="$t('all_completed_hint')"></span
            ></span>
        </li>
        <li class="list-row">
            <div class="list-col-grow">
                <input
                    v-model="taskInput"
                    type="text"
                    :placeholder="$t('new_task_hint')"
                    class="input w-full"
                    @keyup.enter="onNewTask"
                />
            </div>
            <div>
                <button
                    class="btn btn-square"
                    :disabled="loading || taskInput.trim().length === 0"
                    @click="onNewTask"
                >
                    <circle-plus-icon />
                </button>
            </div>
        </li>
    </ul>
    <div
        v-if="separateCompleted && hasCompleted"
        class="collapse collapse-arrow"
    >
        <input id="completed-dropdown" type="checkbox" />
        <div class="collapse-title mb-0">
            <circle-check-big-icon class="inline" :size="24" />
            {{ $t("completed") }} ({{ completedCount }})
        </div>
        <div class="collapse-content p-0">
            <ul class="list">
                <template
                    v-for="(task, i) in tasks"
                    :key="`${task.id}-completed`"
                >
                    <li v-if="tasks[i] && taskCompleted(task)">
                        <task-item
                            v-model="tasks[i]"
                            :show-last-checked="showLastChecked"
                            :show-next-reset="showNextReset"
                            @clone="onCloneTask"
                            @delete="onDeleteTask"
                        />
                    </li>
                </template>
            </ul>
        </div>
    </div>
    <div>
        <button class="btn btn-sm px-4" @click="onShare">
            <share-2-icon class="inline" :size="16" /> {{ $t('share_button') }}
        </button>
    </div>
    <div class="collapse collapse-arrow font-light text-sm">
        <input id="options-dropdown" type="checkbox" />
        <div class="collapse-title">
            <settings-2-icon class="inline" :size="16" />
            {{ $t("options.title") }}
        </div>
        <div class="collapse-content">
            <fieldset class="fieldset flex flex-col gap-2">
                <label class="label">
                    <arrow-down-up-icon class="inline" />
                    {{ $t("options.sort_by") }}
                    <select
                        v-model="sortType"
                        class="select"
                        @change="onChangeSortType"
                    >
                        <option :value="SortType.CREATED_AT">
                            {{ $t("options.sort.created_at") }}
                        </option>
                        <option :value="SortType.UPDATED_AT">
                            {{ $t("options.sort.updated_at") }}
                        </option>
                        <option :value="SortType.CHECK_DATE">
                            {{ $t("options.sort.check_date") }}
                        </option>
                        <option :value="SortType.RESET_DATE">
                            {{ $t("options.sort.reset_date") }}
                        </option>
                        <option :value="SortType.NAME">
                            {{ $t("options.sort.name") }}
                        </option>
                    </select>
                </label>
                <label class="label">
                    <input
                        v-model="sortReverse"
                        type="checkbox"
                        class="checkbox"
                        @change="onChangeSortReverse"
                    />
                    {{ $t("options.reverse_sort") }}
                </label>
                <label class="label">
                    <input
                        v-model="showLastChecked"
                        type="checkbox"
                        class="checkbox"
                    />
                    {{ $t("options.last_checked") }}
                </label>
                <label class="label">
                    <input
                        v-model="showNextReset"
                        type="checkbox"
                        class="checkbox"
                    />
                    {{ $t("options.next_reset") }}
                </label>
                <label class="label">
                    <input
                        v-model="separateCompleted"
                        type="checkbox"
                        class="checkbox"
                    />
                    {{ $t("options.separate_completed") }}
                </label>
            </fieldset>
        </div>
    </div>
</template>
