import { Host, h } from "@stencil/core";
import { ZIconButton } from "../internal-component/z-icon-button";
import { useTranslation } from "../../utils/utils";
import { getPriorityConfig, getBusinessUser } from "./utils";
import { displayDate } from "../../utils/dayjs";
import { CUSTOM_FIELD_CONFIG_TYPE, TICKET_PRIORITY, TICKET_STATUS_SETTING } from "../../store/zdesk.type";
import { selectedChatStore } from "../../store/store";
import { getConnectionId, getConnectionItem } from "../../utils/func";
import { getTicketCustomField, getTicketCustomFieldConfigs, patchTicketCustomField, postTicketCustomField, deleteTicketFollowing, createTicketFollowing, putTicket, putTransferTicket, getTicket, patchUpdateStatusTicket } from "../../api/zdesk/ticket";
import { handleError, openDialog, closeDialog } from "../../store/dialog";
import { ProfileTicketAction } from "./profile-ticket-action";
export class ProfileTicketDrawer {
    ticket;
    isOpen = false;
    close;
    ticketUpdated;
    drawerTab = 'ticket';
    editingStatus = false;
    showDialog = { open: false, type: 'input', saveType: 'ticket' };
    showAssignDialog = false;
    isCollapsed = false;
    isLoading = false;
    ticketCustomFieldConfigList = [];
    ticketCustomField = [];
    disposeListener;
    prevSelectedChat = null;
    componentShouldUpdate(newValue, oldValue, propName) {
        if (propName === 'ticket') {
            const newTicket = newValue;
            const oldTicket = oldValue;
            return newTicket?.id !== oldTicket?.id || JSON.stringify(newTicket) !== JSON.stringify(oldTicket);
        }
        return newValue !== oldValue;
    }
    async componentWillLoad() {
        this.disposeListener = selectedChatStore.onChange('selectedChat', async (newChat) => {
            if (!newChat) {
                this.ticketCustomFieldConfigList = [];
                this.ticketCustomField = [];
                return;
            }
            if (newChat.id !== (this.prevSelectedChat ? this.prevSelectedChat.id : '')) {
                await this.loadTicketCustomField();
                this.prevSelectedChat = newChat;
            }
        });
        if (selectedChatStore.get('selectedChat')) {
            await this.loadTicketCustomField();
        }
    }
    disconnectedCallback() {
        if (this.disposeListener)
            this.disposeListener();
    }
    async loadTicketCustomField() {
        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 [ticketCustomFieldConfigs, ticketCustomField] = await Promise.all([
                getTicketCustomFieldConfigs({ connectionId }, {
                    page: 1,
                    limit: 1000,
                    order_by: 'order_index',
                    business_id: businessUser.business_id,
                }),
                getTicketCustomField({ connectionId }, {
                    ticket_id: this.ticket.id.toString(),
                    business_id: businessUser.business_id,
                })
            ]);
            this.ticketCustomFieldConfigList = ticketCustomFieldConfigs.data.filter(item => item.is_show);
            this.ticketCustomField = ticketCustomField.data;
        }
        catch (error) {
            handleError(error, 'Failed to load Tickets');
        }
        finally {
            this.isLoading = false;
        }
    }
    handleTabClick = (tabId) => {
        this.drawerTab = tabId;
    };
    renderDrawerTabs() {
        const t = useTranslation();
        const tabs = [
            { id: 'ticket', label: t('ticket_field.ticket') },
            { id: 'comments', label: t('ticket_field.comments') },
            { id: 'history', label: t('ticket_field.history') }
        ];
        return (h("div", { class: "mx-4" }, h("div", { class: "drawer-tabs" }, tabs.map(tab => (h("button", { key: tab.id, class: `tab-button ${this.drawerTab === tab.id ? 'tab-active' : 'tab-inactive'}`, onClick: () => this.handleTabClick(tab.id) }, tab.label))))));
    }
    handleOpenDialogEditor = async (data) => {
        this.showDialog = { open: true, ...data };
    };
    handleCloseDialogEditor = () => {
        this.showDialog = { open: false };
    };
    handleSaveDialogEditor = async (saveType, field, value) => {
        try {
            if (saveType === 'custom-field') {
                await this.handleUpdateTicketCustomField(field, value);
            }
            if (saveType === 'ticket') {
                await this.handleUpdateTicket(field, value);
            }
            this.handleCloseDialogEditor();
        }
        catch (error) {
            handleError(error, 'Failed to update ticket');
        }
    };
    handleCloseAssignDialog = () => {
        this.showAssignDialog = false;
    };
    handleSubmitAssignDialog = async (event) => {
        const { business_group_id, business_user_id, comment, isFollowing } = event.detail;
        try {
            if (!this.ticket)
                return;
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await putTransferTicket({ connectionId }, {
                data: {
                    ids: [this.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();
            // Reload ticket immediately
            const refreshedTicket = await getTicket({ connectionId }, { ids: [this.ticket.id.toString()], business_id: businessUser.business_id });
            if (refreshedTicket.data && refreshedTicket.data.length > 0) {
                this.ticket = refreshedTicket.data[0];
                this.ticketUpdated.emit(this.ticket);
            }
        }
        catch (error) {
            handleError(error, 'Failed to transfer ticket');
        }
    };
    handleUpdateStatus = async (statusSetting) => {
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await patchUpdateStatusTicket({ connectionId }, {
                data: {
                    id: this.ticket.id,
                    business_id: businessUser.business_id,
                    status_id: statusSetting.id,
                },
            });
            this.ticket = {
                ...this.ticket,
                status: { ...this.ticket.status, id: statusSetting.id, ticket_status: statusSetting.ticket_status },
            };
            this.ticketUpdated.emit(this.ticket);
        }
        catch (error) {
            handleError(error, 'Failed to update ticket status');
        }
    };
    handleUpdateTicketCustomField = async (field, value) => {
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            const ticketCustomFieldConfig = this.ticketCustomFieldConfigList.find((item) => item.key === field);
            if (!ticketCustomFieldConfig)
                return;
            const ticketCustomField = this.ticketCustomField.find((item) => item.custom_field_config_id === ticketCustomFieldConfig.id);
            const selectedOption = ticketCustomFieldConfig.options?.find((item) => item.value === value);
            const saveValue = { value: selectedOption || value };
            if (ticketCustomField) {
                await patchTicketCustomField({ connectionId }, {
                    business_id: businessUser.business_id,
                    id: ticketCustomField.id,
                    value: saveValue
                });
                this.ticketCustomField = this.ticketCustomField.map((item) => item.id === ticketCustomField.id ? { ...item, value: saveValue } : item);
            }
            else {
                const response = await postTicketCustomField({ connectionId }, {
                    business_id: businessUser.business_id,
                    ticket_id: this.ticket.id,
                    custom_field_config_id: ticketCustomFieldConfig.id,
                    value: saveValue
                });
                this.ticketCustomField = [...this.ticketCustomField, response];
            }
        }
        catch (error) {
            handleError(error, 'Failed to update ticket custom field');
        }
    };
    handleUpdateTicket = async (field, value) => {
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await putTicket({ connectionId }, {
                data: {
                    id: this.ticket.id,
                    business_id: businessUser.business_id,
                    [field]: value,
                }
            });
            this.ticket = {
                ...this.ticket,
                ...(field === 'status' ? { status: { ...this.ticket.status, ticket_status: value } } : { [field]: value })
            };
            this.ticketUpdated.emit(this.ticket);
        }
        catch (error) {
            handleError(error, 'Failed to update ticket');
            throw error;
        }
    };
    handleUpdateTicketTags = async (tags) => {
        try {
            const connectionItem = getConnectionItem();
            const connectionId = getConnectionId(connectionItem);
            const businessUser = getBusinessUser(connectionItem);
            if (!businessUser)
                return;
            await putTicket({ connectionId }, {
                data: {
                    id: this.ticket.id,
                    business_id: businessUser.business_id,
                    tags: tags,
                }
            });
            const existingTags = this.ticket.tags || [];
            this.ticket = {
                ...this.ticket,
                tags: tags.map(tag => {
                    const existing = existingTags.find(t => t.tag === tag);
                    if (existing)
                        return existing;
                    return {
                        id: '',
                        ticket_id: this.ticket.id.toString(),
                        business_id: businessUser.business_id,
                        channel_id: this.ticket.channel_id,
                        tag: tag,
                        tag_id: '',
                        created_at: new Date().toISOString(),
                        create_by: businessUser.id || ''
                    };
                })
            };
            this.ticketUpdated.emit(this.ticket);
        }
        catch (error) {
            handleError(error, 'Failed to update ticket tags');
            throw error;
        }
    };
    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.ticket = {
                    ...this.ticket,
                    ticket_followings: this.ticket.ticket_followings.filter(f => f.business_user_id !== ticket.business_user.id)
                };
                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.ticket = {
                    ...this.ticket,
                    ticket_followings: [
                        ...(this.ticket.ticket_followings || []),
                        { business_user_id: ticket.business_user.id }
                    ]
                };
                openDialog({
                    open: true,
                    type: "SUCCESS" /* DIALOG_TYPE.SUCCESS */,
                    title: 'ติดตามสำเร็จ',
                    onCloseDialog: closeDialog,
                });
            }
        }
        catch (error) {
            handleError(error, 'Failed to update ticket following');
        }
    };
    isAllowEmpty = (field) => {
        return ['description'].includes(field);
    };
    handleClose = () => {
        this.close.emit();
    };
    handleBackdropClick = (e) => {
        e.stopPropagation();
        this.close.emit();
    };
    handleContainerClick = (e) => {
        e.stopPropagation();
    };
    handleToggleCollapse = () => {
        this.isCollapsed = !this.isCollapsed;
    };
    render() {
        const t = useTranslation();
        if (!this.ticket)
            return null;
        const priorityConfig = getPriorityConfig(this.ticket.priority);
        const renderDetailRow = ({ showEdit = true, customValue, saveType = 'ticket', onEdit, ...data }) => {
            return (h("div", { class: "detail-row" }, h("span", { class: "detail-label" }, data.label), h("div", { class: "detail-value-container" }, customValue ? customValue : h("span", { class: "detail-value" }, String(data.value || '-')), showEdit &&
                h(ZIconButton, { variant: "text", iconName: "Pencil", addClassIcon: "size-4 text-primary", noPadding: true, noPaddingY: true, disabled: data.field === 'assignee' && [TICKET_STATUS_SETTING.CANCELED, TICKET_STATUS_SETTING.CLOSED].includes(this.ticket.status.ticket_status) ? true : false, onClick: () => {
                        if (onEdit) {
                            onEdit();
                        }
                        else {
                            this.handleOpenDialogEditor({ ...data, saveType });
                        }
                    } }))));
        };
        return (h(Host, null, h("div", { class: "absolute inset-0 z-50 flex items-end justify-center bg-black/40", onClick: this.handleBackdropClick }, h("div", { class: "drawer-container z-animate-width", onClick: this.handleContainerClick }, h("div", { class: "drawer-header" }, h("div", { class: "text-right" }, h(ZIconButton, { iconName: "X", variant: "none", addClassIcon: "size-5", noPadding: true, noPaddingY: true, onClick: this.handleClose })), h("span", { class: "text-lg font-bold text-surface" }, "#", this.ticket.id), h("div", { class: "absolute right-2 top-10 flex items-center gap-1" }, h(ProfileTicketAction, { ticket: this.ticket, addClassIcon: "size-5 text-primary", onFollowClick: (isFollowing) => this.handleFollowToggle(this.ticket, isFollowing) }))), h("div", { class: "drawer-content scroll-container pt-0 flex flex-col h-full" }, h("div", { class: "flex-none" }, this.renderDrawerTabs()), this.drawerTab === 'ticket' && (h("div", { class: "flex-1 overflow-y-auto px-4" }, h("div", { class: "space-y-6 pb-20" }, h("div", { class: "space-y-1 border-b border-divider" }, renderDetailRow({
            label: t('ticket_field.subject'),
            field: 'subject',
            value: this.ticket.subject || '-',
            customValue: h("span", { class: "detail-value" }, this.ticket.subject || '-')
        }), renderDetailRow({
            label: t('ticket_field.status'),
            field: 'status',
            value: this.ticket.status.ticket_status,
            showEdit: false,
            customValue: (h("ticket-status-field", { statusId: this.ticket.status.id, ticketStatus: this.ticket.status.ticket_status, statusName: this.ticket.status.status, referenceKey: `drawer-${this.ticket.id}`, editMode: this.editingStatus, onStartEdit: () => { this.editingStatus = true; }, onCancelEdit: () => { this.editingStatus = false; }, onStatusChanged: (e) => {
                    this.editingStatus = false;
                    if (!e.detail.isClosing) {
                        this.handleUpdateStatus({ id: e.detail.id, ticket_status: e.detail.ticket_status });
                    }
                } }))
        }), renderDetailRow({
            label: t('ticket_field.priority'),
            field: 'priority',
            value: this.ticket.priority,
            type: CUSTOM_FIELD_CONFIG_TYPE.DROPDOWN,
            options: Object.values(TICKET_PRIORITY).map((priority) => ({
                label: t(`ticket_priority.${priority}`),
                value: priority,
            })),
            customValue: (h("div", { class: "flex items-center gap-2" }, h("span", { class: `size-2.5 rounded-full ${priorityConfig.color}` }), h("span", { class: "text-surface text-sm" }, priorityConfig.label)))
        }), renderDetailRow({
            label: t('ticket_field.due_date'),
            field: 'due_date',
            value: this.ticket.due_date,
            type: CUSTOM_FIELD_CONFIG_TYPE.DATE,
            customValue: h("span", { class: "detail-value" }, displayDate(this.ticket.due_date))
        }), renderDetailRow({
            label: t('ticket_field.assignee'),
            field: 'assignee',
            value: this.ticket.business_user.display_name || '-',
            onEdit: () => this.showAssignDialog = true,
            customValue: (h("div", { class: "flex items-center gap-2" }, h("span", { class: "text-surface text-sm" }, this.ticket.business_user.display_name || '-')))
        })), h("profile-ticket-tags", { ticket: this.ticket, onTicketTagsUpdated: (e) => this.handleUpdateTicketTags(e.detail) }), h("div", { class: "border-b border-divider my-2" }), h("div", { class: "space-y-4" }, h("div", { class: "drawer-tabs" }, h("button", { class: "tab-button tab-active" }, t('ticket_field.additional_info')), h("div", { class: "ml-auto" }, h(ZIconButton, { iconName: this.isCollapsed ? 'ChevronDown' : 'ChevronUp', onClick: this.handleToggleCollapse, variant: 'none' }))), !this.isCollapsed &&
            h("div", { class: "space-y-1" }, this.ticketCustomFieldConfigList
                .sort((a, b) => a.order_index - b.order_index)
                .map(customFieldConfig => {
                const itemField = this.ticketCustomField.find(field => field.custom_field_config_id === customFieldConfig.id)?.value;
                let labelValue = '';
                let value = '';
                let customValue = null;
                if (itemField) {
                    if (typeof itemField.value === 'number') {
                        itemField.value = itemField.value.toString();
                    }
                    if (typeof itemField.value === 'string') {
                        labelValue = customFieldConfig.type === CUSTOM_FIELD_CONFIG_TYPE.DATE ? displayDate(itemField.value) : itemField.value;
                        value = itemField.value;
                    }
                    else if (Array.isArray(itemField.value)) {
                        if (customFieldConfig.type === CUSTOM_FIELD_CONFIG_TYPE.FILE) {
                            labelValue = itemField.value.map(item => item.name).join(', ');
                            value = itemField.value.map(item => item.url);
                            customValue = (h("div", { class: "flex flex-col gap-2" }, itemField.value.map(item => (h("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", class: "text-sm text-primary underline" }, item.name)))));
                        }
                        else {
                            labelValue = itemField.value.map(item => item.label).join(', ');
                            value = itemField.value.map(item => item.value);
                        }
                    }
                    else if (typeof itemField.value === 'object') {
                        labelValue = itemField.value?.label || '';
                        value = itemField.value?.value || '';
                    }
                }
                return renderDetailRow({
                    label: customFieldConfig.name,
                    field: customFieldConfig.key,
                    value: value,
                    type: customFieldConfig.type,
                    customValue: customValue ? customValue : h("span", { class: "detail-value" }, labelValue),
                    options: customFieldConfig.options,
                    saveType: 'custom-field'
                });
            })))))), this.drawerTab === 'history' && h("profile-ticket-activities", { class: "flex-1 min-h-0", ticketId: this.ticket?.id }), this.drawerTab === 'comments' && h("profile-ticket-comments", { class: "flex-1 min-h-0", ticketId: this.ticket?.id, businessUserId: this.ticket?.business_user_id })))), this.showDialog.open && (h("div", { class: "dialog-backdrop", onClick: (e) => e.stopPropagation() }, h("dialog-editor", { 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.saveType, this.showDialog.field, event ? event.detail : undefined), options: this.showDialog.options }))), this.showAssignDialog && (h("profile-ticket-assign-dialog", { ticket: this.ticket, isOpen: this.showAssignDialog, onClose: this.handleCloseAssignDialog, onSubmitAssign: this.handleSubmitAssignDialog }))));
    }
    static get is() { return "profile-ticket-drawer"; }
    static get originalStyleUrls() {
        return {
            "$": ["profile-ticket-drawer.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["profile-ticket-drawer.css"]
        };
    }
    static get properties() {
        return {
            "ticket": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "ITicket",
                    "resolved": "ITicket",
                    "references": {
                        "ITicket": {
                            "location": "import",
                            "path": "../../store/zdesk.type",
                            "id": "src/store/zdesk.type.ts::ITicket",
                            "referenceLocation": "ITicket"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false
            },
            "isOpen": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "is-open",
                "defaultValue": "false"
            }
        };
    }
    static get states() {
        return {
            "drawerTab": {},
            "editingStatus": {},
            "showDialog": {},
            "showAssignDialog": {},
            "isCollapsed": {},
            "isLoading": {},
            "ticketCustomFieldConfigList": {},
            "ticketCustomField": {}
        };
    }
    static get events() {
        return [{
                "method": "close",
                "name": "close",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "void",
                    "resolved": "void",
                    "references": {}
                }
            }, {
                "method": "ticketUpdated",
                "name": "ticketUpdated",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "ITicket",
                    "resolved": "ITicket",
                    "references": {
                        "ITicket": {
                            "location": "import",
                            "path": "../../store/zdesk.type",
                            "id": "src/store/zdesk.type.ts::ITicket",
                            "referenceLocation": "ITicket"
                        }
                    }
                }
            }];
    }
}
