import React, { useState, useCallback } from "react";
import { render, Box, Text, useApp, useInput } from "ink";

import MainMenu from "./screens/MainMenu.jsx";
import FrpMenu from "./screens/FrpMenu.jsx";
import TokenPrompt from "./screens/TokenPrompt.jsx";
import ProxyForm from "./screens/ProxyForm.jsx";
import ProxyList from "./screens/ProxyList.jsx";
import PlanPreview from "./screens/PlanPreview.jsx";
import RunLog from "./screens/RunLog.jsx";
import FrpConfigForm from "./screens/FrpConfigForm.jsx";
import SshKeyPrompt from "./screens/SshKeyPrompt.jsx";

function App() {
  const { exit } = useApp();
  const [stack, setStack] = useState([{ name: "main" }]);
  const screen = stack[stack.length - 1];

  const push = useCallback((next) => {
    setStack((current) => [...current, next]);
  }, []);

  const replace = useCallback((next) => {
    setStack((current) => [...current.slice(0, -1), next]);
  }, []);

  const back = useCallback(() => {
    setStack((current) => (current.length > 1 ? current.slice(0, -1) : current));
  }, []);

  const home = useCallback(() => {
    setStack([{ name: "main" }]);
  }, []);

  useInput((input, key) => {
    if (key.escape && stack.length > 1 && screen.name !== "run") {
      back();
    }
    if (input === "q" && screen.name === "main") {
      exit();
    }
  });

  const nav = { push, replace, back, home, exit };

  return (
    <Box flexDirection="column" paddingX={1}>
      <Header />
      <Box flexDirection="column" marginTop={1}>
        {renderScreen(screen, nav)}
      </Box>
      <Footer screen={screen.name} />
    </Box>
  );
}

function renderScreen(screen, nav) {
  switch (screen.name) {
    case "main":
      return <MainMenu nav={nav} />;
    case "frp":
      return <FrpMenu nav={nav} />;
    case "token":
      return <TokenPrompt nav={nav} {...screen.props} />;
    case "frp-config-form":
      return <FrpConfigForm nav={nav} {...screen.props} />;
    case "proxy-form":
      return <ProxyForm nav={nav} {...screen.props} />;
    case "proxy-list":
      return <ProxyList nav={nav} {...screen.props} />;
    case "ssh-key":
      return <SshKeyPrompt nav={nav} {...screen.props} />;
    case "plan":
      return <PlanPreview nav={nav} {...screen.props} />;
    case "run":
      return <RunLog nav={nav} {...screen.props} />;
    default:
      return <Text>Unknown screen: {screen.name}</Text>;
  }
}

const LOGO = String.raw` ____                  ____       _ _
|  _ \  ___  ___ _ __ |  _ \ ___ | (_) ___ _   _
| | | |/ _ \/ _ \ '_ \| |_) / _ \| | |/ __| | | |
| |_| |  __/  __/ |_) |  __/ (_) | | | (__| |_| |
|____/ \___|\___| .__/|_|   \___/|_|_|\___|\__, |
                |_|                        |___/`;

function Header() {
  return (
    <Box flexDirection="column" borderStyle="round" borderColor="cyan" paddingX={1}>
      <Text color="cyan" bold>{LOGO}</Text>
      <Box marginTop={1}>
        <Text color="cyan" bold>server-config</Text>
        <Text dimColor>  zsh · ssh · frp client</Text>
      </Box>
    </Box>
  );
}

function Footer({ screen }) {
  const hint =
    screen === "main"
      ? "↑↓ select · Enter confirm · q quit"
      : screen === "run"
        ? "(Esc disabled while running)"
        : "↑↓ select · Enter confirm · Esc back";
  return (
    <Box marginTop={1}>
      <Text dimColor>{hint}</Text>
    </Box>
  );
}

export function start() {
  render(<App />);
}

start();
