import {FC, useMemo} from "react";
import {FactorySelect} from "./FactorySelect";
import {useDetails} from "../src/hooks/useDetails";
import {Entity, Group} from "../src/types";
import styles from "./Group.module.css"
import {EntitySpan} from "./EntitySpan";

interface Props {
  onRemove: () => void
  onSetOutputFactories: (uids: string[]) => void
  onSetIntermediateFactories: (uids: string[]) => void
  onSetInputFactories: (uids: string[]) => void
  onToggleExported: () => void
  onRename: (name: string) => void
  onDoIgnore: (name: string) => void
  group: Group
  sets: {
    doNotSuggest: Set<string>
    basic: Set<string>
    exported: Set<string>
  }
}

export const GroupBox: FC<Props> = ({
  onRemove,
  onRename,
  onSetOutputFactories,
  onSetIntermediateFactories,
  onSetInputFactories,
  onToggleExported,
  group: {
    inputs,
    intermediates,
    factories,
    isExported,
    name
  },
  sets: {
    doNotSuggest,
    basic,
    exported
  },
  onDoIgnore
}) => {
  const details = useDetails()

  const calculatedInputs = useMemo<string[]>(() => {
    const newData: string[] = details
      .filter(detail => intermediates.includes(detail.href) || factories.includes(detail.href))
      .flatMap(detail => Object.keys(detail.recipe?.prerequisites ?? {}))
    const uniqueInputs = Array.from(new Set(newData))
    return uniqueInputs
      .filter(input => !intermediates.includes(input) && !factories.includes(input))
  }, [details, intermediates, factories])

  const suggestions = useMemo<Entity[]>(() => {
    const availableIngredients = Array.from(new Set([...intermediates, ...factories, ...calculatedInputs, ...inputs]))
    const selectedValues = Array.from(new Set([...intermediates, ...factories, ...inputs]))
    return details
      .filter(detail => {
        if (!detail.recipe) return false
        if (selectedValues.includes(detail.href)) return false
        if (doNotSuggest.has(detail.href)) return false
        const prerequisites = Object.keys(detail.recipe?.prerequisites ?? {})
        return prerequisites.every(pre => availableIngredients.includes(pre))
      })
  }, [inputs, doNotSuggest, details, calculatedInputs, intermediates, factories])

  const addIntermediateFactory = (uid: string) => {
    onSetIntermediateFactories([...intermediates, uid])
  }

  const addOutputFactory = (uid: string) => {
    onSetOutputFactories([...factories, uid])
  }

  return <div style={{border: "2px solid black", padding: "0.5em", margin: "1em"}}>
    <div>
      <h3
        contentEditable={true}
        suppressContentEditableWarning={true}
        onBlur={event => {
          event.currentTarget.innerText = event.currentTarget.innerText.trim()
          onRename(event.currentTarget.innerText);
        }}
      >
        {name}
      </h3>
      <button onClick={onRemove} style={{display: 'block'}}>X</button>
      <input type={"checkbox"} onChange={onToggleExported} checked={isExported} style={{display: 'block'}}/>
      <label>Additional Inputs</label>
      <FactorySelect
        factories={inputs}
        onSetFactories={onSetInputFactories}
      />
      <label>Intermediate Factories</label>
      <FactorySelect
        factories={intermediates}
        onSetFactories={onSetIntermediateFactories}
      />
      <label>Output Factories</label>
      <FactorySelect
        factories={factories}
        onSetFactories={onSetOutputFactories}
      />
      <div className={styles.grid}>
        <div>
          <h4>Inputs</h4>
          <ul>
            {
              calculatedInputs.map(input => <li key={input}><EntitySpan
                value={input}
                onClick={() => addIntermediateFactory(input)}
                style={{color: basic.has(input) ? 'darkgreen' : exported.has(input) ? 'orange' : undefined}}
                leftClickText={"Add to intermediate factories"}
              /></li>)
            }
          </ul>
        </div>
        <div>
          <h4>Suggestions</h4>
          <ul>
            {suggestions.map(suggestion => <li key={suggestion.href}>
              <EntitySpan
                value={suggestion}
                onClick={() => addOutputFactory(suggestion.href)}
                onContextMenu={event => {
                  event.preventDefault()
                  onDoIgnore(suggestion.href)
                }}
                leftClickText={"Add to output factories"}
                rightClickText={"Exclude this recipe from suggestions"}
              />
            </li>)}
          </ul>
        </div>
      </div>
    </div>
  </div>
}
