import styled from "@emotion/styled"
import Icon from "@aet/icons/macro"
import { useTranslation } from "react-i18next"
import { css, cx } from "@emotion/css"
import { memo } from "react"
import { PanelPosition } from "../App"
import { TabButton } from "~/shared/styled"
import { Rules } from "./rules/index"
import { Issues } from "./Issues"
import { Tags } from "./tags/index"
import { Statistics } from "./Statistics"
import { getMap } from "../utils/componentMap"
import { LIGHT_MODE, token } from "../theme"
import { useSelector } from "../store"
import { Preview } from "./Preview"

interface PanelProps {
  pane: Tab
  position: PanelPosition
  setPane(pane: Tab): void
  setPosition(position: PanelPosition): void
  style?: React.CSSProperties
}

const positionsToIcon = getMap<
  PanelPosition,
  (props: { style?: React.CSSProperties }) => React.ReactElement
>(() => ({
  [PanelPosition.Right]: Icon.of("BiDockRight"),
  [PanelPosition.Bottom]: Icon.of("BiDockBottom"),
}))

export enum Tab {
  Rules = "Rules",
  Issues = "Issues",
  Tags = "Tags",
  Statistics = "Statistics",
  Preview = "Preview",
}

const tabs = Object.values(Tab)

const PositionToggle = memo<PanelProps & { pos: PanelPosition }>(props => {
  const { pos, position, setPosition } = props
  const Icon = positionsToIcon.get(pos)

  return (
    <TabButton key={pos} onClick={() => setPosition(pos)} active={pos === position}>
      <Icon style={{ marginRight: 0 }} />
    </TabButton>
  )
})

export const Panels = memo<PanelProps>(props => {
  const { position, pane, setPane, ...rest } = props
  const hasFiles = useSelector(s => s.tabs.length > 0)

  const tab = getActiveTab(pane)
  const { t } = useTranslation()

  function getTabName(tab: Tab) {
    switch (tab) {
      case Tab.Rules:
        return t("editorPane.rules")
      case Tab.Issues:
        return t("editorPane.issues")
      case Tab.Tags:
        return t("editorPane.tags")
      case Tab.Statistics:
        return t("editorPane.statistics")
      case Tab.Preview:
        return t("editorPane.preview")
    }
  }

  if (position == null || !hasFiles) {
    return null
  }

  return (
    <PanelContainer {...rest}>
      <Toolbar>
        <TabContainer>
          {tabs.map(tab => (
            <TabButton key={tab} active={tab === pane} onClick={() => setPane(tab)}>
              {getTabName(tab)}
            </TabButton>
          ))}
        </TabContainer>
        <PositionToggleContainer>
          <PositionToggle {...props} pos={PanelPosition.Right} />
          <PositionToggle {...props} pos={PanelPosition.Bottom} />
        </PositionToggleContainer>
      </Toolbar>
      {tab}
    </PanelContainer>
  )
})

function getActiveTab(activeTab: Tab | null) {
  return (
    <>
      <Rules className={cx(Tab.Rules !== activeTab && hidden)} />
      <Issues className={cx(Tab.Issues !== activeTab && hidden)} />
      <Tags className={cx(Tab.Tags !== activeTab && hidden)} />
      <Statistics className={cx(Tab.Statistics !== activeTab && hidden)} />
      <Preview
        className={cx(Tab.Preview !== activeTab && hidden)}
        active={Tab.Preview === activeTab}
      />
    </>
  )
}

const hidden = css`
  display: none !important;
`

const PanelContainer = styled.div`
  display: flex;
  flex-direction: column;
  height: 100%;
  ${LIGHT_MODE} {
    background: ${token.canvas.inset};
  }
`

const Toolbar = styled.div`
  display: flex;
  margin-left: 10px;
  margin-top: 9px;
`
const TabContainer = styled.div`
  display: flex;
  gap: 5px;
  flex-grow: 1;
`
const PositionToggleContainer = styled.div`
  display: flex;
  font-size: 1.2em;
  margin-right: 12px;
`
