// Copyright (C) 2024 The Android Open Source Project
//
// Licensed 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 m from 'mithril';

import {Gate} from '../base/mithril_utils';
import {exists} from '../base/utils';
import {Actions} from '../common/actions';
import {EmptyState} from '../widgets/empty_state';

import {
  DragHandle,
  getDetailsHeight,
  Tab,
  TabDropdownEntry,
} from './drag_handle';
import {globals} from './globals';

interface TabWithContent extends Tab {
  content: m.Children;
}

export class TabPanel implements m.ClassComponent {
  private detailsHeight = getDetailsHeight();

  view() {
    const tabMan = globals.tabManager;
    const tabList = globals.store.state.tabs.openTabs;

    const resolvedTabs = tabMan.resolveTabs(tabList);
    const tabs = resolvedTabs.map(({uri, tab: tabDesc}): TabWithContent => {
      if (tabDesc) {
        return {
          key: uri,
          hasCloseButton: true,
          title: tabDesc.content.getTitle(),
          content: tabDesc.content.render(),
        };
      } else {
        return {
          key: uri,
          hasCloseButton: true,
          title: 'Tab does not exist',
          content: undefined,
        };
      }
    });

    // Add the permanent current selection tab to the front of the list of tabs
    tabs.unshift({
      key: 'current_selection',
      title: 'Current Selection',
      content: this.renderCurrentSelectionTabContent(),
    });

    const tabDropdownEntries =
        globals.tabManager.tabs.filter((tab) => tab.isEphemeral === false)
          .map(({content, uri}): TabDropdownEntry => {
            return {
              key: uri,
              title: content.getTitle(),
              onClick: () => globals.dispatch(Actions.showTab({uri})),
            };
          });

    return [
      m(DragHandle, {
        resize: (height: number) => {
          this.detailsHeight = Math.max(height, 0);
        },
        height: this.detailsHeight,
        tabs,
        currentTabKey: globals.state.tabs.currentTab,
        tabDropdownEntries,
        onTabClick: (key) => globals.dispatch(Actions.showTab({uri: key})),
        onTabClose: (key) => globals.dispatch(Actions.hideTab({uri: key})),
      }),
      m(
        '.details-panel-container',
        {
          style: {height: `${this.detailsHeight}px`},
        },
        tabs.map(({key, content}) => {
          const active = key === globals.state.tabs.currentTab;
          return m(Gate, {open: active}, content);
        }),
      ),
    ];
  }

  private renderCurrentSelectionTabContent(): m.Children {
    const cs = globals.state.currentSelection;
    if (!exists(cs)) {
      return m(EmptyState, {
        className: 'pf-noselection',
        header: 'No selection',
        detail: 'Please select something',
      });
    }

    const sectionReg = globals.tabManager.currentSelectionSections;
    const allSections = Array.from(sectionReg.values());

    // Get the first "truthy" current selection section
    const section =
        allSections.map((dp) => dp.render(cs)).find((panel) => panel);

    if (!Boolean(section)) {
      return m(EmptyState, {
        className: 'pf-noselection',
        header: 'No details available',
        detail: `Selection kind: '${cs.kind}'`,
        icon: 'warning',
      });
    } else {
      return section;
    }
  }
}
