import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEventSubscription, useFlows, usePauseFlow, useResumeFlow, useSyncFlow } from "@ghostflow/ui-core";
import { Array as Arr, Data, Match, Option as O, pipe } from "effect";
import { Box, Text, useInput } from "ink";
import { useState } from "react";
import { ConnectionStatus } from "../components/ConnectionStatus.js";
import { FlowList } from "../components/FlowList.js";
import { DASHBOARD_HINTS, KeyHints } from "../components/KeyHints.js";
import { useTerminalDimensions } from "../hooks/useTerminalDimensions.js";
// ============================================================================
// Constants
// ============================================================================
/** Initial selection index */
const INITIAL_SELECTION_INDEX = 0;
/** Minimum selection index (first item) */
const MIN_SELECTION_INDEX = 0;
/** Loading text displayed while fetching flows */
const LOADING_TEXT = "Loading flows...";
/** Error prefix for flow loading errors */
const ERROR_PREFIX = "Error loading flows:";
/** Quit hint text */
const QUIT_HINT = "Press 'q' to quit";
/** Key bindings */
const KEY_ADD = "a";
const KEY_REMOVE = "r";
const KEY_SYNC = "s";
const KEY_PAUSE_RESUME = "p";
const KEY_QUIT = "q";
/** Tagline displayed when no flows */
const TAGLINE = "Your work, always synced";
/** Reserved rows for chrome (header=2, summary=1, key hints=1, padding=2) */
const CHROME_ROWS = 6;
// ============================================================================
// Helpers
// ============================================================================
/**
 * Execute an action on the selected flow if present.
 * Returns true if action was executed, false if no flow selected.
 */
const withSelectedFlow = (selectedFlow, action) => O.match(selectedFlow, {
    onNone: () => false,
    onSome: (flow) => {
        action(flow);
        return true;
    }
});
/** Calculate max selection index from flows array */
const getMaxSelectionIndex = (flows) => Math.max(MIN_SELECTION_INDEX, flows.length - 1);
/** Decrement index with minimum bound */
const decrementIndex = (current) => Math.max(MIN_SELECTION_INDEX, current - 1);
/** Increment index with maximum bound */
const incrementIndex = (flows) => (current) => Math.min(getMaxSelectionIndex(flows), current + 1);
/** Handle keyboard navigation (up/down arrows) */
const handleKeyNavigation = (key, flows, setSelectedIndex) => pipe(Match.value(key), Match.when(({ upArrow }) => upArrow, () => setSelectedIndex(decrementIndex)), Match.when(({ downArrow }) => downArrow, () => setSelectedIndex(incrementIndex(flows))), Match.orElse(() => { }));
const FlowListStatus = Data.taggedEnum();
/** Determine flow list status from counts */
const determineStatus = (counts, totalCount) => {
    if (counts.error > 0)
        return FlowListStatus.HasErrors({ count: counts.error });
    if (counts.syncing > 0)
        return FlowListStatus.Syncing();
    if (counts.paused === totalCount)
        return FlowListStatus.AllPaused();
    if (counts.paused > 0)
        return FlowListStatus.SomePaused({ count: counts.paused });
    if (counts.idle === totalCount)
        return FlowListStatus.AllSynced();
    return FlowListStatus.Synced();
};
/** Convert status to display text with exhaustive matching */
const statusToText = (status) => FlowListStatus.$match(status, {
    HasErrors: ({ count }) => `${count} error${count > 1 ? "s" : ""}`,
    Syncing: () => "Syncing",
    AllPaused: () => "All paused",
    SomePaused: ({ count }) => `${count} paused`,
    AllSynced: () => "All synced",
    Synced: () => "Synced"
});
const countFlowStates = (flows) => Arr.reduce(flows, { idle: 0, syncing: 0, error: 0, paused: 0 }, (acc, flow) => pipe(Match.value(flow.state), Match.when("idle", () => ({ ...acc, idle: acc.idle + 1 })), Match.when("syncing", () => ({ ...acc, syncing: acc.syncing + 1 })), Match.when("error", () => ({ ...acc, error: acc.error + 1 })), Match.when("paused", () => ({ ...acc, paused: acc.paused + 1 })), Match.exhaustive));
/** Generate flow summary text (e.g., "3 flows · All synced") */
const getFlowSummary = (flows) => {
    const count = flows.length;
    const flowWord = count === 1 ? "flow" : "flows";
    const counts = countFlowStates(flows);
    const status = statusToText(determineStatus(counts, count));
    return `${count} ${flowWord} · ${status}`;
};
/** Calculate available rows for flow list */
const getContentHeight = (terminalRows) => Math.max(3, terminalRows - CHROME_ROWS);
// ============================================================================
// Component
// ============================================================================
/**
 * Dashboard screen with flow list and keyboard controls.
 * Fills terminal height with header, tagline, flow list, and key hints.
 */
