/*
 * Copyright 2022 The Kubernetes Authors
 *
 * 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.
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import React from 'react';
import { i18n } from '@kui-shell/core/mdist/api/i18n';
import { Graph, Memoizer } from 'madwizard';
import Progress from './Progress';
import Card from '../../../../spi/Card';
import Loading from '../../../../spi/Loading';
import { statusFromStatusVector } from '../../../ProgressStepper';
import { MiniProgressStepper } from '../../../MiniProgressStepper';
import { subscribeToLinkUpdates, unsubscribeToLinkUpdates } from '../../../LinkStatus';
const KWizard = React.lazy(() => import('./KWizard'));
const strings = i18n('plugin-client-common', 'code');
export default class Wizard extends React.PureComponent {
    constructor(props) {
        super(props);
        this.cleaners = [];
        this._statusUpdateHandler = (statusVector, codeBlockId) => {
            const status = statusFromStatusVector(statusVector, false);
            this.updateStatus(codeBlockId, status);
        };
        this.memos = new Memoizer();
        this.state = {
            graph: undefined,
            status: undefined,
            codeBlocksPerStep: undefined
        };
    }
    init(props) {
        return __awaiter(this, void 0, void 0, function* () {
            const codeBlocks = yield Promise.all(Wizard.children(props).map(_ => Graph.compile(Wizard.containedCodeBlocks(_), props.choices, this.memos)));
            this.setState(state => {
                const status = state.status || {};
                const codeBlocksPerStep = codeBlocks.map(codeBlocksInStep => Graph.blocks(codeBlocksInStep, props.choices).map(_ => ({
                    codeBlockId: _.id,
                    validate: _.validate,
                    body: _.body,
                    language: _.language,
                    optional: _.optional,
                    status: status[_.id]
                })));
                const noChangeToCodeBlocks = state && Wizard.sameCodeBlocks(state.codeBlocksPerStep, codeBlocksPerStep);
                return {
                    status,
                    codeBlocksPerStep: noChangeToCodeBlocks ? state.codeBlocksPerStep : codeBlocksPerStep,
                    graph: noChangeToCodeBlocks ? state.graph : Graph.order(Graph.sequence(codeBlocks.filter(Boolean)))
                };
            });
        });
    }
    static sameCodeBlock(a, b) {
        return (a.codeBlockId === b.codeBlockId &&
            a.validate === b.validate &&
            a.body === b.body &&
            a.language === b.language &&
            a.optional === b.optional &&
            a.status === b.status);
    }
    static sameCodeBlocks(AA, BB) {
        return AA && BB && AA.every((A, idx1) => A.every((a, idx2) => Wizard.sameCodeBlock(a, BB[idx1][idx2])));
    }
    componentDidMount() {
        this.init(this.props);
        Graph.blocks(this.state.graph, 'all').forEach(_ => {
            subscribeToLinkUpdates(_.id, this._statusUpdateHandler);
            this.cleaners.push(() => unsubscribeToLinkUpdates(_.id, this._statusUpdateHandler));
        });
    }
    componentWillUnmount() {
        this.cleaners.forEach(_ => _());
    }
    updateStatus(codeBlockId, status) {
        this.setState(curState => {
            if (curState.status[codeBlockId] === status) {
                // no change to state!
                return null;
            }
            else {
                curState.status[codeBlockId] = status;
                return {
                    status: Object.assign({}, curState.status)
                };
            }
        });
    }
    wizardCodeBlockSteps(stepIdx) {
        const containedCodeBlocks = this.state.codeBlocksPerStep[stepIdx];
        return containedCodeBlocks && containedCodeBlocks.length > 0 && React.createElement(MiniProgressStepper, { steps: containedCodeBlocks });
    }
    wizardStepDescription(stepIdx, description) {
        return (React.createElement("div", { className: "kui--wizard-nav-item-description" },
            this.wizardCodeBlockSteps(stepIdx),
            React.createElement("div", { className: "paragraph" }, description)));
    }
    static containedCodeBlocks(_) {
        if (typeof _.props.containedCodeBlocks === 'string' && _.props.containedCodeBlocks.length > 0) {
            return _.props.containedCodeBlocks
                .split(' ')
                .filter(Boolean)
                .map(_ => JSON.parse(Buffer.from(_, 'base64').toString()));
        }
        else {
            return undefined;
        }
    }
    /** Overall progress across all steps */
    progress() {
        if (this.props['data-kui-wizard-progress'] === 'bar' && Graph.blocks(this.state.graph).length > 0) {
            return (React.createElement("div", { className: "kui--markdown-major-paragraph" },
                React.createElement(Progress, { status: this.state.status, choices: this.props.choices, codeBlocks: this.state.graph, title: strings('Completed tasks') })));
        }
    }
    static children(props) {
        return (props.children || []).slice(1);
    }
    wizard() {
        const steps = Wizard.children(this.props).map((_, stepIdx) => ({
            name: _.props['data-kui-title'],
            hideCancelButton: true,
            stepNavItemProps: {
                children: this.wizardStepDescription(stepIdx, _.props['data-kui-description'])
            },
            component: React.createElement(Card, { className: "kui--markdown-tab-card" }, _.props && _.props.children)
        }));
        // onGoToStep={this._onWizardStepChange} onNext={this._onWizardStepChange} onBack={this._onWizardStepChange}
        const description = this.props.children[0];
        return (React.createElement(KWizard, { title: this.props['data-kui-title'], description: React.isValidElement(description) && description, descriptionFooter: this.progress(), steps: steps }));
    }
    render() {
        if (!this.state.graph) {
            return React.createElement(Loading, null);
        }
        else {
            return this.wizard();
        }
    }
}
/* private readonly _onWizardStepChange = (newStep: { name: React.ReactNode }) => {
    if (typeof newStep.name === 'string') {
      const activeKey = this.props.children.findIndex(_ => _.props.title === newStep.name)
      if (activeKey >= 0) {
        this.setState({ activeKey })
      }
    }
  } */
//# sourceMappingURL=index.js.map