// Copyright (C) 2022 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 {
  RecordingTargetV2,
  TargetFactory,
} from '../../common/recordingV2/recording_interfaces_v2';
import {
  RecordingPageController,
} from '../../common/recordingV2/recording_page_controller';
import {fullscreenModalContainer} from '../modal';

interface RecordingMultipleChoiceAttrs {
  targetFactories: TargetFactory[];
  // Reference to the controller which maintains the state of the recording
  // page.
  controller: RecordingPageController;
}

export class RecordingMultipleChoice implements
    m.ClassComponent<RecordingMultipleChoiceAttrs> {
  private selectedIndex: number = -1;

  targetSelection(
      targets: RecordingTargetV2[],
      controller: RecordingPageController): m.Vnode|undefined {
    const targetInfo = controller.getTargetInfo();
    const targetNames = [];
    this.selectedIndex = -1;
    for (let i = 0; i < targets.length; i++) {
      const targetName = targets[i].getInfo().name;
      targetNames.push(m('option', targetName));
      if (targetInfo && targetName === targetInfo.name) {
        this.selectedIndex = i;
      }
    }

    const selectedIndex = this.selectedIndex;
    return m(
        'label',
        m('select',
          {
            selectedIndex,
            onchange: (e: Event) => {
              controller.onTargetSelection(
                  (e.target as HTMLSelectElement).value);
            },
            onupdate: (select) => {
              // Work around mithril bug
              // (https://github.com/MithrilJS/mithril.js/issues/2107): We
              // may update the select's options while also changing the
              // selectedIndex at the same time. The update of selectedIndex
              // may be applied before the new options are added to the
              // select element. Because the new selectedIndex may be
              // outside of the select's options at that time, we have to
              // reselect the correct index here after any new children were
              // added.
              (select.dom as HTMLSelectElement).selectedIndex =
                  this.selectedIndex;
            },
            ...{size: targets.length, multiple: 'multiple'},
          },
          ...targetNames),
    );
  }

  view({attrs}: m.CVnode<RecordingMultipleChoiceAttrs>): m.Vnode[]|undefined {
    const controller = attrs.controller;
    if (!controller.shouldShowTargetSelection()) {
      return undefined;
    }
    const targets: RecordingTargetV2[] = [];
    for (const targetFactory of attrs.targetFactories) {
      for (const target of targetFactory.listTargets()) {
        targets.push(target);
      }
    }
    if (targets.length === 0) {
      return undefined;
    }

    return [
      m('text', 'Select target:'),
      m('.record-modal-command',
        this.targetSelection(targets, controller),
        m('button.record-modal-button-high',
          {
            disabled: this.selectedIndex === -1,
            onclick: () => {
              fullscreenModalContainer.close();
              controller.onStartRecordingPressed();
            },
          },
          'Connect')),
    ];
  }
}
