import type { NextPage } from 'next'
import Head from 'next/head'
import {useGroups} from "../../components/contexts/GroupProvider";
import {useFactories} from "../../src/hooks/useFactories";
import {ProducingGraph, ProducingNode} from "../../components/shared/ProducingGraph";
import {useMemo} from "react";
import {calculateInputs} from "../../src/calculateInputs";
import {useRouter} from "next/router";
import {isNonNullable} from "../../src/utils";
import {EnrichedEntity} from "../../src/types";

const Page: NextPage = () => {
  const {query: {name}} = useRouter()
  const {
    exportedFactories,
    baseFactories,
    ignoredFactories,
    groups
  } = useGroups()
  const {
    findFactory
  } = useFactories()

  const group = typeof name === 'string' ? groups[name] : undefined

  const [inputFactories, intermediateFactories] = useMemo<ReturnType<typeof calculateInputs>>(() => {
    if (!group) return [[], []]
    return calculateInputs(
      [...group.exports, ...group.malls],
      ignoredFactories,
      baseFactories,
      exportedFactories,
      findFactory
    )
  }, [baseFactories, exportedFactories, findFactory, group, ignoredFactories])

  const producingNodes: ProducingNode[] = useMemo(() => {
    if (!group) return []
    return Array.from(new Set([...intermediateFactories, ...group.exports, ...group.malls]))
      .map(findFactory)
      .filter(isNonNullable)
      .map((factory: EnrichedEntity) => ({
        inputs: Object.keys(factory.recipe?.prerequisites ?? {}).sort((a, b) => a.localeCompare(b)),
        outputs: Object.keys(factory.recipe?.output ?? {}).sort((a, b) => a.localeCompare(b)),
        name: factory.name,
        recipe: factory.recipe
      }))
  }, [findFactory, group, intermediateFactories])

  return (
    <div>
      <Head>
        <title>Factorio Microservices</title>
        <meta name="description" content="Create Factorio microservices" />
        <link rel="icon" href="/public/favicon.ico" />
      </Head>
      <main>
        <h1>Factorio Microservices</h1>
        <ProducingGraph nodes={producingNodes} inputs={inputFactories}></ProducingGraph>
      </main>
    </div>
  )
}

export default Page
