import { Host, h } from "@stencil/core";
import { selectedChatStore, businessStore } from "../../store/store";
import { ZIconButton } from "../internal-component/z-icon-button";
import { Icon } from "../internal-component/icon";
import { useTranslation } from "../../utils/utils";
import { handleError, openDialog, closeDialog } from "../../store/dialog";
import { getPriorityConfig, getBusinessUser } from "./utils";
import { CUSTOM_FIELD_CONFIG_TYPE, MESSAGE_TYPE, PAGINATION_PAGE_LIMIT, PaginationOrder, TICKET_PRIORITY, TICKET_STATUS_SETTING } from "../../store/zdesk.type";
import { getTicket, createTicketFollowing, deleteTicketFollowing, putTicket, putTransferTicket, patchUpdateStatusTicket, postTicketComment } from "../../api/zdesk/ticket";
import { getConnectionId, getConnectionItem } from "../../utils/func";
import { debounce } from "../../utils/helpers";
import { ProfileTicketAction } from "./profile-ticket-action";
import { displayDate } from "../../utils/dayjs";
export class ProfileTicket {
    el;
    ticketList = [];
    isLoading = false;
    page = 1;
    totalPage = 1;
    hasNextPage = true;
    expandedTicketIds = new Set();
    showDialog = { open: false };
    showDialogDetails = { open: false };
    showAssignDialog = { open: false };
    editingStatusTicketId = null;
    showCloseNoteDialog = { open: false };
    disposeListener;
    prevSelectedChat = null;
    async componentWillLoad() {
        this.disposeListener = selectedChatStore.onChange('selectedChat', async (newChat) => {
            if (!newChat) {
                this.ticketList = [];
                return;
            }
            if (newChat.id !== (this.prevSelectedChat ? this.prevSelectedChat.id : '')) {
                await this.loadTickets(true);
                this.prevSelectedChat = newChat;
            }
        });
        if (selectedChatStore.get('selectedChat')) {
            await this.loadTickets(true);
        }
    }
    disconnectedCallback() {
        if (this.disposeListener)
            this.disposeListener();
    }
    async loadTickets(reset = false) {
        if (this.isLoading && !reset)
            return;
        if (reset) {
            this.ticketList = [];
            this.page = 1;
            this.hasNextPage = true;
        }
        if (!this.hasNextPage)
            return;
        const selectedChat = selectedChatStore.get('selectedChat');
        if (!selectedChat)
            return;
        const connectionItem = getConnectionItem();
        const connectionId = getConnectionId(connectionItem);
        const businessUser = getBusinessUser(connectionItem);
        if (!businessUser)
            return;
        try {
            this.isLoading = true;
            const ticket = await getTicket({ connectionId }, {
                page: this.page,
                limit: PAGINATION_PAGE_LIMIT,
                order: PaginationOrder.DESC,
                order_by: 'updated_at',
                business_id: businessUser.business_id,
                business_user_id: businessUser.id,
                customer_id: selectedChat.user.id,
            });
            this.ticketList = [...this.ticketList, ...ticket.data];
            this.hasNextPage = ticket.meta.has_next_page;
            this.page++;
        }
        catch (error) {
            handleError(error, 'Failed to load Tickets');
        }
        finally {
            this.isLoading = false;
        }
    }
    toggleTicketExpand = (ticketId) => {
        const newSet = new Set(this.expandedTicketIds);
        if (newSet.has(ticketId)) {
            newSet.delete(ticketId);
        }
        else {
            newSet.add(ticketId);
        }
        this.expandedTicketIds = newSet;
    };
    handleOpenDialogEditor = async ({ label, field, value, type = 'input', options, ticketId }) => {
        this.showDialog = { open: true, type, label, field, value, options, ticketId };
    };
    handleCloseDialogEditor = () => {
        this.showDialog = { open: false };
    };
    handleSaveDialogEditor = async (field, value) => {
        try {
            console.log('handleSaveDialogEditor', field, value);
            if (['subject', 'priority', 'due_date'].includes(field) && this.showDialog.ticketId) {
                const ticket = this.ticketList.find(t => t.id === this.showDialog.ticketId);
                if (ticket) {
                    const connectionItem = getConnectionItem();
                    const connectionId = getConnectionId(connectionItem);
                    const businessUser = getBusinessUser(connectionItem);
                    if (businessUser) {
                        await putTicket({ connectionId }, {
                            data: {
                                id: ticket.id,
                                business_id: businessUser.business_id,
                                ...(field === 'priority' ? { priority: value } : {}),
                                ...(field === 'subject' ? { subject: value } : {}),
                                ...(field === 'due_date' ? { due_date: value } : {}),
                            },
                        });
                        this.ticketList = this.ticketList.map(t => {
                            if (t.id === ticket.id) {
                                return { ...t, [field]: value };
                            }
                            return t;
                        });
                    }
                }
            }
            this.handleCloseDialogEditor();
        }
        catch (error) {
            handleError(error, 'Failed to update ticket');
        }
    };
    handleCloseAssignDialog = () => {
        this.showAssignDialog = { open: false };
    };
    handleOpenCloseNoteDialog = (ticketId) => {
        this.showCloseNoteDialog = { open: true, id: ticketId };
    };
    handleCloseNoteDialog = () => {
        this.showCloseNoteDialog = { open: false };
    };
    handleSaveCloseNote = async (note) => {
        const ticketId = this.showCloseNoteDialog.id;
        const ticket = this.ticketList.find(t => t.id === ticketId);
        if (!ticket)
            return;
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            const closedSetting = businessStore.get('ticketStatusSettings').find(s => s.ticket_status === TICKET_STATUS_SETTING.CLOSED);
            await patchUpdateStatusTicket({ connectionId }, {
                data: {
                    id: ticket.id,
                    business_id: businessUser.business_id,
                    ...(closedSetting ? { status_id: closedSetting.id } : { ticket_status: TICKET_STATUS_SETTING.CLOSED }),
                },
            });
            if (note?.trim()) {
                // await putTicket(
                //   { connectionId },
                //   {
                //     data: {
                //       id: ticket.id,
                //       business_id: businessUser.business_id,
                //       note,
                //     },
                //   }
                // );
                await postTicketComment({ connectionId }, {
                    ticket_id: ticket.id,
                    business_id: businessUser.business_id,
                    business_user_id: ticket.business_user_id,
                    messages: {
                        type: MESSAGE_TYPE.TEXT,
                        text: note
                    }
                });
            }
            this.ticketList = this.ticketList.map(t => t.id === ticket.id
                ? { ...t, status: { ...t.status, ticket_status: TICKET_STATUS_SETTING.CLOSED } }
                : t);
            this.handleCloseNoteDialog();
            this.editingStatusTicketId = null;
        }
        catch (error) {
            handleError(error, 'Failed to close ticket');
        }
    };
    handleSubmitAssignDialog = async (event) => {
        const { business_group_id, business_user_id, comment, isFollowing } = event.detail;
        try {
            const ticket = this.ticketList.find(t => t.id === this.showAssignDialog.id);
            if (!ticket)
                return;
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await putTransferTicket({ connectionId }, {
                data: {
                    ids: [ticket.id],
                    business_id: businessUser.business_id,
                    business_group_id: business_group_id || null,
                    business_user_id: business_user_id || null,
                    ticket_following_business_user_id: isFollowing ? businessUser.id : undefined,
                    comment_messages: comment ? { type: 'text', text: comment } : undefined,
                }
            });
            openDialog({
                open: true,
                type: "SUCCESS" /* DIALOG_TYPE.SUCCESS */,
                title: 'มอบหมายสำเร็จ',
                onCloseDialog: closeDialog,
            });
            this.handleCloseAssignDialog();
            await this.loadTickets(true); // reload tickets to reflect changes
        }
        catch (error) {
            handleError(error, 'Failed to transfer ticket');
        }
    };
    handleFollowToggle = async (ticket, isFollowing) => {
        try {
            if (!ticket.business_user?.id)
                return;
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            if (isFollowing) {
                await deleteTicketFollowing({ connectionId }, {
                    ticket_id: ticket.id,
                    business_user_id: ticket.business_user.id
                });
                // Optimistically update the ticket list
                this.ticketList = this.ticketList.map(t => {
                    if (t.id === ticket.id) {
                        return {
                            ...t,
                            ticket_followings: t.ticket_followings.filter(f => f.business_user_id !== ticket.business_user.id)
                        };
                    }
                    return t;
                });
                openDialog({
                    open: true,
                    type: "SUCCESS" /* DIALOG_TYPE.SUCCESS */,
                    title: 'ยกเลิกติดตามสำเร็จ',
                    onCloseDialog: closeDialog,
                });
            }
            else {
                await createTicketFollowing({ connectionId }, {
                    ticket_id: ticket.id,
                    business_user_id: ticket.business_user.id
                });
                // Optimistically update the ticket list
                this.ticketList = this.ticketList.map(t => {
                    if (t.id === ticket.id) {
                        return {
                            ...t,
                            ticket_followings: [
                                ...(t.ticket_followings || []),
                                { business_user_id: ticket.business_user.id }
                            ]
                        };
                    }
                    return t;
                });
                openDialog({
                    open: true,
                    type: "SUCCESS" /* DIALOG_TYPE.SUCCESS */,
                    title: 'ติดตามสำเร็จ',
                    onCloseDialog: closeDialog,
                });
            }
        }
        catch (error) {
            handleError(error, 'Failed to update ticket following');
        }
    };
    handleOpenDialogDetailsEditor = async ({ id }) => {
        this.showDialogDetails = { open: true, id };
    };
    handleCloseDialogDetailsEditor = () => {
        this.showDialogDetails = { open: false };
    };
    // private handleSaveDialogDetailsEditor = async (field: string, value: string) => {
    //   console.log('handleSaveDialogDetailsEditor', field, value);
    //   // await handleUpdateUser(field, value);
    //   this.handleCloseDialogDetailsEditor();
    // };
    handleTicketUpdated = (event) => {
        const updatedTicket = event.detail;
        this.ticketList = this.ticketList.map(t => t.id === updatedTicket.id ? updatedTicket : t);
    };
    handleUpdateStatus = async (ticket, statusSetting) => {
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await patchUpdateStatusTicket({ connectionId }, {
                data: {
                    id: ticket.id,
                    business_id: businessUser.business_id,
                    status_id: statusSetting.id,
                },
            });
            this.ticketList = this.ticketList.map(t => t.id === ticket.id
                ? { ...t, status: { ...t.status, id: statusSetting.id, ticket_status: statusSetting.ticket_status } }
                : t);
        }
        catch (error) {
            handleError(error, 'Failed to update ticket status');
        }
    };
    isAllowEmpty = (field) => {
        return ['description'].includes(field);
    };
    renderTicketCard(ticket) {
        const t = useTranslation();
        const isExpanded = this.expandedTicketIds.has(ticket.id);
        const priorityConfig = getPriorityConfig(ticket.priority);
        const renderTicketDetail = (fieldName) => {
            const label = t(`ticket_field.${fieldName}`);
            let value = ticket[fieldName];
            if (fieldName === 'status') {
                value = ticket.status.ticket_status;
            }
            if (fieldName === 'assignee') {
                value = ticket.business_user.display_name || '-';
            }
            return (h("div", { class: "detail-row" }, h("span", { class: "detail-label" }, label), h("div", { class: "detail-value-container" }, !['status', 'priority'].includes(fieldName) &&
                h("span", { class: "detail-value" }, (fieldName === 'due_date' ? displayDate(value) : value) || '-'), fieldName === 'status' &&
                h("ticket-status-field", { statusId: ticket.status.id, ticketStatus: ticket.status.ticket_status, statusName: ticket.status.status, referenceKey: ticket.id, editMode: this.editingStatusTicketId === ticket.id, onStartEdit: () => {
                        this.editingStatusTicketId = ticket.id;
                    }, onCancelEdit: () => {
                        this.editingStatusTicketId = null;
                    }, onStatusChanged: (e) => {
                        if (e.detail.isClosing) {
                            this.handleOpenCloseNoteDialog(ticket.id);
                            return;
                        }
                        this.handleUpdateStatus(ticket, { id: e.detail.id, ticket_status: e.detail.ticket_status });
                        this.editingStatusTicketId = null;
                    } }), fieldName === 'priority' &&
                h("div", { class: "priority-badge" }, h("span", { class: `rounded-dot ${priorityConfig.color}` }), h("span", { class: "text-surface" }, priorityConfig.label)), fieldName !== 'status' &&
                h(ZIconButton, { variant: "text", iconName: "Pencil", addClassIcon: "size-4", noPadding: true, noPaddingY: true, disabled: fieldName === 'assignee' && [TICKET_STATUS_SETTING.CANCELED, TICKET_STATUS_SETTING.CLOSED].includes(ticket.status.ticket_status) ? true : false, onClick: () => {
                        if (fieldName === 'assignee') {
                            this.showAssignDialog = { open: true, id: ticket.id };
                            return;
                        }
                        let type = 'input';
                        let options = [];
                        if (fieldName === 'due_date') {
                            type = CUSTOM_FIELD_CONFIG_TYPE.DATE;
                        }
                        if (fieldName === 'description') {
                            type = 'textarea';
                        }
                        if (fieldName === 'priority') {
                            type = CUSTOM_FIELD_CONFIG_TYPE.DROPDOWN;
                            options = Object.values(TICKET_PRIORITY).map((priority) => ({
                                label: t(`ticket_priority.${priority}`),
                                value: priority,
                            }));
                        }
                        this.handleOpenDialogEditor({
                            label,
                            field: fieldName,
                            value,
                            type: type,
                            options: options,
                            ticketId: ticket.id
                        });
                    } }))));
        };
        return (h("div", { class: "ticket-card" }, h("div", { class: "ticket-header" }, h("div", { class: "ticket-header-left" }, h(ZIconButton, { iconName: "Menu", variant: "none", noPadding: true, noPaddingY: true, onClick: () => this.toggleTicketExpand(ticket.id) }), h("span", { class: "ticket-no" }, "#", ticket.id), h("span", { class: "ticket-title" }, ticket.subject || '-')), h("div", { class: "ticket-header-actions" }, h(ProfileTicketAction, { ticket: ticket, onFollowClick: (isFollowing) => this.handleFollowToggle(ticket, isFollowing) }))), isExpanded && (h("div", { class: "ticket-details" }, ['subject', 'status', 'priority', /*'description',*/ 'due_date', 'assignee'].map((field) => renderTicketDetail(field)), h("div", { class: "show-more-container" }, h("button", { class: "show-more-btn", onClick: () => this.handleOpenDialogDetailsEditor({ id: ticket.id }) }, t('show_more')))))));
    }
    handleScroll = debounce((e) => {
        const target = e.target;
        if (target.scrollTop + target.clientHeight >= target.scrollHeight - 50) {
            this.loadTickets();
        }
    }, 200);
    render() {
        const t = useTranslation();
        const hasItems = this.ticketList.length > 0;
        return (h(Host, { key: 'df47d7b3158fef3925974fa0d652dba388e77096' }, h("div", { key: 'b6a64cac91e1834de7408947df660fc0f468aef5', class: "profile-ticket" }, h("div", { key: 'b224f05bc73e9c996d5ec305ebb6699013924852', class: "flex justify-end mb-2 mr-2 h-6" }, this.isLoading ? (h(Icon, { name: "LoaderCircle", addClass: 'size-5 mr-1 text-primary animate-spin' })) : (h(ZIconButton, { variant: "text", iconName: "RotateCw", onClick: () => this.loadTickets(true) }))), !this.isLoading && !hasItems && (h("div", { key: '5c109df8aa02bb512f75c6ccb1e8d834cf20040f', class: "profile-ticket-empty" }, h("span", { key: '2b614dac99808cb3a44fa951b97b4e0701f05578', class: "text-sm" }, t('ticket_empty')))), hasItems && (h("div", { key: '90430c63b6d8df0d7f1ba4311d4f2e32c0d61286', class: "profile-ticket-wrapper", onScroll: (e) => this.handleScroll(e) }, h("div", { key: '2651a7a509cdeaf852a80eb984fba58ea1930555', class: "profile-ticket-list" }, this.ticketList.map(ticket => this.renderTicketCard(ticket)), this.isLoading && (h("div", { key: '6c2c4bc277f31bf55afd6faadad478cdfd33c219', class: "flex justify-center p-2 text-theme-gray w-full" }, h(Icon, { key: 'ca04f4c5d2fa7f55b9c57390339635ccc8931336', name: "Loader2", addClass: "animate-spin size-6" })))))), this.showDialogDetails.open && (h("profile-ticket-drawer", { key: 'c0532ab2950eb483c7a3f938d61e3d49f5d0c52d', ticket: this.ticketList.find(t => t.id === this.showDialogDetails.id), isOpen: this.showDialogDetails.open, onClose: this.handleCloseDialogDetailsEditor, onTicketUpdated: this.handleTicketUpdated }))), this.showDialog.open && (h("div", { key: '352158822dedc9fe035b9fad76bfbe4afc10c230', class: "dialog-backdrop" }, h("dialog-editor", { key: '77a278daf141a8147c045a6cca049d3aedace647', label: this.showDialog.label, dialogType: this.showDialog.type, field: this.showDialog.field, value: this.showDialog.value, allowEmpty: this.isAllowEmpty(this.showDialog.field), onCancel: this.handleCloseDialogEditor, onSave: (event) => this.handleSaveDialogEditor(this.showDialog.field, event ? event.detail : undefined), options: this.showDialog.options }))), this.showAssignDialog.open && (h("profile-ticket-assign-dialog", { key: 'fef025ea32749d6b9c59e80b6df29c41887009b2', ticket: this.ticketList.find(t => t.id === this.showAssignDialog.id), isOpen: this.showAssignDialog.open, onClose: this.handleCloseAssignDialog, onSubmitAssign: this.handleSubmitAssignDialog })), this.showCloseNoteDialog.open && (() => {
            const t = useTranslation();
            const ticket = this.ticketList.find(t => t.id === this.showCloseNoteDialog.id);
            return (h("div", { class: "dialog-backdrop" }, h("dialog-editor", { headerTitle: `${t('ticket_close_title')} #${ticket?.id}`, label: t('note'), dialogType: "textarea", field: "note", allowEmpty: true, onCancel: this.handleCloseNoteDialog, onSave: (event) => this.handleSaveCloseNote(event?.detail ?? '') })));
        })()));
    }
    static get is() { return "profile-ticket"; }
    static get originalStyleUrls() {
        return {
            "$": ["profile-ticket.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["profile-ticket.css"]
        };
    }
    static get states() {
        return {
            "ticketList": {},
            "isLoading": {},
            "page": {},
            "totalPage": {},
            "hasNextPage": {},
            "expandedTicketIds": {},
            "showDialog": {},
            "showDialogDetails": {},
            "showAssignDialog": {},
            "editingStatusTicketId": {},
            "showCloseNoteDialog": {}
        };
    }
    static get elementRef() { return "el"; }
}