export const DashboardScreen = ({ send }) => {
    const { data, error, isError, isPending } = useFlows();
    const { rows: terminalRows } = useTerminalDimensions();
    useEventSubscription();
    const [selectedIndex, setSelectedIndex] = useState(INITIAL_SELECTION_INDEX);
    // Convert undefined data to empty readonly array using Option
    const flows = pipe(O.fromNullable(data), O.getOrElse(() => []));
    // Clamp selection index to valid range (derived state, not effect)
    const clampedIndex = flows.length > 0
        ? Math.min(selectedIndex, flows.length - 1)
        : INITIAL_SELECTION_INDEX;
    const syncFlow = useSyncFlow();
    const pauseFlow = usePauseFlow();
    const resumeFlow = useResumeFlow();
    // Get currently selected flow using safe array access
    const selectedFlow = Arr.get(flows, clampedIndex);
    // Handle pause/resume toggle based on flow state
    const togglePauseResume = (flow) => pipe(Match.value(flow.state), Match.when("paused", () => resumeFlow.mutate(flow.id)), Match.orElse(() => pauseFlow.mutate(flow.id)));
    // Handle action key inputs
    const handleActionInput = (input) => {
        pipe(Match.value(input), Match.when(KEY_ADD, () => send({ type: "OPEN_ADD_WIZARD" })), Match.when(KEY_REMOVE, () => withSelectedFlow(selectedFlow, (flow) => send({
            type: "CONFIRM_REMOVE",
            flowId: flow.id,
            flowName: flow.name
        }))), Match.when(KEY_SYNC, () => withSelectedFlow(selectedFlow, (flow) => syncFlow.mutate(flow.id))), Match.when(KEY_PAUSE_RESUME, () => withSelectedFlow(selectedFlow, togglePauseResume)), Match.when(KEY_QUIT, () => send({ type: "EXIT" })), Match.orElse(() => { }));
    };
    // Handle Enter key for flow detail (future: OPEN_FLOW_DETAIL event)
    const handleEnterKey = () => {
        // TODO: Week 2 - Enable when flow detail screen is implemented
        // withSelectedFlow(selectedFlow, (flow) =>
        //   send({ type: "OPEN_FLOW_DETAIL", flowId: flow.id })
        // )
    };
    // Calculate content height for flow list
    const contentHeight = getContentHeight(terminalRows);
    // Keyboard handling - always active (including during loading/error states)
    useInput((input, key) => {
        // Quit is always available
        if (input === KEY_QUIT) {
            send({ type: "EXIT" });
            return;
        }
        // Navigation and actions only when data is ready
        if (!isPending && !isError) {
            if (key.upArrow || key.downArrow) {
                handleKeyNavigation(key, flows, setSelectedIndex);
            }
            else if (key.return) {
                handleEnterKey();
            }
            else {
                handleActionInput(input);
            }
        }
    });
    // Loading state
    if (isPending) {
        return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { children: LOADING_TEXT }), _jsx(Text, { dimColor: true, children: QUIT_HINT })] }));
    }
    // Error state
    if (isError) {
        return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { color: "red", children: [ERROR_PREFIX, " ", String(error)] }), _jsx(Text, { dimColor: true, children: QUIT_HINT })] }));
    }
    // Generate summary text using Option pattern
    const summary = Arr.match(flows, {
        onEmpty: () => O.none(),
        onNonEmpty: (nonEmptyFlows) => O.some(getFlowSummary(nonEmptyFlows))
    });
    // Subtract 1 for Ink's cursor line to prevent scroll
    const screenHeight = terminalRows - 1;
    return (_jsxs(Box, { flexDirection: "column", height: screenHeight, children: [_jsxs(Box, { borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, justifyContent: "space-between", paddingX: 1, children: [_jsx(Text, { bold: true, children: "Ghostflow" }), _jsx(ConnectionStatus, {})] }), _jsx(Box, { paddingX: 1, paddingTop: 1, justifyContent: "space-between", children: O.match(summary, {
                    onSome: (s) => _jsx(Text, { dimColor: true, children: s }),
                    onNone: () => _jsx(Text, { dimColor: true, children: TAGLINE })
                }) }), _jsx(Box, { flexDirection: "column", flexGrow: 1, height: contentHeight, children: _jsx(FlowList, { flows: flows, selectedIndex: clampedIndex }) }), _jsx(KeyHints, { hints: DASHBOARD_HINTS })] }));
};
//# sourceMappingURL=DashboardScreen.js.map