import * as React from "react"
import getLogger from "common/log/Logger"
import {
  FillHeight,
  FlexColumnCenter,
  FlexRowCenter,
  IThemedProperties,
  makeHeightConstraint,
  makePaddingRem,
  mergeClasses, rem,
  StyleDeclaration
} from "renderer/styles/ThemedStyles"


import {IRepo} from "common/models/Repo"
import AutoCompleteSelect from "renderer/components/elements/AutoCompleteSelect"
import * as _ from 'lodash'
import {guard} from "typeguard"
import ReactSelect from 'react-select'
import {StyledComponent} from "renderer/components/elements/StyledComponent"
import {useCallback, useEffect, useMemo, useRef, useState} from "react"
import {useCommandManager} from "renderer/command-manager-ui"
import {assert} from "common/ObjectUtil"
import {currentReposSelector} from "renderer/store/selectors/UISelectors"
const log = getLogger(__filename)


function baseStyles(theme):StyleDeclaration {
	const
		{palette,components:{Select,TextField}} = theme,
		{primary, secondary} = palette

	return {
		root: {
		  flexGrow: 1,
      backgroundColor: TextField.colors.bg,
      backgroundClip: "border-box",
      //borderRadius: rem(0.3)
    },
		paper: {
		  ...Select.paper,
      position: 'absolute',
      //backgroundColor: TextField.colors.bg,
      zIndex: 1,
      //marginTop: theme.spacing.unit,
      left: 0,
      right: 0,
		},
    select: {
      ...makeHeightConstraint(rem(4)),
      ...FlexRowCenter,
      flexGrow: 1,
      //backgroundColor: TextField.colors.bg,
      borderRadius: rem(0.3),
      backgroundClip: "border-box",
      //...makePaddingRem(1,1),
      backgroundColor: "rgba(255, 255, 255, 0.09)",

      "& > div": {
        flexGrow: 1,
        ...FlexRowCenter,
        ...FillHeight
      }
    }
	}
}

interface P extends IThemedProperties {
	onSelection: (repo:IRepo) => void
	onOpen?:(open:boolean) => void
	value:IRepo
  open?: boolean | undefined
  repos?:Array<IRepo> | undefined
  selectRef?: React.Ref<ReactSelect<IRepo>> | React.RefObject<ReactSelect<IRepo>>
}

interface SP {
  defaultRepos:Array<IRepo>
}

function idGetter(value:IRepo):string {
  return value.id.toString(10)
}

function labelGetter(value:IRepo):string {
  return value.full_name
}

export default StyledComponent<P,SP>(baseStyles,{
  defaultRepos: currentReposSelector,
},{withTheme: true})(function RepoSelect(props:P & SP):React.ReactElement<P> {
	const
		{
		  id,
			theme,
      className,
      classes,
      repos = props.defaultRepos,
      defaultRepos,
      value,
      open: menuIsOpen,
      innerRef,
      selectRef:inSelectRef,
      onSelection,
			...other
		} = props,
    [open, setOpen] = useState(false),
		selectRef = inSelectRef || useRef<ReactSelect<IRepo>>(null),
    onOpen = useCallback(() => setOpen(true),[open]),
    onClose = useCallback(() => setOpen(false),[open])

  assert(() => !!id,() => "ID is required")

  const
    {props:commandManagerProps} = useCommandManager(
			id,
				builder => builder.make(),
			selectRef as React.RefObject<any>
		)

	useEffect(() => {
    guard(() => props.onOpen(open))
	},[open])

	const styles = useMemo(() => ({
    input: (base,state,...other) => {
      return {
        ...base,
        color: theme.palette.primary.contrastText
      }
    },
    menuPortal: (base,state) => {
      return {
        ..._.omit(base,'width','left'),
        right: window.innerWidth - base.left - base.width,
        minWidth: base.width,
        maxWidth: "40vw",
        zIndex: 9999,
      }
    }
  }),[theme,open])




  return <div className={mergeClasses(classes.root,className)}>
    <AutoCompleteSelect
      options={repos}
      selectRef={selectRef}
      onSelection={onSelection}
      commandManagerProps={commandManagerProps}
      idGetter={idGetter}
      labelGetter={labelGetter}
      classes={{
        root: classes.select,
        paper: classes.paper
      }}
      styles={styles}
      {...(other as any)}
    />
	</div>
})
      value={value}
      menuIsOpen={menuIsOpen}
      onMenuOpen={onOpen}
      onMenuClose={onClose}