/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { useMemo, FC } from 'react';

import { bindActionCreators } from 'redux';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import { MenuDotsDropdown } from '@superset-ui/core/components';
import { Menu, MenuItemType } from '@superset-ui/core/components/Menu';
import { t, QueryState } from '@superset-ui/core';
import { styled, css, SupersetTheme, useTheme } from '@apache-superset/core/ui';
import {
  removeQueryEditor,
  removeAllOtherQueryEditors,
  queryEditorSetTitle,
  cloneQueryToNewTab,
  toggleLeftBar,
} from 'src/SqlLab/actions/sqlLab';
import { QueryEditor, SqlLabRootState } from 'src/SqlLab/types';
import { Icons, type IconType } from '@superset-ui/core/components/Icons';

const TabTitleWrapper = styled.div`
  display: flex;
  align-items: center;

  [aria-label='check-circle'],
  .status-icon {
    margin: 0px;
  }
`;
const TabTitle = styled.span`
  margin-right: ${({ theme }) => theme.sizeUnit * 2}px;
  text-transform: none;
`;

const IconContainer = styled.div`
  ${({ theme }) => css`
    display: inline-block;
    margin: 0 ${theme.sizeUnit * 2}px 0 0px;
  `}
`;
interface Props {
  queryEditor: QueryEditor;
}

const STATE_ICONS: Record<string, FC<IconType>> = {
  started: Icons.CircleSolid,
  stopped: Icons.StopOutlined,
  pending: Icons.CircleSolid,
  scheduled: Icons.CalendarOutlined,
  fetching: Icons.CircleSolid,
  timedOut: Icons.FieldTimeOutlined,
  running: Icons.CircleSolid,
  success: Icons.CheckCircleOutlined,
  failed: Icons.CloseCircleOutlined,
};

const SqlEditorTabHeader: FC<Props> = ({ queryEditor }) => {
  const theme = useTheme();
  const qe = useSelector<SqlLabRootState, QueryEditor>(
    ({ sqlLab: { unsavedQueryEditor } }) => ({
      ...queryEditor,
      ...(queryEditor.id === unsavedQueryEditor?.id && unsavedQueryEditor),
    }),
    shallowEqual,
  );
  const queryState = useSelector<SqlLabRootState, QueryState>(
    ({ sqlLab }) => sqlLab.queries[qe.latestQueryId || '']?.state || '',
  );
  const StatusIcon = queryState ? STATE_ICONS[queryState] : STATE_ICONS.running;

  const dispatch = useDispatch();
  const actions = useMemo(
    () =>
      bindActionCreators(
        {
          removeQueryEditor,
          removeAllOtherQueryEditors,
          queryEditorSetTitle,
          cloneQueryToNewTab,
          toggleLeftBar,
        },
        dispatch,
      ),
    [dispatch],
  );

  function renameTab() {
    const newTitle = prompt(t('Enter a new title for the tab'));
    if (newTitle) {
      actions.queryEditorSetTitle(qe, newTitle, qe.id);
    }
  }
  const getStatusColor = (state: QueryState, theme: SupersetTheme): string => {
    const statusColors: Record<QueryState, string> = {
      [QueryState.Running]: theme.colorInfo,
      [QueryState.Success]: theme.colorSuccess,
      [QueryState.Failed]: theme.colorError,
      [QueryState.Started]: theme.colorPrimary,
      [QueryState.Stopped]: theme.colorWarning,
      [QueryState.Pending]: theme.colorIcon,
      [QueryState.Scheduled]: theme.colorIcon,
      [QueryState.Fetching]: theme.colorWarning,
      [QueryState.TimedOut]: theme.colorError,
    };

    return statusColors[state] || theme.colorIcon;
  };
  return (
    <TabTitleWrapper>
      <MenuDotsDropdown
        trigger={['click']}
        overlay={
          <Menu
            items={[
              {
                className: 'close-btn',
                key: '1',
                onClick: () => actions.removeQueryEditor(qe),
                'data-test': 'close-tab-menu-option',
                label: (
                  <>
                    <IconContainer>
                      <Icons.CloseOutlined
                        iconSize="l"
                        css={css`
                          verticalalign: middle;
                        `}
                      />
                    </IconContainer>
                    {t('Close tab')}
                  </>
                ),
              } as MenuItemType,
              {
                key: '2',
                onClick: renameTab,
                'data-test': 'rename-tab-menu-option',
                label: (
                  <>
                    <IconContainer>
                      <Icons.EditOutlined
                        css={css`
                          verticalalign: middle;
                        `}
                        iconSize="l"
                      />
                    </IconContainer>
                    {t('Rename tab')}
                  </>
                ),
              } as MenuItemType,
              {
                key: '4',
                onClick: () => actions.removeAllOtherQueryEditors(qe),
                'data-test': 'close-all-other-menu-option',
                label: (
                  <>
                    <IconContainer>
                      <Icons.CloseOutlined
                        iconSize="l"
                        css={css`
                          vertical-align: middle;
                        `}
                      />
                    </IconContainer>
                    {t('Close all other tabs')}
                  </>
                ),
              } as MenuItemType,
              {
                key: '5',
                onClick: () => actions.cloneQueryToNewTab(qe, false),
                'data-test': 'clone-tab-menu-option',
                label: (
                  <>
                    <IconContainer>
                      <Icons.CopyOutlined
                        iconSize="l"
                        css={css`
                          vertical-align: middle;
                        `}
                      />
                    </IconContainer>
                    {t('Duplicate tab')}
                  </>
                ),
              } as MenuItemType,
            ]}
          />
        }
      />
      <TabTitle>{qe.name}</TabTitle>{' '}
      <StatusIcon
        className="status-icon"
        iconSize="m"
        iconColor={getStatusColor(queryState, theme)}
      />{' '}
    </TabTitleWrapper>
  );
};

export default SqlEditorTabHeader;
