import React, { useEffect, useState } from "react";
import { Box, render, UseInput, UseStdout } from "./interactive/Ink";
import { getApiKey } from "../zygonApi";
import { ConfiguredFilter } from "./interactive/Filter";
import { Breadcrumb, Step } from "./interactive/Breadcrumb";
import { EntityPicker } from "./interactive/EntityPicker";
import { FieldsPicker } from "./interactive/FieldsPicker";
import { FiltersPicker } from "./interactive/FiltersPicker";
import { QueryResults } from "./interactive/QueryResults";
import {
  KeyboardShortcuts,
  KeyboardShortcutsProvider,
} from "./interactive/KeyboardShortcuts";

export type Entity = "app" | "account" | "user" | "task";

export const entityToTable = (entity: Entity): string => {
  switch (entity) {
    case "app":
      return "appInstance";
    case "account":
      return "appAccount";
    case "user":
      return "collaborator";
    case "task":
      return "todo";
  }
};

const useShellDimensions = (useStdout: UseStdout): [number, number] => {
  const { stdout } = useStdout();
  const [dimensions, setDimensions] = useState<[number, number]>([
    stdout?.columns || 0,
    (stdout?.rows || 1) - 1,
  ]);

  useEffect(() => {
    const handler = () =>
      setDimensions([stdout?.columns || 0, (stdout?.rows || 1) - 1]);
    stdout?.on("resize", handler);
    return () => {
      stdout?.off("resize", handler);
    };
  }, [stdout]);

  return dimensions;
};

type ZQueryBuilderProps = {
  apiKey: string;
  useStdout: UseStdout;
  useInput: UseInput;
};

const ZQueryBuilder = ({ apiKey, useStdout, useInput }: ZQueryBuilderProps) => {
  const [width, height] = useShellDimensions(useStdout);

  const [entity, setEntity] = useState<null | Entity>(null);
  const [selectedFields, setSelectedFields] = useState<Array<string>>([]);
  const [selectedFilters, setSelectedFilters] = useState<
    Array<ConfiguredFilter>
  >([]);

  const [step, setStep] = useState(Step.Entity);

  return (
    <KeyboardShortcutsProvider>
      <Box flexDirection="column" width={width} height={height} gap={1}>
        <Breadcrumb step={step} />

        {step === Step.Entity && (
          <EntityPicker
            width={width}
            height={height - 3}
            onEntitySelection={(entity) => {
              setEntity(entity);
              setStep(Step.Fields);
            }}
            useInput={useInput}
          />
        )}

        {step === Step.Fields && (
          <FieldsPicker
            entity={entity!}
            width={width}
            height={height - 3}
            onFieldsSelection={(fields) => {
              setSelectedFields(fields);
              setStep(Step.Filters);
            }}
            useInput={useInput}
            apiKey={apiKey}
          />
        )}

        {step === Step.Filters && (
          <FiltersPicker
            entity={entity!}
            width={width}
            height={height - 3}
            onFiltersSelection={(filters) => {
              setSelectedFilters(filters);
              setStep(Step.Results);
            }}
            useInput={useInput}
            apiKey={apiKey}
          />
        )}

        {step === Step.Results && (
          <QueryResults
            entity={entity!}
            fields={selectedFields}
            filters={selectedFilters}
            width={width}
            height={height - 3}
            useInput={useInput}
            apiKey={apiKey}
          />
        )}

        <KeyboardShortcuts />
      </Box>
    </KeyboardShortcutsProvider>
  );
};

export const interactive = async () => {
  const apiKey = getApiKey();

  const { useStdout, useInput } = await import("ink");

  await render(
    <ZQueryBuilder apiKey={apiKey} useStdout={useStdout} useInput={useInput} />,
  );
};
