"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BoardView = BoardView;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const child_process_1 = require("child_process");
const ink_1 = require("ink");
const ink_text_input_1 = tslib_1.__importDefault(require("ink-text-input"));
const TrelloContext_1 = require("../state/TrelloContext");
const NavigationContext_1 = require("../state/NavigationContext");
const ListColumn_1 = require("../components/ListColumn");
const ConfirmDialog_1 = require("../components/ConfirmDialog");
const HelpScreen_1 = require("../components/HelpScreen");
const MultiLineInput_1 = require("../components/MultiLineInput");
const useTerminalSize_1 = require("../hooks/useTerminalSize");
const ink_spinner_1 = tslib_1.__importDefault(require("ink-spinner"));
// Key sequence for checklist items: 1-9, then a-h (skip i), j-z
const CHECKITEM_KEYS = [
    "1", "2", "3", "4", "5", "6", "7", "8", "9",
    "a", "b", "c", "d", "e", "f", "g", "h", // skip "i" — reserved for add item
    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
];
function getCheckItemIndex(input) {
    const idx = CHECKITEM_KEYS.indexOf(input.toLowerCase());
    return idx;
}
function BoardView() {
    const { state: trelloState, loadBoard, createCard, createList, moveCard, archiveCard, deleteCard, updateCard, addLabelToCard, removeLabelFromCard, addMemberToCard, removeMemberFromCard, loadCardDetails, toggleCheckItem, createChecklist, createCheckItem, addAttachment, } = (0, TrelloContext_1.useTrello)();
    const { state: navState, dispatch, config } = (0, NavigationContext_1.useNavigation)();
    const { exit } = (0, ink_1.useApp)();
    const { columns: termWidth, rows: termHeight } = (0, useTerminalSize_1.useTerminalSize)();
    // Local state for input modes
    const [inputValue, setInputValue] = (0, react_1.useState)("");
    const [descValue, setDescValue] = (0, react_1.useState)("");
    const [showHelp, setShowHelp] = (0, react_1.useState)(false);
    const [activeChecklistId, setActiveChecklistId] = (0, react_1.useState)(null);
    const [checklistPage, setChecklistPage] = (0, react_1.useState)(0);
    const prevModeRef = (0, react_1.useRef)(navState.mode);
    const [confirmAction, setConfirmAction] = (0, react_1.useState)(null);
    const lists = trelloState.lists;
    const numColumns = (0, useTerminalSize_1.getListColumns)(termWidth);
    const listWidth = (0, useTerminalSize_1.getListWidth)(termWidth, numColumns);
    // List height: terminal height minus header(3), footer(2), content paddingY(2), list row paddingX wrapper(0)
    const listHeight = Math.max(8, termHeight - 7);
    // Max card rows: list height minus border(2), header(1), hint(1) = 4 lines of chrome
    const maxCardRows = Math.max(3, listHeight - 4);
    // Calculate visible lists based on scroll
    const visibleStart = navState.listScrollOffset;
    const visibleEnd = Math.min(lists.length, visibleStart + numColumns);
    const visibleLists = lists.slice(visibleStart, visibleEnd);
    const currentList = lists[navState.selectedListIndex];
    const currentCards = currentList
        ? trelloState.cardsByList[currentList.id] || []
        : [];
    const selectedCard = currentCards.length > 0
        ? currentCards[navState.selectedCardIndex]
        : null;
    // When entering edit-card, set-due, edit-desc, or checklist/attachment modes
    // from CardDetailView, initialize the input value appropriately
    (0, react_1.useEffect)(() => {
        if (navState.mode === "edit-card" && selectedCard) {
            setInputValue(selectedCard.name);
        }
        else if (navState.mode === "set-due") {
            setInputValue("");
        }
        else if (navState.mode === "edit-desc" && selectedCard) {
            setDescValue(selectedCard.desc || "");
        }
        else if (navState.mode === "toggle-checklist" && selectedCard) {
            // Only reset checklist selection when entering fresh (not returning from add-checkitem)
            if (prevModeRef.current !== "add-checkitem") {
                setActiveChecklistId(null);
                setChecklistPage(0);
            }
            loadCardDetails(selectedCard.id);
        }
        else if (navState.mode === "add-checklist") {
            setInputValue("");
        }
        else if (navState.mode === "add-checkitem") {
            setInputValue("");
        }
        else if (navState.mode === "add-attachment") {
            setInputValue("");
        }
        else if (navState.mode === "view-attachments" && selectedCard) {
            loadCardDetails(selectedCard.id);
        }
        prevModeRef.current = navState.mode;
    }, [navState.mode]);
    // Return to the originating view after completing an editing mode.
    // If we came from card-detail, go back there; otherwise just reset to normal mode.
    const exitEditMode = (0, react_1.useCallback)(() => {
        if (navState.modeOriginView === "card-detail") {
            dispatch({ type: "SET_VIEW", view: "card-detail", preserveSelection: true });
        }
        else {
            dispatch({ type: "SET_MODE", mode: "normal" });
        }
    }, [navState.modeOriginView, dispatch]);
    // Ensure selected list is visible
    const ensureListVisible = (0, react_1.useCallback)((listIndex) => {
        if (listIndex < navState.listScrollOffset) {
            dispatch({ type: "SET_LIST_SCROLL", offset: listIndex });
        }
        else if (listIndex >= navState.listScrollOffset + numColumns) {
            dispatch({
                type: "SET_LIST_SCROLL",
                offset: listIndex - numColumns + 1,
            });
        }
    }, [navState.listScrollOffset, numColumns, dispatch]);
    // Handle normal mode keyboard input
    (0, ink_1.useInput)((input, key) => {
        if (confirmAction)
            return;
        if (showHelp) {
            if (key.escape || input === "?" || input === "q") {
                setShowHelp(false);
            }
            return;
        }
        // Handle card detail view
        if (navState.view === "card-detail")
            return;
        // Input modes
        if (navState.mode === "create-card") {
            if (key.escape) {
                dispatch({ type: "SET_MODE", mode: "normal" });
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "create-list") {
            if (key.escape) {
                dispatch({ type: "SET_MODE", mode: "normal" });
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "move-card") {
            // Handle list number selection for move
            const num = parseInt(input);
            if (num >= 1 && num <= lists.length && selectedCard) {
                const targetList = lists[num - 1];
                if (targetList && targetList.id !== (currentList === null || currentList === void 0 ? void 0 : currentList.id)) {
                    moveCard(selectedCard.id, currentList.id, targetList.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Moved "${selectedCard.name}" to ${targetList.name}`,
                    });
                    setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
                }
                exitEditMode();
                return;
            }
            if (key.escape) {
                exitEditMode();
                return;
            }
            return;
        }
        if (navState.mode === "toggle-label") {
            if (key.escape) {
                exitEditMode();
                return;
            }
            const num = parseInt(input);
            const boardLabels = trelloState.boardLabels;
            if (num >= 1 && num <= Math.min(9, boardLabels.length) && selectedCard) {
                const label = boardLabels[num - 1];
                const hasLabel = selectedCard.labels.some((l) => l.id === label.id);
                if (hasLabel) {
                    removeLabelFromCard(selectedCard.id, label.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Removed label "${label.name || label.color}"`,
                    });
                }
                else {
                    addLabelToCard(selectedCard.id, label.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Added label "${label.name || label.color}"`,
                    });
                }
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            return;
        }
        if (navState.mode === "toggle-member") {
            if (key.escape) {
                exitEditMode();
                return;
            }
            const num = parseInt(input);
            const members = trelloState.members;
            if (num >= 1 && num <= Math.min(9, members.length) && selectedCard) {
                const member = members[num - 1];
                const hasMember = selectedCard.idMembers.includes(member.id);
                if (hasMember) {
                    removeMemberFromCard(selectedCard.id, member.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Removed ${member.fullName}`,
                    });
                }
                else {
                    addMemberToCard(selectedCard.id, member.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Added ${member.fullName}`,
                    });
                }
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            return;
        }
        if (navState.mode === "toggle-checklist") {
            const checklists = ((selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.checklists) || []).sort((a, b) => a.pos - b.pos);
            if (!activeChecklistId) {
                // Checklist selection level
                if (key.escape) {
                    exitEditMode();
                    return;
                }
                const num = parseInt(input);
                if (num >= 1 && num <= Math.min(9, checklists.length)) {
                    setActiveChecklistId(checklists[num - 1].id);
                    setChecklistPage(0);
                }
                return;
            }
            // Item level — a checklist is selected
            const activeChecklist = checklists.find((cl) => cl.id === activeChecklistId);
            if (!activeChecklist) {
                setActiveChecklistId(null);
                return;
            }
            if (key.escape) {
                setActiveChecklistId(null);
                setChecklistPage(0);
                return;
            }
            // Press 'i' to add new item to this checklist
            if (input === "i" && selectedCard) {
                setInputValue("");
                dispatch({ type: "SET_MODE", mode: "add-checkitem" });
                return;
            }
            const items = activeChecklist.checkItems.sort((a, b) => a.pos - b.pos);
            const itemsPerPage = CHECKITEM_KEYS.length; // 35
            const totalPages = Math.max(1, Math.ceil(items.length / itemsPerPage));
            // Left/right arrows to navigate pages
            if (key.leftArrow || key.rightArrow) {
                if (totalPages > 1) {
                    if (key.leftArrow && checklistPage > 0) {
                        setChecklistPage(checklistPage - 1);
                    }
                    else if (key.rightArrow && checklistPage < totalPages - 1) {
                        setChecklistPage(checklistPage + 1);
                    }
                }
                return;
            }
            // Map input key to page-relative item index
            const keyIndex = getCheckItemIndex(input);
            const globalIndex = checklistPage * itemsPerPage + keyIndex;
            if (keyIndex >= 0 && globalIndex < items.length && selectedCard) {
                const item = items[globalIndex];
                toggleCheckItem(selectedCard.id, item.id, item.state);
                dispatch({
                    type: "SET_STATUS",
                    message: `${item.state === "complete" ? "Unchecked" : "Checked"} "${item.name}"`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            return;
        }
        if (navState.mode === "add-checklist") {
            if (key.escape) {
                exitEditMode();
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "add-checkitem") {
            // Esc returns to toggle-checklist with checklist still selected
            if (key.escape) {
                dispatch({ type: "SET_MODE", mode: "toggle-checklist" });
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "add-attachment") {
            if (key.escape) {
                exitEditMode();
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "view-attachments") {
            if (key.escape) {
                exitEditMode();
                return;
            }
            return;
        }
        if (navState.mode === "edit-card") {
            if (key.escape) {
                exitEditMode();
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "edit-desc") {
            // MultiLineInput handles this
            return;
        }
        if (navState.mode === "set-due") {
            if (key.escape) {
                exitEditMode();
                setInputValue("");
                return;
            }
            // TextInput handles the rest
            return;
        }
        if (navState.mode === "search") {
            // TextInput handles this
            return;
        }
        // Normal mode
        if (input === "q") {
            exit();
            return;
        }
        if (input === "?") {
            setShowHelp(true);
            return;
        }
        if (key.escape) {
            dispatch({ type: "SET_VIEW", view: "home" });
            return;
        }
        if (input === "b") {
            dispatch({ type: "SET_VIEW", view: "home" });
            return;
        }
        // List navigation
        if (key.leftArrow || (key.shift && key.tab)) {
            const newIndex = Math.max(0, navState.selectedListIndex - 1);
            dispatch({ type: "SELECT_LIST", index: newIndex });
            ensureListVisible(newIndex);
            return;
        }
        if (key.rightArrow || key.tab) {
            const newIndex = Math.min(lists.length - 1, navState.selectedListIndex + 1);
            dispatch({ type: "SELECT_LIST", index: newIndex });
            ensureListVisible(newIndex);
            return;
        }
        // Jump to list by number
        const num = parseInt(input);
        if (num >= 1 && num <= Math.min(9, lists.length)) {
            dispatch({ type: "SELECT_LIST", index: num - 1 });
            ensureListVisible(num - 1);
            return;
        }
        // Card navigation
        if (key.upArrow) {
            dispatch({
                type: "SELECT_CARD",
                index: Math.max(0, navState.selectedCardIndex - 1),
            });
            return;
        }
        if (key.downArrow) {
            dispatch({
                type: "SELECT_CARD",
                index: Math.min(currentCards.length - 1, navState.selectedCardIndex + 1),
            });
            return;
        }
        // Jump to first/last card
        if (input === "g") {
            dispatch({ type: "SELECT_CARD", index: 0 });
            return;
        }
        if (input === "G") {
            dispatch({
                type: "SELECT_CARD",
                index: Math.max(0, currentCards.length - 1),
            });
            return;
        }
        // Card detail
        if (key.return && selectedCard) {
            dispatch({ type: "SET_VIEW", view: "card-detail", preserveSelection: true });
            return;
        }
        // Create card
        if (input === "n" && currentList) {
            setInputValue("");
            dispatch({ type: "SET_MODE", mode: "create-card" });
            return;
        }
        // Edit card
        if (input === "e" && selectedCard) {
            setInputValue(selectedCard.name);
            dispatch({ type: "SET_MODE", mode: "edit-card" });
            return;
        }
        // Move card
        if (input === "m" && selectedCard && lists.length > 1) {
            dispatch({ type: "SET_MODE", mode: "move-card" });
            return;
        }
        // Due date
        if (input === "d" && selectedCard) {
            setInputValue("");
            dispatch({ type: "SET_MODE", mode: "set-due" });
            return;
        }
        // Edit description
        if (input === "D" && selectedCard) {
            setDescValue(selectedCard.desc || "");
            dispatch({ type: "SET_MODE", mode: "edit-desc" });
            return;
        }
        // Toggle labels
        if (input === "l" && selectedCard) {
            dispatch({ type: "SET_MODE", mode: "toggle-label" });
            return;
        }
        // Toggle members (assign)
        if (input === "M" && selectedCard) {
            dispatch({ type: "SET_MODE", mode: "toggle-member" });
            return;
        }
        // Toggle checklist items
        if (input === "c" && selectedCard) {
            loadCardDetails(selectedCard.id);
            setActiveChecklistId(null);
            setChecklistPage(0);
            dispatch({ type: "SET_MODE", mode: "toggle-checklist" });
            return;
        }
        // Add new checklist
        if (input === "C" && selectedCard) {
            setInputValue("");
            dispatch({ type: "SET_MODE", mode: "add-checklist" });
            return;
        }
        // Add attachment
        if (input === "A" && selectedCard) {
            setInputValue("");
            dispatch({ type: "SET_MODE", mode: "add-attachment" });
            return;
        }
        // View all attachments
        if (input === "a" && selectedCard) {
            loadCardDetails(selectedCard.id);
            dispatch({ type: "SET_MODE", mode: "view-attachments" });
            return;
        }
        // Create list
        if (input === "L") {
            setInputValue("");
            dispatch({ type: "SET_MODE", mode: "create-list" });
            return;
        }
        // Open card in browser
        if (input === "o" && selectedCard) {
            openUrl(selectedCard.url);
            dispatch({ type: "SET_STATUS", message: `Opening in browser...` });
            setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            return;
        }
        // Archive card
        if (input === "x" && selectedCard) {
            const card = selectedCard;
            const list = currentList;
            setConfirmAction({
                message: `Archive "${card.name}"?`,
                onConfirm: () => {
                    archiveCard(card.id, list.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Archived "${card.name}"`,
                    });
                    setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
                    setConfirmAction(null);
                    // Adjust selection if needed
                    if (navState.selectedCardIndex >= currentCards.length - 1 &&
                        navState.selectedCardIndex > 0) {
                        dispatch({
                            type: "SELECT_CARD",
                            index: navState.selectedCardIndex - 1,
                        });
                    }
                },
            });
            return;
        }
        // Delete card
        if (key.delete && selectedCard) {
            const card = selectedCard;
            const list = currentList;
            setConfirmAction({
                message: `Permanently delete "${card.name}"? This cannot be undone.`,
                onConfirm: () => {
                    deleteCard(card.id, list.id);
                    dispatch({
                        type: "SET_STATUS",
                        message: `Deleted "${card.name}"`,
                    });
                    setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
                    setConfirmAction(null);
                    if (navState.selectedCardIndex >= currentCards.length - 1 &&
                        navState.selectedCardIndex > 0) {
                        dispatch({
                            type: "SELECT_CARD",
                            index: navState.selectedCardIndex - 1,
                        });
                    }
                },
            });
            return;
        }
        // Sync
        if (input === "s") {
            if (trelloState.currentBoard) {
                loadBoard(trelloState.currentBoard);
            }
            return;
        }
        // Ctrl+R refresh
        if (key.ctrl && input === "r") {
            if (trelloState.currentBoard) {
                loadBoard(trelloState.currentBoard);
            }
            return;
        }
    }, { isActive: navState.view === "board" });
    // Handle create card submission
    const handleCreateCard = (0, react_1.useCallback)(async (name) => {
        if (name.trim() && currentList) {
            try {
                await createCard(currentList.id, name.trim());
                dispatch({
                    type: "SET_STATUS",
                    message: `Created "${name.trim()}"`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 5000);
            }
        }
        dispatch({ type: "SET_MODE", mode: "normal" });
        setInputValue("");
    }, [currentList, createCard, dispatch]);
    // Handle create list submission
    const handleCreateList = (0, react_1.useCallback)(async (name) => {
        if (name.trim()) {
            try {
                const list = await createList(name.trim());
                dispatch({
                    type: "SET_STATUS",
                    message: `Created list "${list.name}"`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
                // Select the newly created list
                const newIndex = trelloState.lists.length; // will be at the end after ADD_LIST
                dispatch({ type: "SELECT_LIST", index: newIndex });
                ensureListVisible(newIndex);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 5000);
            }
        }
        dispatch({ type: "SET_MODE", mode: "normal" });
        setInputValue("");
    }, [createList, dispatch, trelloState.lists.length, ensureListVisible]);
    // Handle edit card submission
    const handleEditCard = (0, react_1.useCallback)(async (name) => {
        if (name.trim() && selectedCard) {
            try {
                await updateCard(selectedCard.id, { name: name.trim() });
                dispatch({
                    type: "SET_STATUS",
                    message: `Updated card name`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        exitEditMode();
        setInputValue("");
    }, [selectedCard, updateCard, dispatch, exitEditMode]);
    // Handle set due date
    const handleSetDue = (0, react_1.useCallback)(async (dueStr) => {
        if (selectedCard) {
            try {
                const chrono = require("chrono-node");
                let due = null;
                if (dueStr.trim().toLowerCase() === "none" || dueStr.trim() === "") {
                    due = "";
                }
                else {
                    const parsed = chrono.parseDate(dueStr);
                    if (parsed) {
                        due = parsed.toISOString();
                    }
                    else {
                        dispatch({
                            type: "SET_STATUS",
                            message: `Could not parse date: "${dueStr}"`,
                        });
                        setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
                        exitEditMode();
                        setInputValue("");
                        return;
                    }
                }
                await updateCard(selectedCard.id, { due });
                dispatch({
                    type: "SET_STATUS",
                    message: due ? `Due date set` : `Due date cleared`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        exitEditMode();
        setInputValue("");
    }, [selectedCard, updateCard, dispatch, exitEditMode]);
    // Handle edit description submission
    const handleEditDesc = (0, react_1.useCallback)(async (desc) => {
        if (selectedCard) {
            try {
                await updateCard(selectedCard.id, { desc });
                dispatch({
                    type: "SET_STATUS",
                    message: `Updated description`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        exitEditMode();
        setDescValue("");
    }, [selectedCard, updateCard, dispatch, exitEditMode]);
    // Handle add checklist submission
    const handleAddChecklist = (0, react_1.useCallback)(async (name) => {
        if (name.trim() && selectedCard) {
            try {
                await createChecklist(selectedCard.id, name.trim());
                dispatch({
                    type: "SET_STATUS",
                    message: `Created checklist "${name.trim()}"`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        exitEditMode();
        setInputValue("");
    }, [selectedCard, createChecklist, dispatch, exitEditMode]);
    // Handle add check item submission
    const handleAddCheckItem = (0, react_1.useCallback)(async (name) => {
        if (name.trim() && activeChecklistId && selectedCard) {
            try {
                await createCheckItem(activeChecklistId, name.trim(), selectedCard.id);
                dispatch({
                    type: "SET_STATUS",
                    message: `Added item "${name.trim()}"`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        // Return to toggle-checklist mode with the same checklist selected
        dispatch({ type: "SET_MODE", mode: "toggle-checklist" });
        setInputValue("");
    }, [selectedCard, activeChecklistId, createCheckItem, dispatch]);
    // Handle add attachment submission
    const handleAddAttachment = (0, react_1.useCallback)(async (value) => {
        if (value.trim() && selectedCard) {
            try {
                let url;
                let name;
                if (value.includes("|")) {
                    const parts = value.split("|");
                    url = parts[0].trim();
                    name = parts.slice(1).join("|").trim() || undefined;
                }
                else {
                    url = value.trim();
                }
                await addAttachment(selectedCard.id, url, name);
                dispatch({
                    type: "SET_STATUS",
                    message: `Added attachment${name ? ` "${name}"` : ""}`,
                });
                setTimeout(() => dispatch({ type: "SET_STATUS", message: null }), 3000);
            }
            catch (e) {
                dispatch({
                    type: "SET_STATUS",
                    message: `Error: ${e.message}`,
                });
            }
        }
        exitEditMode();
        setInputValue("");
    }, [selectedCard, addAttachment, dispatch, exitEditMode]);
    // Handle confirm dialog
    if (confirmAction) {
        return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", paddingX: 1, children: (0, jsx_runtime_1.jsx)(ConfirmDialog_1.ConfirmDialog, { message: confirmAction.message, onConfirm: confirmAction.onConfirm, onCancel: () => setConfirmAction(null) }) }));
    }
    // Help screen
    if (showHelp) {
        return (0, jsx_runtime_1.jsx)(HelpScreen_1.HelpScreen, { onClose: () => setShowHelp(false) });
    }
    if (trelloState.loading && lists.length === 0) {
        return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: (0, jsx_runtime_1.jsxs)(ink_1.Text, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.primary, children: (0, jsx_runtime_1.jsx)(ink_spinner_1.default, { type: "dots" }) }), " ", "Loading board..."] }) }));
    }
    return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [navState.mode === "move-card" && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.warning, bold: true, children: ["Move \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" to which list? [Esc] to cancel"] }), lists.slice(0, 9).map((list, i) => {
                        const isCurrent = list.id === (currentList === null || currentList === void 0 ? void 0 : currentList.id);
                        return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [i + 1, ". "] }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { bold: isCurrent, color: isCurrent ? config.theme.muted : config.theme.secondary, children: [list.name, isCurrent ? " (current)" : ""] })] }, list.id));
                    })] })), navState.mode === "toggle-label" && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Toggle labels for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" - Press number to toggle, [Esc] to close"] }), trelloState.boardLabels.slice(0, 9).map((label, i) => {
                        const hasLabel = (selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.labels.some((l) => l.id === label.id)) || false;
                        return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [i + 1, ". "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: hasLabel ? config.theme.accent : config.theme.muted, children: hasLabel ? "[x] " : "[ ] " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: LABEL_COLORS[label.color] || config.theme.muted, children: label.name || label.color || "(no color)" }), label.name && label.color ? ((0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.muted, children: [" (", label.color, ")"] })) : null] }, label.id));
                    }), trelloState.boardLabels.length === 0 && ((0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "No labels on this board" }))] })), navState.mode === "toggle-member" && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Toggle members for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" - Press number to toggle, [Esc] to close"] }), trelloState.members.slice(0, 9).map((member, i) => {
                        const hasMember = (selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.idMembers.includes(member.id)) || false;
                        return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [i + 1, ". "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: hasMember ? config.theme.accent : config.theme.muted, children: hasMember ? "[x] " : "[ ] " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: member.fullName }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.muted, children: [" @", member.username] })] }, member.id));
                    }), trelloState.members.length === 0 && ((0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "No members on this board" }))] })), navState.mode === "toggle-checklist" && ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: (() => {
                    const checklists = ((selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.checklists) || []).sort((a, b) => a.pos - b.pos);
                    if (checklists.length === 0) {
                        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Checklists for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" - [Esc] to close"] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "No checklists on this card. Press [Esc] then [C] to create one." })] }));
                    }
                    if (!activeChecklistId) {
                        // Checklist selection level
                        return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Checklists for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" - Press number to select, [Esc] to close"] }), checklists.slice(0, 9).map((cl, i) => {
                                    const done = cl.checkItems.filter((ci) => ci.state === "complete").length;
                                    const total = cl.checkItems.length;
                                    return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [i + 1, ". "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { bold: true, color: config.theme.secondary, children: cl.name }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.muted, children: [" (", done, "/", total, ")"] })] }, cl.id));
                                })] }));
                    }
                    // Item level — show items of the selected checklist
                    const activeChecklist = checklists.find((cl) => cl.id === activeChecklistId);
                    if (!activeChecklist)
                        return null;
                    const items = activeChecklist.checkItems.sort((a, b) => a.pos - b.pos);
                    // Pagination: slice items into pages of CHECKITEM_KEYS.length (35)
                    const itemsPerPage = CHECKITEM_KEYS.length;
                    const totalPages = Math.max(1, Math.ceil(items.length / itemsPerPage));
                    const currentPage = Math.min(checklistPage, totalPages - 1);
                    const pageItems = items.slice(currentPage * itemsPerPage, (currentPage + 1) * itemsPerPage);
                    // Calculate available rows and split page items into columns if needed
                    // termHeight minus: header(3) + footer(2) + content paddingY(2) + title(1) + page indicator(1) + marginBottom(1) = 10
                    const availableRows = Math.max(3, termHeight - 10);
                    const numItemColumns = pageItems.length > 0 ? Math.ceil(pageItems.length / availableRows) : 1;
                    const itemColumnWidth = numItemColumns > 1
                        ? Math.floor((termWidth - 4) / numItemColumns)
                        : undefined;
                    // Split page items into column chunks
                    const itemsPerColumn = Math.ceil(pageItems.length / numItemColumns);
                    const itemColumns = [];
                    for (let col = 0; col < numItemColumns; col++) {
                        itemColumns.push(pageItems.slice(col * itemsPerColumn, (col + 1) * itemsPerColumn));
                    }
                    const pageLabel = totalPages > 1 ? ` (page ${currentPage + 1}/${totalPages})` : "";
                    return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [activeChecklist.name, " (", items.filter((ci) => ci.state === "complete").length, "/", items.length, ")", pageLabel, " - [key] Toggle, [i] Add item, [Esc] Back"] }), totalPages > 1 && ((0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "Use Left/Right arrows to switch pages" })), items.length === 0 && ((0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "No items. Press [i] to add one." })), numItemColumns <= 1 ? (
                            // Single column — render flat
                            pageItems.map((item, i) => {
                                const keyLabel = CHECKITEM_KEYS[i] || "?";
                                return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [keyLabel, ". "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: item.state === "complete" ? config.theme.accent : config.theme.muted, children: item.state === "complete" ? "[x] " : "[ ] " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { strikethrough: item.state === "complete", color: item.state === "complete" ? config.theme.muted : undefined, children: item.name })] }, item.id));
                            })) : (
                            // Multi-column layout
                            (0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "row", children: itemColumns.map((colItems, colIndex) => ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", width: itemColumnWidth, children: colItems.map((item, i) => {
                                        const pageIndex = colIndex * itemsPerColumn + i;
                                        const keyLabel = CHECKITEM_KEYS[pageIndex] || "?";
                                        return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: [keyLabel, ". "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: item.state === "complete" ? config.theme.accent : config.theme.muted, children: item.state === "complete" ? "[x] " : "[ ] " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { strikethrough: item.state === "complete", color: item.state === "complete" ? config.theme.muted : undefined, wrap: "truncate", children: item.name })] }, item.id));
                                    }) }, colIndex))) }))] }));
                })() })), navState.mode === "view-attachments" && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Attachments for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\" - [Esc] to close"] }), (() => {
                        const attachments = (selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.attachments) || [];
                        if (attachments.length === 0) {
                            return (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "No attachments on this card." });
                        }
                        return attachments.map((att) => ((0, jsx_runtime_1.jsxs)(ink_1.Box, { paddingLeft: 2, children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.secondary, children: att.name }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: " - " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.primary, children: att.url })] }, att.id)));
                    })()] })), (navState.mode === "create-card" ||
                navState.mode === "create-list" ||
                navState.mode === "edit-card" ||
                navState.mode === "set-due" ||
                navState.mode === "add-checklist" ||
                navState.mode === "add-checkitem" ||
                navState.mode === "add-attachment") && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.primary, bold: true, children: navState.mode === "create-card"
                            ? "New card: "
                            : navState.mode === "create-list"
                                ? "New list: "
                                : navState.mode === "edit-card"
                                    ? "Edit name: "
                                    : navState.mode === "set-due"
                                        ? "Due date (e.g. 'tomorrow', 'next friday', 'none'): "
                                        : navState.mode === "add-checklist"
                                            ? "New checklist name: "
                                            : navState.mode === "add-checkitem"
                                                ? "New item: "
                                                : "Attachment (URL or URL | description): " }), (0, jsx_runtime_1.jsx)(ink_text_input_1.default, { value: inputValue, onChange: setInputValue, onSubmit: (value) => {
                            if (navState.mode === "create-card")
                                handleCreateCard(value);
                            else if (navState.mode === "create-list")
                                handleCreateList(value);
                            else if (navState.mode === "edit-card")
                                handleEditCard(value);
                            else if (navState.mode === "set-due")
                                handleSetDue(value);
                            else if (navState.mode === "add-checklist")
                                handleAddChecklist(value);
                            else if (navState.mode === "add-checkitem")
                                handleAddCheckItem(value);
                            else if (navState.mode === "add-attachment")
                                handleAddAttachment(value);
                        } })] })), navState.mode === "edit-desc" && ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", paddingX: 2, marginBottom: 1, children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: config.theme.primary, bold: true, children: ["Edit description for \"", selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.name, "\":"] }), (0, jsx_runtime_1.jsx)(ink_1.Box, { borderStyle: "single", borderColor: config.theme.primary, paddingX: 1, marginTop: 1, children: (0, jsx_runtime_1.jsx)(MultiLineInput_1.MultiLineInput, { value: descValue, onChange: setDescValue, onSubmit: handleEditDesc, onCancel: () => {
                                exitEditMode();
                                setDescValue("");
                            }, cursorColor: config.theme.primary, hintColor: config.theme.muted }) })] })), navState.mode === "normal" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "row", paddingX: 1, children: [visibleStart > 0 && ((0, jsx_runtime_1.jsx)(ink_1.Box, { alignItems: "center", marginRight: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "<" }) })), visibleLists.map((list, i) => {
                                const actualIndex = visibleStart + i;
                                const cards = trelloState.cardsByList[list.id] || [];
                                return ((0, jsx_runtime_1.jsx)(ListColumn_1.ListColumn, { list: list, cards: cards, listIndex: actualIndex, isSelectedList: actualIndex === navState.selectedListIndex, selectedCardIndex: navState.selectedCardIndex, width: listWidth, height: listHeight, maxCardRows: maxCardRows }, list.id));
                            }), visibleEnd < lists.length && ((0, jsx_runtime_1.jsx)(ink_1.Box, { alignItems: "center", marginLeft: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: ">" }) }))] }), lists.length === 0 && ((0, jsx_runtime_1.jsx)(ink_1.Box, { paddingX: 2, paddingY: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { color: config.theme.muted, children: "This board has no lists. Create one with 'trello list:create'." }) }))] }))] }));
}
const LABEL_COLORS = {
    green: "green",
    yellow: "yellow",
    orange: "#FFA500",
    red: "red",
    purple: "magenta",
    blue: "blue",
    sky: "cyan",
    lime: "greenBright",
    pink: "magentaBright",
    black: "white",
};
function openUrl(url) {
    const platform = process.platform;
    const cmd = platform === "darwin" ? "open" :
        platform === "win32" ? "start" :
            "xdg-open";
    (0, child_process_1.exec)(`${cmd} ${JSON.stringify(url)}`);
}
