<template>
    <v-row no-gutters>
        <TableMain :headers="headers" :items="paginatePlaceholderItem" v-model:search="searchInput"
            :loading="getAnnouncementPending" :page="page" :pages="pages" :pageRange="pageRange"
            @refresh="getAnnouncementsRefresh" :show-header="APP_CONSTANTS.RESIDENT === props.recipients" @update:page="handleUpdatePage" @row-click="handleRowClick"
            @create="handleCreateEvent" :can-create="canCreateBulletinBoard" create-label="Add Announcement">
            <template #extension>
                <v-row no-gutters class="w-100 d-flex flex-column">
                    <v-tabs v-model="status" color="primary" :height="40" @update:model-value="toRoute" class="w-100">
                        <v-tab v-for="tab in tabOptions" :value="tab.status" :key="tab.status" class="text-capitalize">
                            {{ tab.name }}
                        </v-tab>
                    </v-tabs>
                </v-row>
            </template>

            <template v-slot:item.createdAt="{ item }">
                <span class="d-flex align-center ga-2">
                    <v-icon icon="mdi-calendar-start" color="green" size="20" />
                    <span class="text-capitalize">{{ toLocalDate(item.createdAt) || "-" }}</span>
                </span>

            </template>

            <template v-slot:item.noExpiration="{ item }">
                <BulletinExpirationChip :value="item?.noExpiration" />
            </template>

            <template v-slot:item.duration="{ item }">
                <span class="d-flex align-center ga-2">
                    <v-icon icon="mdi-calendar-start" color="green" size="20" />
                    <span class="text-capitalize">{{ toLocalDate(item.startDate) || "-" }}</span>
                </span>
                <span class="d-flex align-center ga-2">
                    <v-icon icon="mdi-calendar-end" color="red" size="20" />
                    <span class="text-capitalize">{{ toLocalDate(item.endDate) || "_" }}</span>
                </span>
            </template>
        </TableMain>

        <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" style="z-index: 3000;" />

        <v-dialog v-model="dialog.showForm" width="600" persistent>
            <BulletinBoardForm :mode="mode" :site-id="siteId" :active-id="selectedAnnouncementId"
                @close="dialog.showForm = false" @done="handleDone" />
        </v-dialog>

        <v-dialog v-model="dialog.moreActions" v-if="activeAnnouncementObj && canViewBulletinBoardDetails" width="600"
            persistent>
            <BulletinBoardView :active-announcement="activeAnnouncementObj" :can-delete="canDeleteBulletinBoard"
                :can-update="canUpdateBulletinBoard" @edit="handleEditAnnouncement" @close="dialog.moreActions = false"
                @delete="dialog.deletePrompt = true" />
        </v-dialog>

        <v-dialog v-model="dialog.deletePrompt" width="450" persistent>
            <CardDeleteConfirmation prompt-title="Are you sure want to delete this announcement?"
                :loading="loading.deletingAnnouncement" @close="dialog.deletePrompt = false"
                @delete="handleProceedDeleteAnnouncement" />
        </v-dialog>
    </v-row>
</template>
<script setup lang="ts">
import useBulletin from '../composables/useBulletin';
import { APP_CONSTANTS } from '../constants/app';

definePageMeta({
    memberOnly: true,
})

const props = defineProps({
    siteId: {
        type: String,
        required: true
    },
    canCreateBulletinBoard: {
        type: Boolean,
        default: true
    },
    canUpdateBulletinBoard: {
        type: Boolean,
        default: true
    },
    canViewBulletinBoardDetails: {
        type: Boolean,
        default: true
    }, canDeleteBulletinBoard: {
        type: Boolean,
        default: true
    },
    recipients: {
        type: String,
        default: "",
        required: false
    }
})


const { authenticate } = useLocalAuth();
authenticate();

const route = useRoute();
const orgId = route.params.org as string;
const siteId = props.siteId;
const routeName = (useRoute().name as string) ?? "";
const { getAll, deleteBulletinById } = useBulletin()
const { debounce } = useUtils()



const headers = computed(() => {
    const arr = [
        { title: "Title", value: "title", align: "start" },
    ]

    if (props.recipients === APP_CONSTANTS.RESIDENT) {
        arr.push({ title: "Date Created", value: "createdAt", align: "start" });
        arr.push({ title: "Start Date/End Date", value: "duration", align: "start" });
        arr.push({ title: "No Expiration", value: "noExpiration", align: "start" });
        arr.push({ title: "", value: "actions", align: "center" });
    }

    return arr;

});
const items = ref<TAnnouncement[]>([]);
const page = ref(1);
const pages = ref(0);
const pageRange = ref("-- - -- of --");
const selectedAnnouncementId = ref<string>("")
const mode = ref<'add' | 'edit'>('add')
const status = ref<TAnnouncementStatus>()
const searchInput = ref('')

