import { Fragment, Host, h } from "@stencil/core";
import { configStore, selectedChatStore, userStore } from "../../store/store";
import { /*createUserContext,*/ createUserStatus, createUserTag, getUser, mergeUser, unlinkUser, updateUser } from "../../api";
import { getCachedUser, persistUser } from "../../utils/cache";
import { ZButton } from "../internal-component/z-button";
import { useTranslation } from "../../utils/utils";
import { leaveRoom } from "../../utils/socket";
import { getChatPicture, handleGetChat } from "../../store/chat";
import { closeDialog, handleError, openDialog } from "../../store/dialog";
import { serviceUpdateChatItem } from "../../store/message";
import { AboutSection } from "../internal-component/about-section";
import { TagSection } from "../internal-component/tag-section";
import { AssociatedUsersSection } from "../internal-component/associated-users-section";
import { MergeUserView } from "../internal-component/merge-user-view";
import { ContextSection } from "../internal-component/context-section";
import { Icon } from "../internal-component/icon";
import { DEFAULT_COLOR } from "../../utils/constant";
export class ProfileInfo {
    disposeListener;
    isLoading = false;
    isEditStatus = false;
    statusId;
    isEditTag = false;
    isAddTag = false;
    isMerge = false;
    isOpenDrawer = false;
    tempDrawerUser = null;
    mergeIndex = 0;
    tempUser = null;
    activeTabIndex = 0;
    tagItems = [];
    showDialog = { open: false };
    matchUsers = [];
    associatedUsers = [];
    isEditContext = false;
    context;
    isEditSummarizeMessage = false;
    summarizeMessageItems = [];
    prevSelectedChat = null;
    tabs() {
        const t = useTranslation();
        return [{ label: t('profile_tab.profile_this_chat') }, { label: t('profile_tab.merged_profile') }];
    }
    resetState() {
        this.isEditStatus = false;
        this.statusId = undefined;
        this.isEditTag = false;
        this.isAddTag = false;
        this.isMerge = false;
        this.isOpenDrawer = false;
        this.tempDrawerUser = null;
        this.mergeIndex = 0;
        this.tempUser = null;
        this.activeTabIndex = 0;
        this.associatedUsers = [];
        this.tagItems = [];
        this.isEditContext = false;
        this.context = undefined;
        this.isEditSummarizeMessage = false;
        this.summarizeMessageItems = [];
        userStore.reset();
    }
    async onSyncTagComplete() {
        const selectedChat = selectedChatStore.get('selectedChat');
        if (selectedChat.id) {
            const type = selectedChat.type === 'group' ? 'group' : 'user';
            await this.loadUser({ type, channel: selectedChat.channel, id: selectedChat[type].id, sessionId: selectedChat.id, force: true });
        }
    }
    handleChatSelection = async ({ chat }) => {
        if (!chat) {
            this.resetState();
            return;
        }
        if ((this.prevSelectedChat ? this.prevSelectedChat.id : '') !== chat.id) {
            this.prevSelectedChat = chat;
            this.resetState();
            const type = chat.type === 'group' ? 'group' : 'user';
            await this.loadUser({ type, channel: chat.channel, id: chat[type].id, sessionId: chat.id });
        }
    };
    async componentWillLoad() {
        this.disposeListener = selectedChatStore.onChange('selectedChat', async (newChat) => {
            await this.handleChatSelection({ chat: newChat });
        });
        const currentChat = selectedChatStore.get('selectedChat');
        await this.handleChatSelection({ chat: currentChat });
    }
    disconnectedCallback() {
        if (this.disposeListener)
            this.disposeListener();
    }
    applyUserToState(user, sessionId) {
        this.statusId = user.status ? user.status.id : undefined;
        this.context = user.context;
        this.tagItems = user.tags.map(tag => ({ item: tag }));
        // Convert session object to summarizeMessageItems
        let sessionSummarizeMessages = [];
        if (user.session) {
            sessionSummarizeMessages = Object.entries(user.session).map(([key, value], index) => ({
                id: key,
                sequence: index,
                name: key,
                value: value,
            }));
            user.summarize_messages = [...sessionSummarizeMessages];
        }
        this.summarizeMessageItems = (user.summarize_messages || []).map(tag => ({ item: tag }));
        userStore.set('user', user);
        serviceUpdateChatItem({
            chatId: sessionId,
            updateValue: {
                tags: user.tags,
                summarize_messages: user.summarize_messages,
            },
        });
    }
    async loadUser({ type, channel, id, sessionId, force = false }) {
        try {
            this.isLoading = true;
            let _channel = channel;
            if (type === 'group') {
                _channel = 'line';
            }
            if (!force) {
                const cachedUser = await getCachedUser(_channel, id);
                if (cachedUser && !userStore.get('user')) {
                    this.applyUserToState(cachedUser, sessionId);
                    this.isLoading = false;
                }
            }
            const user = await getUser({ type, channel: _channel, id, sessionId });
            this.applyUserToState(user, sessionId);
            persistUser(_channel, id, user);
            await this.loadAssociatedUsers(user);
            return user;
        }
        catch (error) {
            if (!userStore.get('user')) {
                handleError(error, 'Failed to load user');
            }
        }
        finally {
            this.isLoading = false;
        }
    }
    async loadAssociatedUsers(user) {
        try {
            this.isLoading = true;
            const id = (user.associated_users || []).length > 0 ? user.id : user.zignal_user_id;
            if (id) {
                const zignalUser = await getUser({ channel: 'zignal', id });
                this.tempUser = zignalUser;
                this.associatedUsers = zignalUser.associated_users;
            }
            else {
                this.associatedUsers = [];
            }
        }
        catch (error) {
            handleError(error, 'Failed to load associated users');
        }
        finally {
            this.isLoading = false;
        }
    }
    async createNewUserStatus(name) {
        try {
            this.isLoading = true;
            const userStatuses = await createUserStatus({ name, color: DEFAULT_COLOR });
            return userStatuses;
        }
        catch (error) {
            handleError(error, 'Failed to createUserStatus');
        }
        finally {
            this.isLoading = false;
        }
    }
    async createNewUserTag(name) {
        try {
            this.isLoading = true;
            const userTags = await createUserTag({ name, color: DEFAULT_COLOR });
            return userTags;
        }
        catch (error) {
            handleError(error, 'Failed to create user tag');
        }
        finally {
            this.isLoading = false;
        }
    }
    async createNewUserContext(name) {
        try {
            this.isLoading = true;
            //await createUserContext({ name });
            return name;
        }
        catch (error) {
            handleError(error, 'Failed to create user context');
        }
        finally {
            this.isLoading = false;
        }
    }
    handleOpenDialogEditor = async ({ label, field, value, type = 'input', limit }) => {
        this.showDialog = { open: true, type, label, field, value, limit };
    };
    handleCloseDialogEditor = () => {
        this.showDialog = { open: false };
    };
    handleEditStatus = () => {
        this.isEditStatus = true;
    };
    handleCloseStatus = () => {
        this.isEditStatus = false;
    };
    handleRemoveStatus = () => {
        this.statusId = undefined;
    };
    handleSaveUserStatus = async () => {
        await this.handleUpdateUser('status_id', this.statusId);
        this.handleCloseStatus();
    };
    handleEditTag = () => {
        this.isEditTag = true;
    };
    handleCloseTag = () => {
        this.isEditTag = false;
        this.tagItems = this.tagItems
            .filter(({ isAdd }) => !isAdd)
            .map(item => ({
            ...item,
            isDelete: undefined,
            isAdd: undefined,
        }));
    };
    handleSaveUserTags = async () => {
        const selectedChat = selectedChatStore.get('selectedChat');
        const user = userStore.get('user');
        const type = (selectedChat && selectedChat.type === 'group') ? 'group' : 'user';
        try {
            this.isLoading = true;
            const addTagIds = [];
            const removeTagIds = [];
            for (const item of this.tagItems) {
                if (item && item.isAdd) {
                    addTagIds.push(item.item.id);
                }
                else if (item && item.isDelete) {
                    removeTagIds.push(item.item.id);
                }
            }
            if (addTagIds.length === 0 && removeTagIds.length === 0) {
                this.handleCloseTag();
                return;
            }
            const userResponse = await updateUser({
                type,
                channel: selectedChat.channel,
                id: user.id,
                add_tag_ids: addTagIds.length > 0 ? addTagIds : undefined,
                remove_tag_ids: removeTagIds.length > 0 ? removeTagIds : undefined,
            });
            if (['user-updated', 'group-updated'].includes(userResponse.code)) {
                await this.loadUser({ type, channel: selectedChat.channel, id: user.id, sessionId: selectedChat.id });
            }
            this.handleCloseTag();
        }
        catch (error) {
            handleError(error, 'Failed to UpdateUserTags');
        }
        finally {
            this.isLoading = false;
        }
    };
    handleEditContext = () => {
        this.isEditContext = true;
    };
    handleCloseContext = () => {
        this.isEditContext = false;
    };
    handleSaveUserContext = async () => {
        await this.handleUpdateUser('context', this.context);
        this.handleCloseContext();
    };
    handleEditSummarizeMessage = () => {
        this.isEditSummarizeMessage = true;
    };
    handleCloseSummarizeMessage = () => {
        this.isEditSummarizeMessage = false;
        this.summarizeMessageItems = this.summarizeMessageItems
            .filter(({ isAdd }) => !isAdd)
            .map(item => ({
            ...item,
            isDelete: undefined,
            isAdd: undefined,
        }));
    };
    handleSaveUserSummarizeMessages = async (detail) => {
        const selectedChat = selectedChatStore.get('selectedChat');
        const user = userStore.get('user');
        const type = (selectedChat && selectedChat.type === 'group') ? 'group' : 'user';
        try {
            this.isLoading = true;
            const session = {};
            detail.forEach(({ item }) => {
                if (item.name && item.value) {
                    session[item.name] = item.value;
                }
            });
            const userResponse = await updateUser({
                type,
                channel: selectedChat.channel,
                id: user.id,
                session,
            });
            if (['user-updated', 'group-updated'].includes(userResponse.code)) {
                await this.loadUser({ type, channel: selectedChat.channel, id: user.id, sessionId: selectedChat.id });
            }
            this.handleCloseSummarizeMessage();
        }
        catch (error) {
            handleError(error, 'Failed to UpdateUserSummarizeMessages');
        }
        finally {
            this.isLoading = false;
        }
    };
    isAllowEmpty = (field) => {
        return ['email', 'phone_number', 'address', 'gender', 'locale', 'note', 'status_id', 'nickname'].includes(field);
    };
    handleUpdateUser = async (field, value) => {
        const user = userStore.get('user');
        const selectedChat = selectedChatStore.get('selectedChat');
        const type = (selectedChat && selectedChat.type === 'group') ? 'group' : 'user';
        try {
            this.isLoading = true;
            const updateValue = this.isAllowEmpty(field) ? (value ? value : null) : value;
            const updateObject = { [field]: (field === 'nickname' && updateValue === null) ? user.name : updateValue };
            const userResponse = await updateUser({
                type,
                channel: user.channel,
                id: user.id,
                ...updateObject,
            });
            if (['user-updated', 'group-updated'].includes(userResponse.code)) {
                await this.loadUser({ type, channel: user.channel, id: user.id, sessionId: selectedChat.id });
            }
        }
        catch (error) {
            handleError(error, 'Failed to UpdateUser');
        }
        finally {
            this.isLoading = false;
        }
    };
    handleSaveDialogEditor = async (field, value) => {
        await this.handleUpdateUser(field, value);
        this.handleCloseDialogEditor();
    };
    getMatchUsers() {
        return userStore.get('user')?.match_users || [];
    }
    handlePrevMergeUser = () => {
        const prevIndex = this.mergeIndex - 1;
        if (prevIndex >= 0 && prevIndex <= this.getMatchUsers().length - 1) {
            this.mergeIndex = prevIndex;
        }
    };
    handleNextMergeUser = () => {
        const nextIndex = this.mergeIndex + 1;
        if (nextIndex <= this.getMatchUsers().length - 1) {
            this.mergeIndex = nextIndex;
        }
    };
    handleActionMergeUser = async (matchDecision) => {
        const selectedChat = selectedChatStore.get('selectedChat');
        const user = userStore.get('user');
        try {
            this.isLoading = true;
            const mergeResponse = await mergeUser({
                matchUserId: this.getMatchUsers()[this.mergeIndex].id,
                matchDecision,
            });
            if (['match-user-merged', 'match-user-rejected'].includes(mergeResponse.code)) {
                const type = selectedChat.type === 'group' ? 'group' : 'user';
                await this.loadUser({ type, channel: selectedChat.channel, id: user.id, sessionId: selectedChat.id });
            }
            if (this.getMatchUsers().length === 0) {
                this.isMerge = false;
                await this.handleSelectTab(1);
            }
        }
        catch (error) {
            handleError(error, 'Failed to MergeUser');
        }
        finally {
            this.isLoading = false;
        }
    };
    handleSelectTab = async (index) => {
        if (this.activeTabIndex === index)
            return;
        this.activeTabIndex = index;
        if (this.tempUser !== null) {
            const tempUser = userStore.get('user');
            userStore.set('user', this.tempUser);
            this.statusId = this.tempUser.status ? this.tempUser.status.id : undefined;
            this.context = this.tempUser.context;
            this.tagItems = this.tempUser.tags.map(tag => ({ item: tag }));
            this.tempUser = tempUser;
        }
        this.handleCloseStatus();
        this.handleCloseTag();
        this.handleCloseContext();
    };
    handleJumpToChat = ({ session_id: sessionId }) => {
        const t = useTranslation();
        const selectedChat = selectedChatStore.get('selectedChat');
        const associatedUser = this.associatedUsers.find(associatedUser => associatedUser.session_id === sessionId);
        const pictureUrl = associatedUser ? associatedUser.picture_url : '';
        const customSign = () => h("div", { class: "profile-info-jump-chat-sign" }, h("z-avatar", { pictureUrl: getChatPicture(selectedChat) }), h(Icon, { name: "ArrowRight", addClass: 'size-8' }), h("z-avatar", { pictureUrl: getChatPicture({
                ...selectedChat,
                user: {
                    ...selectedChat.user,
                    picture_url: pictureUrl
                }
            }) }));
        const onSubmitDialog = async () => {
            try {
                const selectedChat = selectedChatStore.get('selectedChat');
                if (selectedChat && selectedChat.id !== sessionId) {
                    this.isLoading = true;
                    leaveRoom(selectedChat.id);
                    const chat = await handleGetChat(sessionId);
                    selectedChatStore.set('selectedChat', chat);
                }
                else {
                    return;
                }
            }
            catch (error) {
                handleError(error, 'Failed to jump Chat');
            }
            finally {
                this.isLoading = false;
            }
        };
        openDialog({
            open: true,
            type: "CUSTOM" /* DIALOG_TYPE.CUSTOM */,
            customSign: customSign(),
            title: 'คุณต้องการสลับไปยังแชทอื่นใช่หรือไม่',
            contentCustom: 'เมื่อยืนยัน ระบบจะพาคุณไปยังแชทที่เลือก หากต้องการกลับมาแชทนี้ คุณจะต้องเลือกแชทนี้ใหม่อีกครั้ง',
            buttonName: t('confirm'),
            cancelButtonName: t('cancel'),
            onSubmitDialog,
            onCloseDialog: closeDialog,
        });
    };
    handleViewProfile = async ({ channel, id, session_id: sessionId }) => {
        try {
            this.isLoading = true;
            const user = await getUser({ channel, id, sessionId });
            this.tempDrawerUser = user;
            this.isOpenDrawer = true;
        }
        catch (error) {
            handleError(error, 'Failed to load View User');
        }
        finally {
            this.isLoading = false;
        }
    };
    handleUnlinkUser = async ({ channel, id: userId }) => {
        const selectedChat = selectedChatStore.get('selectedChat');
        const user = userStore.get('user');
        try {
            this.isLoading = true;
            let isTempUser = false;
            if (user.zignal_user_id) {
                isTempUser = false;
            }
            if (this.tempUser && this.tempUser.zignal_user_id) {
                isTempUser = true;
            }
            const unlinkResponse = await unlinkUser({
                zignalUserId: isTempUser ? this.tempUser.zignal_user_id : user.zignal_user_id,
                channel,
                userId,
            });
            if (unlinkResponse.code === 'user-unlinked') {
                const _user = await this.loadUser({
                    channel: selectedChat.channel,
                    id: isTempUser ? this.tempUser.id : user.id,
                    sessionId: selectedChat.id
                });
                if (!_user.zignal_user_id && ((this.associatedUsers || []).length === 0)) {
                    this.tempUser = null;
                    this.handleSelectTab(0);
                }
            }
        }
        catch (error) {
            handleError(error, 'Failed to unlinkUser');
        }
        finally {
            this.isLoading = false;
        }
    };
    renderUserInfo = (_user, readOnly = false) => {
        const selectedChat = selectedChatStore.get('selectedChat');
        const _connection = configStore.get('connectionList').find(connection => connection.type === 'zwiz' && connection.channels.find(channel => channel.id === selectedChat?.connection?.id));
        return (h("div", null, h("user-info-section", { user: _user, readOnly: readOnly, isEditStatus: this.isEditStatus, statusId: this.statusId, onOpenDialogEditor: event => this.handleOpenDialogEditor(event.detail), onEditStatus: this.handleEditStatus, onCloseStatus: this.handleCloseStatus, onRemoveStatus: this.handleRemoveStatus, onSaveUserStatus: this.handleSaveUserStatus, onStatusSelecting: event => (this.statusId = event.detail), onCreateUserStatusRequest: (event) => {
                this.createNewUserStatus(event.detail.name).then(result => {
                    event.detail.callback(result);
                });
            }, onSyncUser: () => {
                if (this.activeTabIndex === 0) {
                    this.loadUser({
                        type: selectedChat.type === 'group' ? 'group' : 'user',
                        channel: _user.channel,
                        id: _user.id,
                        sessionId: selectedChat.id
                    });
                }
                if (this.activeTabIndex === 1) {
                    this.loadAssociatedUsers(_user);
                }
            } }), (() => {
            const associatedUser = this.associatedUsers.find(user => user.id === _user.id);
            const connection = associatedUser ? associatedUser.connection : undefined;
            return (h(AboutSection, { user: _user, readOnly: readOnly, activeTabIndex: this.activeTabIndex, onOpenDialogEditor: this.handleOpenDialogEditor, connection: connection }));
        })(), h(TagSection, { user: _user, readOnly: readOnly, activeTabIndex: this.activeTabIndex, isEditTag: this.isEditTag, isAddTag: this.isAddTag, tagItems: this.tagItems, onEditTag: this.handleEditTag, onCloseTag: this.handleCloseTag, onSaveUserTags: this.handleSaveUserTags, onSetIsAddTag: value => (this.isAddTag = value), onDeleteTag: tagId => {
                this.tagItems = this.tagItems.map(item => item.item.id === tagId
                    ? {
                        ...item,
                        isDelete: true,
                        isAdd: false,
                    }
                    : item);
            }, onAddTag: tag => {
                this.tagItems = [
                    ...this.tagItems,
                    {
                        item: tag,
                        isAdd: true,
                        isDelete: undefined,
                    },
                ];
            }, onCreateUserTag: name => this.createNewUserTag(name) }), selectedChat &&
            _connection &&
            _connection?.type === 'zwiz' &&
            _connection?.platform === 'sme' &&
            this.activeTabIndex === 0 &&
            h(Fragment, null, h(ContextSection, { user: _user, readOnly: readOnly, activeTabIndex: this.activeTabIndex, isEditContext: this.isEditContext, context: this.context, onEditContext: this.handleEditContext, onCloseContext: this.handleCloseContext, onSaveUserContexts: this.handleSaveUserContext, onContextSelecting: context => (this.context = context), onCreateUserContext: context => this.createNewUserContext(context) }), h("summarize-message-section", { user: _user, readOnly: readOnly, activeTabIndex: this.activeTabIndex, isEditSummarizeMessage: this.isEditSummarizeMessage, summarizeMessageItems: this.summarizeMessageItems, onEditSummarizeMessage: this.handleEditSummarizeMessage, onCancelSummarizeMessage: this.handleCloseSummarizeMessage, onSaveUserSummarizeMessage: (event) => this.handleSaveUserSummarizeMessages(event.detail) })), selectedChat &&
            _connection &&
            _connection?.type === 'zwiz' &&
            _connection?.platform === 'enterprise' &&
            this.activeTabIndex === 0 &&
            h("customer-info-section", { user: _user, readOnly: readOnly })));
    };
    handleCloseMerge = () => {
        this.isMerge = false;
    };
    handleOpenMerge = () => {
        this.isMerge = true;
    };
    handleSetIsOpenDrawer = (value) => {
        this.isOpenDrawer = value;
    };
    render() {
        const t = useTranslation();
        const selectedChat = selectedChatStore.get('selectedChat');
        const user = userStore.get('user');
        const theme = configStore.get('theme');
        return (h(Host, { key: '0f794cb6c0ef609df454b021e4756758abfcd0c2' }, selectedChat && user && (h("div", { key: '1709111879264a752e47812e685706ecd941b795', class: "z-animate-width profile-info" }, this.isMerge ? (h(MergeUserView, { mergeIndex: this.mergeIndex, onClose: this.handleCloseMerge, onPrevMergeUser: this.handlePrevMergeUser, onNextMergeUser: this.handleNextMergeUser, onActionMergeUser: this.handleActionMergeUser })) : (h("div", { class: "z-animate-width relative" }, user.match_users && user.match_users.length > 0 && (h("div", { class: "profile-info-match-user-suggest-wrapper" }, h("div", { class: "profile-info-box-wrapper" }, h("span", null, t('profile_tab.match_user')), h("div", { class: "relative" }, h("z-avatar", { size: "small", pictureUrl: user.match_users[0].user.picture_url }), h("img", { src: `https://zwizai-platform.s3.ap-southeast-1.amazonaws.com/zignal-package/${user.match_users[0].channel}.png`, alt: "agent avatar", class: "profile-info-avatar absolute -bottom-0.5 -right-0.5", loading: "lazy" }))), h("span", { class: "profile-info-match-user-suggest-button", onClick: this.handleOpenMerge }, `${t('profile_tab.view_data')} >`))), (user.zignal_user_id || this.tempUser !== null) && (h("div", { class: "profile-info-match-user-suggest-user-wrapper border-primary" }, this.tabs().map(({ label }, index) => (h(ZButton, { label: label, onClick: () => this.handleSelectTab(index), variant: this.activeTabIndex === index ? 'primary' : 'text', startIcon: h("img", { src: `https://zwizai-platform.s3.ap-southeast-1.amazonaws.com/zignal-package/${index === 0 ? selectedChat.channel : `${theme}-zignal`}.png`, alt: "agent avatar", class: "profile-info-avatar", loading: "lazy" }) }))))), this.renderUserInfo(user), this.associatedUsers && this.associatedUsers.length > 0 && (h(AssociatedUsersSection, { associatedUsers: this.associatedUsers, isOpenDrawer: this.isOpenDrawer, tempDrawerUser: this.tempDrawerUser, onJumpToChat: this.handleJumpToChat, onViewProfile: this.handleViewProfile, onUnlinkUser: this.handleUnlinkUser, onSetIsOpenDrawer: this.handleSetIsOpenDrawer, renderUserInfo: this.renderUserInfo })), this.showDialog.open && (h("div", { class: "dialog-backdrop" }, 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.field, event ? event.detail : undefined), limit: this.showDialog.limit })))))))));
    }
    static get is() { return "profile-info"; }
    static get originalStyleUrls() {
        return {
            "$": ["profile-info.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["profile-info.css"]
        };
    }
    static get states() {
        return {
            "isLoading": {},
            "isEditStatus": {},
            "statusId": {},
            "isEditTag": {},
            "isAddTag": {},
            "isMerge": {},
            "isOpenDrawer": {},
            "tempDrawerUser": {},
            "mergeIndex": {},
            "tempUser": {},
            "activeTabIndex": {},
            "tagItems": {},
            "showDialog": {},
            "matchUsers": {},
            "associatedUsers": {},
            "isEditContext": {},
            "context": {},
            "isEditSummarizeMessage": {},
            "summarizeMessageItems": {}
        };
    }
    static get listeners() {
        return [{
                "name": "syncTagComplete",
                "method": "onSyncTagComplete",
                "target": "window",
                "capture": false,
                "passive": false
            }];
    }
}
