"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConversationsWidget = void 0;
var jsx_runtime_1 = require("preact/jsx-runtime");
// eslint-disable-next-line @typescript-eslint/no-unused-vars
var preact_1 = require("preact");
var logger_1 = require("../../../../utils/logger");
var styles_1 = require("./styles");
var OpenChatButton_1 = require("./OpenChatButton");
var SendMessageButton_1 = require("./SendMessageButton");
var CloseChatButton_1 = require("./CloseChatButton");
var RichContent_1 = require("./RichContent");
var TicketListView_1 = require("./TicketListView");
var utils_1 = require("./utils");
var logger = (0, logger_1.createLogger)('[ConversationsWidget]');
var ConversationsWidget = /** @class */ (function (_super) {
    __extends(ConversationsWidget, _super);
    function ConversationsWidget(props) {
        var _this = _super.call(this, props) || this;
        _this._messagesEndRef = null;
        _this._inputRef = null;
        _this._handleToggleOpen = function () {
            _this.setState(function (prevState) { return ({
                state: prevState.state === 'open' ? 'closed' : 'open',
            }); });
        };
        _this._handleClose = function () {
            _this.setState({ state: 'closed' });
        };
        _this._handleSelectTicket = function (ticketId) {
            if (_this.props.onSelectTicket) {
                _this.props.onSelectTicket(ticketId);
            }
        };
        _this._handleNewConversation = function () {
            if (_this.props.onNewConversation) {
                _this.props.onNewConversation();
            }
        };
        _this._handleBackToTickets = function () {
            if (_this.props.onBackToTickets) {
                _this.props.onBackToTickets();
            }
        };
        _this._handleInputChange = function (e) {
            var target = e.target;
            _this.setState({ inputValue: target.value });
        };
        _this._handleKeyPress = function (e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                _this._handleSendMessage();
            }
        };
        // Identification form handlers
        _this._handleFormNameChange = function (e) {
            var target = e.target;
            _this.setState({ formName: target.value });
        };
        _this._handleFormEmailChange = function (e) {
            var target = e.target;
            _this.setState({ formEmail: target.value, formEmailError: null });
        };
        _this._handleFormSubmit = function (e) {
            e.preventDefault();
            var _a = _this.state, formEmail = _a.formEmail, formName = _a.formName;
            var _b = _this.props, config = _b.config, onIdentify = _b.onIdentify;
            // Validate email if required
            if (config.requireEmail && !formEmail.trim()) {
                _this.setState({ formEmailError: 'Email is required' });
                return;
            }
            if (formEmail.trim() && !_this._validateEmail(formEmail.trim())) {
                _this.setState({ formEmailError: 'Please enter a valid email address' });
                return;
            }
            // Create traits object
            var traits = {};
            if (formName.trim()) {
                traits.name = formName.trim();
            }
            if (formEmail.trim()) {
                traits.email = formEmail.trim();
            }
            // Update state and notify parent
            _this.setState({
                userTraits: traits,
                showIdentificationForm: false,
            });
            if (onIdentify) {
                onIdentify(traits);
            }
        };
        _this._handleSendMessage = function () { return __awaiter(_this, void 0, void 0, function () {
            var inputValue, trimmedMessage, userMessage, error_1;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        inputValue = this.state.inputValue;
                        trimmedMessage = inputValue.trim();
                        if (!trimmedMessage) {
                            return [2 /*return*/];
                        }
                        userMessage = {
                            id: "temp-".concat(Date.now()),
                            content: trimmedMessage,
                            author_type: 'customer',
                            author_name: 'You',
                            created_at: new Date().toISOString(),
                            is_private: false,
                        };
                        this.setState({
                            messages: __spreadArray(__spreadArray([], __read(this.state.messages), false), [userMessage], false),
                            inputValue: '',
                            isLoading: true,
                            error: null,
                        });
                        _a.label = 1;
                    case 1:
                        _a.trys.push([1, 3, , 4]);
                        return [4 /*yield*/, this.props.onSendMessage(trimmedMessage)
                            // Success - message will be updated via addMessage()
                        ];
                    case 2:
                        _a.sent();
                        // Success - message will be updated via addMessage()
                        this.setState({ isLoading: false });
                        return [3 /*break*/, 4];
                    case 3:
                        error_1 = _a.sent();
                        logger.error('Failed to send message', error_1);
                        this.setState({
                            isLoading: false,
                            error: error_1 instanceof Error ? error_1.message : 'Failed to send message',
                        });
                        // Remove the temporary message on error
                        this.setState(function (prevState) { return ({
                            messages: prevState.messages.filter(function (m) { return m.id !== userMessage.id; }),
                        }); });
                        return [3 /*break*/, 4];
                    case 4: return [2 /*return*/];
                }
            });
        }); };
        // Determine if we need to show the identification form
        var userTraits = props.initialUserTraits || null;
        var needsIdentification = _this._needsIdentification(props.config, userTraits, props.isUserIdentified);
        _this.state = {
            state: props.initialState || 'closed',
            view: props.initialView || 'messages',
            messages: [],
            tickets: props.initialTickets || [],
            ticketsLoading: false,
            inputValue: '',
            isLoading: false,
            error: null,
            showIdentificationForm: needsIdentification,
            formName: (userTraits === null || userTraits === void 0 ? void 0 : userTraits.name) || '',
            formEmail: (userTraits === null || userTraits === void 0 ? void 0 : userTraits.email) || '',
            formEmailError: null,
            userTraits: userTraits,
            unreadCount: 0,
            hasMultipleTickets: props.hasMultipleTickets || false,
        };
        return _this;
    }
    /**
     * Check if we need to show the identification form
     */
    ConversationsWidget.prototype._needsIdentification = function (config, traits, isUserIdentified) {
        // If user is already identified via PostHog, no form needed
        // They've called posthog.identify() so we have their identity
        if (isUserIdentified) {
            return false;
        }
        // If requireEmail is not set, no identification needed
        if (!config.requireEmail) {
            return false;
        }
        // If we already have an email, no form needed
        if (traits === null || traits === void 0 ? void 0 : traits.email) {
            return false;
        }
        return true;
    };
    ConversationsWidget.prototype.componentDidMount = function () {
        // Add greeting message if no messages exist and we're in message view
        if (this.state.view === 'messages' && this.state.messages.length === 0 && this.props.config.greetingText) {
            this._addGreetingMessage();
        }
    };
    ConversationsWidget.prototype.componentDidUpdate = function (_prevProps, prevState) {
        // Scroll to bottom when messages change
        if (this.state.messages.length !== prevState.messages.length) {
            this._scrollToBottom();
        }
        // Notify parent of state changes
        if (this.state.state !== prevState.state && this.props.onStateChange) {
            this.props.onStateChange(this.state.state);
        }
        // Focus input and scroll to bottom when opening
        if (this.state.state === 'open' && prevState.state !== 'open') {
            this._focusInput();
            this._scrollToBottom();
        }
    };
    ConversationsWidget.prototype._addGreetingMessage = function () {
        var greetingMessage = {
            id: 'greeting',
            content: this.props.config.greetingText || 'Hi! How can we help?',
            author_type: 'AI',
            author_name: 'Support',
            created_at: new Date().toISOString(),
            is_private: false,
        };
        this.setState({ messages: [greetingMessage] });
    };
    ConversationsWidget.prototype._scrollToBottom = function () {
        if (this._messagesEndRef) {
            this._messagesEndRef.scrollIntoView({ behavior: 'smooth' });
        }
    };
    ConversationsWidget.prototype._focusInput = function () {
        if (this._inputRef) {
            this._inputRef.focus();
        }
    };
    ConversationsWidget.prototype._validateEmail = function (email) {
        // Basic email validation
        var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    };
    /**
     * Public method to add messages from outside
     */
    ConversationsWidget.prototype.addMessages = function (messages) {
        this.setState(function (prevState) {
            // Filter out duplicates
            var existingIds = new Set(prevState.messages.map(function (m) { return m.id; }));
            var newMessages = messages.filter(function (m) { return !existingIds.has(m.id); });
            if (newMessages.length > 0) {
                return {
                    messages: __spreadArray(__spreadArray([], __read(prevState.messages), false), __read(newMessages), false),
                };
            }
            return null;
        });
    };
    /**
     * Public method to show the widget
     */
    ConversationsWidget.prototype.show = function () {
        this.setState({ state: 'open' });
    };
    /**
     * Public method to hide the widget
     */
    ConversationsWidget.prototype.hide = function () {
        this.setState({ state: 'closed' });
    };
    /**
     * Public method to close the widget completely
     */
    ConversationsWidget.prototype.close = function () {
        this.setState({ state: 'closed' });
    };
    /**
     * Get user traits (either provided via form or from props)
     */
    ConversationsWidget.prototype.getUserTraits = function () {
        return this.state.userTraits;
    };
    /**
     * Called when user identifies via posthog.identify()
     * Hides the identification form since we now know who they are
     */
    ConversationsWidget.prototype.setUserIdentified = function () {
        if (this.state.showIdentificationForm) {
            this.setState({ showIdentificationForm: false });
        }
    };
    /**
     * Set the unread message count (called by manager)
     */
    ConversationsWidget.prototype.setUnreadCount = function (count) {
        this.setState({ unreadCount: count });
    };
    /**
     * Update the tickets list (called by manager during polling)
     */
    ConversationsWidget.prototype.updateTickets = function (tickets) {
        this.setState({
            tickets: tickets,
            ticketsLoading: false,
            hasMultipleTickets: tickets.length > 1,
        });
    };
    /**
     * Set the current view (tickets list or messages)
     */
    ConversationsWidget.prototype.setView = function (view) {
        this.setState({ view: view });
        if (this.props.onViewChange) {
            this.props.onViewChange(view);
        }
    };
    /**
     * Get the current view
     */
    ConversationsWidget.prototype.getView = function () {
        return this.state.view;
    };
    /**
     * Set tickets loading state
     */
    ConversationsWidget.prototype.setTicketsLoading = function (loading) {
        this.setState({ ticketsLoading: loading });
    };
    /**
     * Clear messages (used when switching tickets or starting new conversation)
     * @param addGreeting - If true, adds the greeting message after clearing
     */
    ConversationsWidget.prototype.clearMessages = function (addGreeting) {
        var _this = this;
        if (addGreeting === void 0) { addGreeting = false; }
        this.setState({ messages: [] }, function () {
            if (addGreeting && _this.props.config.greetingText) {
                _this._addGreetingMessage();
            }
        });
    };
    ConversationsWidget.prototype._renderIdentificationForm = function (styles) {
        var config = this.props.config;
        var _a = this.state, formName = _a.formName, formEmail = _a.formEmail, formEmailError = _a.formEmailError;
        var title = config.identificationFormTitle || 'Before we start...';
        var description = config.identificationFormDescription || 'Please provide your details so we can help you better.';
        var showNameField = config.collectName !== false; // Show by default unless explicitly disabled
        return ((0, jsx_runtime_1.jsxs)("div", { style: styles.identificationForm, children: [(0, jsx_runtime_1.jsx)("div", { style: styles.formTitle, children: title }), (0, jsx_runtime_1.jsx)("div", { style: styles.formDescription, children: description }), (0, jsx_runtime_1.jsxs)("form", { onSubmit: this._handleFormSubmit, children: [showNameField && ((0, jsx_runtime_1.jsxs)("div", { style: styles.formField, children: [(0, jsx_runtime_1.jsxs)("label", { style: styles.formLabel, children: ["Name ", (0, jsx_runtime_1.jsx)("span", { style: styles.formOptional, children: "(optional)" })] }), (0, jsx_runtime_1.jsx)("input", { type: "text", style: styles.formInput, value: formName, onInput: this._handleFormNameChange, placeholder: "Your name", autoComplete: "name" })] })), (0, jsx_runtime_1.jsxs)("div", { style: styles.formField, children: [(0, jsx_runtime_1.jsxs)("label", { style: styles.formLabel, children: ["Email ", !config.requireEmail && (0, jsx_runtime_1.jsx)("span", { style: styles.formOptional, children: "(optional)" })] }), (0, jsx_runtime_1.jsx)("input", { type: "email", style: __assign(__assign({}, styles.formInput), (formEmailError ? styles.formInputError : {})), value: formEmail, onInput: this._handleFormEmailChange, placeholder: "you@example.com", autoComplete: "email" }), formEmailError && (0, jsx_runtime_1.jsx)("div", { style: styles.formError, children: formEmailError })] }), (0, jsx_runtime_1.jsx)("button", { type: "submit", style: styles.formSubmitButton, onMouseEnter: function (e) {
                                e.currentTarget.style.opacity = '0.9';
                            }, onMouseLeave: function (e) {
                                e.currentTarget.style.opacity = '1';
                            }, children: "Start Chat" })] })] }));
    };
    ConversationsWidget.prototype._renderMessage = function (message, styles, primaryColor) {
        var isCustomer = message.author_type === 'customer';
        var messageStyle = __assign(__assign({}, styles.message), (isCustomer ? styles.messageCustomer : styles.messageAgent));
        var contentStyle = __assign(__assign({}, styles.messageContent), (isCustomer ? styles.messageContentCustomer : styles.messageContentAgent));
        return ((0, jsx_runtime_1.jsxs)("div", { style: messageStyle, children: [!isCustomer && message.author_name && (0, jsx_runtime_1.jsx)("div", { style: styles.messageAuthor, children: message.author_name }), (0, jsx_runtime_1.jsx)("div", { style: contentStyle, children: (0, jsx_runtime_1.jsx)(RichContent_1.RichContent, { richContent: message.rich_content, content: message.content, isCustomer: isCustomer, primaryColor: primaryColor }) }), (0, jsx_runtime_1.jsx)("div", { style: styles.messageTime, children: (0, utils_1.formatRelativeTime)(message.created_at) })] }, message.id));
    };
    ConversationsWidget.prototype._renderBackButton = function (styles) {
        return ((0, jsx_runtime_1.jsx)("button", { style: styles.backButton, onClick: this._handleBackToTickets, "aria-label": "Back to conversations", children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: (0, jsx_runtime_1.jsx)("polyline", { points: "15 18 9 12 15 6" }) }) }));
    };
    ConversationsWidget.prototype._renderTicketList = function (styles) {
        var _a = this.state, tickets = _a.tickets, ticketsLoading = _a.ticketsLoading;
        return ((0, jsx_runtime_1.jsx)(TicketListView_1.TicketListView, { tickets: tickets, isLoading: ticketsLoading, styles: styles, onSelectTicket: this._handleSelectTicket, onNewConversation: this._handleNewConversation }));
    };
    ConversationsWidget.prototype._renderMessages = function (styles, primaryColor, placeholderText) {
        var _this = this;
        var _a = this.state, messages = _a.messages, inputValue = _a.inputValue, isLoading = _a.isLoading, error = _a.error;
        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { style: styles.messages, children: [messages.map(function (message) { return _this._renderMessage(message, styles, primaryColor); }), (0, jsx_runtime_1.jsx)("div", { ref: function (el) {
                                _this._messagesEndRef = el;
                            } })] }), error && (0, jsx_runtime_1.jsx)("div", { style: styles.error, children: error }), (0, jsx_runtime_1.jsxs)("div", { style: styles.inputContainer, children: [(0, jsx_runtime_1.jsx)("textarea", { ref: function (el) {
                                _this._inputRef = el;
                            }, style: styles.input, placeholder: placeholderText, value: inputValue, onInput: this._handleInputChange, onKeyPress: this._handleKeyPress, rows: 1, disabled: isLoading }), (0, jsx_runtime_1.jsx)(SendMessageButton_1.SendMessageButton, { primaryColor: primaryColor, inputValue: inputValue, isLoading: isLoading, handleSendMessage: this._handleSendMessage })] })] }));
    };
    ConversationsWidget.prototype.render = function () {
        var config = this.props.config;
        var _a = this.state, state = _a.state, view = _a.view, showIdentificationForm = _a.showIdentificationForm;
        var primaryColor = config.color || '#5375ff';
        var widgetPosition = config.widgetPosition || 'bottom_right';
        var placeholderText = config.placeholderText || 'Type your message...';
        var styles = (0, styles_1.getStyles)(primaryColor, widgetPosition);
        // Button only (closed state)
        if (state === 'closed') {
            return ((0, jsx_runtime_1.jsx)(OpenChatButton_1.OpenChatButton, { primaryColor: primaryColor, position: widgetPosition, handleToggleOpen: this._handleToggleOpen, unreadCount: this.state.unreadCount }));
        }
        // Open state
        var windowStyle = __assign(__assign({}, styles.window), styles.windowOpen);
        // Determine header title based on view
        var headerTitle = view === 'tickets' ? 'Conversations' : 'Support Chat';
        // Show back button in message view when there are multiple tickets
        var showBackButton = view === 'messages' && this.state.hasMultipleTickets;
        return ((0, jsx_runtime_1.jsx)("div", { style: styles.widget, children: (0, jsx_runtime_1.jsxs)("div", { style: windowStyle, children: [(0, jsx_runtime_1.jsxs)("div", { style: styles.header, children: [(0, jsx_runtime_1.jsxs)("div", { style: showBackButton ? styles.headerWithBack : styles.headerTitle, children: [showBackButton && this._renderBackButton(styles), (0, jsx_runtime_1.jsx)("span", { style: styles.headerTitle, children: headerTitle })] }), (0, jsx_runtime_1.jsx)("div", { style: styles.headerActions, children: (0, jsx_runtime_1.jsx)(CloseChatButton_1.CloseChatButton, { primaryColor: primaryColor, handleClose: this._handleClose }) })] }), showIdentificationForm
                        ? this._renderIdentificationForm(styles)
                        : view === 'tickets'
                            ? // Ticket list view
                                this._renderTicketList(styles)
                            : // Messages view
                                this._renderMessages(styles, primaryColor, placeholderText)] }) }));
    };
    return ConversationsWidget;
}(preact_1.Component));
exports.ConversationsWidget = ConversationsWidget;
//# sourceMappingURL=ConversationsWidget.js.map