const dialog = reactive({
    showForm: false,
    moreActions: false,
    viewDetails: false,
    deletePrompt: false,
})

const loading = reactive({
    deletingAnnouncement: false
})

const messageSnackbar = ref(false)
const message = ref('')
const messageColor = ref<'success' | 'error' | 'info'>()

const activeAnnouncementObj = computed(() => {
    return items.value.find(x => x._id === selectedAnnouncementId.value)
})

const paginatePlaceholderItem = computed(() => {
    const pageSize = 10
    const total = items.value.length
    const currentPage = page.value

    const start = (currentPage - 1) * pageSize
    const end = start + pageSize

    const from = total === 0 ? 0 : start + 1
    const to = Math.min(end, total)
    pageRange.value = `${from}-${to} of ${total}`

    pages.value = Math.ceil(total / pageSize)

    return items.value.slice(start, end)
})


const {
    data: getAnnouncementReq,
    refresh: getAnnouncementsRefresh,
    pending: getAnnouncementPending,
} = await useLazyAsyncData(
    `get-all-announcements-${page.value}`,
    () => getAll({ page: page.value, site: siteId, status: status.value, recipients: props.recipients ?? "" }),
    {
        watch: [page, () => route.query],
    }
);

watch(getAnnouncementReq, (newVal) => {
    items.value = newVal?.items || [];
    pages.value = newVal?.pages || 0;
    pageRange.value = newVal?.pageRange || "-- - -- of --";
});


function eventStatusFormat(status: any) {
    switch (status) {
        case 'In Progress':
            return {
                color: 'orange',
                text: 'In Progress'
            };
        case 'Active':
            return {
                color: 'green',
                text: status
            }
        case 'Scheduled':
            return {
                color: 'blue',
                text: status
            }
        default:
            return {
                color: 'grey',
                text: status
            }
    }
}

const tabOptions = [
    { name: "Active", status: "active" },
    { name: "Upcoming", status: "upcoming" },
    { name: "Expired", status: "expired" },
];

function toRoute(status: any) {
    const obj = tabOptions.find((x) => x.status === status);
    if (!obj) return;
    page.value = 1
    navigateTo({
        name: routeName,
        params: {
            org: orgId,
        },
        query: {
            status: obj.status,
        },
    });
}

function toLocalDate(utcString: string) {
    if (!utcString) return ""
    return new Date(utcString).toLocaleString("en-US", {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
    })
}

function handleRowClick(data: any) {
    selectedAnnouncementId.value = data?.item?._id;
    dialog.moreActions = true;
}

function handleUpdatePage(newPageNum: number) {
    page.value = newPageNum;
}

function handleClose() {
    dialog.showForm = false;

}

function handleFormDone() {
    getAnnouncementsRefresh();
    dialog.showForm = false;
}

function handleFormCreateMore() {
    getAnnouncementsRefresh();
}

function handleCreateEvent() {
    selectedAnnouncementId.value = ""
    mode.value = 'add'
    dialog.showForm = true;
}

function handleDeleteAnnouncement() {
    dialog.moreActions = false;
    dialog.showForm = false;
    dialog.deletePrompt = true;
}

function handleEditAnnouncement() {
    dialog.moreActions = false
    mode.value = "edit"
    dialog.showForm = true;
}

function showMessage(text: string, type: "error" | 'success' | 'info') {
    messageSnackbar.value = true;
    message.value = text;
    messageColor.value = type
}





async function handleProceedDeleteAnnouncement() {
    try {
        loading.deletingAnnouncement = true;
        const bulletinId = selectedAnnouncementId.value;
        const res = await deleteBulletinById(bulletinId as string);
        if (res) {
            showMessage("Announcement successfully deleted!", "info");
            await getAnnouncementsRefresh();
            dialog.deletePrompt = false;
        }
    } catch (error: any) {
        const errorMessage = error?.response?._data?.message;
        console.log("[ERROR]", error);
        showMessage(
            errorMessage || "Something went wrong. Please try again later.",
            "error"
        );
    } finally {
        loading.deletingAnnouncement = false;
    }
}




async function handleDone() {
    await getAnnouncementsRefresh()
    dialog.showForm = false
}


const debounceSearch = debounce(getAnnouncementsRefresh, 500)

watch([searchInput], ([search]) => {
    debounceSearch()
})


onMounted(() => {
    const statusQuery = (useRoute()?.query?.status)
    status.value = (statusQuery === "active" || statusQuery === "upcoming" || statusQuery === "expired") ? statusQuery : "active"
})

</script>