import { ExpandMore } from "@mui/icons-material"
import { Accordion, AccordionDetails, AccordionSummary, Box, Button, Typography } from "@mui/material"
import SearchSelect, { Option } from "common/SearchSelect"
import { pond } from "protobuf-ts/pond"
import { useGlobalState } from "providers"
import { useGrainAPI } from "providers/pond/grainAPI"
import React, { useEffect, useState } from "react"
import CustomGrainForm from "./CustomGrainForm"

interface Props {
  initialGrain?: pond.GrainSettings
  onGrainSettingsChange: (settings: pond.GrainSettings) => void
}

export default function CustomGrainSelector(props: Props) {
  const {initialGrain, onGrainSettingsChange} = props
  const grainAPI = useGrainAPI()
  const [{as}] = useGlobalState()
  const [newGrainSettings, setNewGrainSettings] = useState(initialGrain ?? pond.GrainSettings.create())
  const [formValid, setFormValid] = useState(true)
  const [grainMap, setGrainMap] = useState<Map<string, pond.GrainObject>>(
    initialGrain ? 
      new Map([
        ["Active", pond.GrainObject.create({key: "Active", name: initialGrain.name, settings: initialGrain})]
      ])
    :
      new Map())
  const [grainOptions, setGrainOptions] = useState<Option[]>(
    initialGrain ? 
      [
        {
          label: initialGrain.name, 
          value: "Active", 
          group: "Active"
        }
      ] 
    : 
      []
    )
  const [isNew, setIsNew] = useState(false)
  const [selectedOption, setSelectedOption] = useState<Option | null>(initialGrain ? {
          label: initialGrain.name, 
          value: "Active", 
          group: "Active"
        } : null)

  useEffect(()=>{
    grainAPI.listGrains(0, 0, "asc", "name", undefined, undefined, undefined, as).then(resp => {
      let options: Option[] = grainOptions
      let map: Map<string, pond.GrainObject> = grainMap
      if (resp.data.grains){
        resp.data.grains.forEach(grain => {
          map.set(grain.key, grain)
          options.push({
            label: grain.name,
            value: grain.key,
            group: grain.settings?.group,
          })
        })
      }
      setGrainOptions([...options])
      setGrainMap(map)
    })
  },[grainAPI])

  const saveGrain = () => {
    // console.log(newGrainSettings)
    grainAPI.addGrain(newGrainSettings, as).then(resp => {
      console.log("grain added")
    }).catch(err => {
      console.log("err")
    })
  }

  const settingsChanged = (newSettings: pond.GrainSettings, formValid: boolean) => {
    setNewGrainSettings(newSettings)
    setIsNew(true)
    setFormValid(formValid)
    onGrainSettingsChange(newSettings)
  }

  const grainAccordion = () => {
    return (
      <Accordion>
       <AccordionSummary expandIcon={<ExpandMore />}>Custom Grain Properties</AccordionSummary> 
       <AccordionDetails>
        <CustomGrainForm grainSettings={newGrainSettings} onGrainSettingsChange={settingsChanged}/>
        {isNew &&
          <Box display='flex' justifyContent="flex-end">
            <Button 
              variant="contained" 
              disabled={!formValid}
              onClick={() => {
                setIsNew(false)
                saveGrain()
              }}
              color="primary">
                Save Custom Grain
            </Button>
          </Box>
        }
       </AccordionDetails>
      </Accordion>
    )
  }

  return (
    <React.Fragment>
      {grainOptions.length === 0 ? 
        <Box>
          <Typography sx={{marginBottom: 1}}>Custom Grain Properties</Typography>
          <CustomGrainForm grainSettings={newGrainSettings} onGrainSettingsChange={settingsChanged}/>
          {isNew &&
            <Box display='flex' justifyContent="flex-end">
              <Button 
                variant="contained" 
                disabled={!formValid}
                onClick={() => {
                  setIsNew(false)
                }}
                color="primary">
                  Save Custom Grain
              </Button>
            </Box>
          }
        </Box>
      :
      <Box>
          <Box sx={{marginBottom: 2}}>
            <SearchSelect
              label="My Grains"
              selected={selectedOption}
              changeSelection={option => {
                setIsNew(false)
                setSelectedOption(option)
                //when an option is selected set all of the state variables controlling the form entries
                let grain = grainMap.get(option?.value)
                if(grain && grain.settings){
                  //the the new grain settings object
                  setNewGrainSettings(grain.settings)
                  //pass that settings object back up
                  settingsChanged(grain.settings, true)
                }
              }}
              group
              options={grainOptions}
            />
          </Box>
          {grainAccordion()}
        </Box>

      }
    </React.Fragment>
  )
}