<template>
    <ActivityPanel id="edit-attributes" title="Attributes" itemscope itemtype="http://schema.org/CreativeWork">
        <b-alert :variant="messageVariant" :show="!!message">
            {{ message }}
        </b-alert>
        <div id="workflow-name-area">
            <b>Name</b>
            <meta itemprop="name" :content="name" />
            <b-input
                id="workflow-name"
                v-model="nameCurrent"
                :state="!nameCurrent ? false : null"
                @keyup="$emit('update:nameCurrent', nameCurrent)" />
        </div>
        <div v-if="versions.length > 0" id="workflow-version-area" class="mt-2">
            <b>Version</b>
            <GLink
                v-if="canSwitchToLatestVersion"
                thin
                title="You are not editing the latest version of this workflow. Click to switch to the latest version."
                @click.prevent="onVersion(versions[versions.length - 1].version)">
                <i>(switch to latest)</i>
            </GLink>
            <i v-else> (latest version)</i>
            <WorkflowVersionSelector
                v-if="version !== null && version !== undefined"
                :version="version"
                :versions="versions"
                @onVersion="onVersion" />
        </div>
        <div v-if="hasParameters" id="workflow-parameters-area" class="mt-2">
            <b>Parameters</b>
            <b-list-group>
                <b-list-group-item v-for="[key, p] in parameters.parameters.entries()" :key="key"
                    >{{ key + 1 }}: {{ p.name }}
                </b-list-group-item>
            </b-list-group>
        </div>
        <div id="workflow-annotation-area" class="mt-2" :class="{ 'highlight-attribute': highlight === 'annotation' }">
            <b>Short Description</b>
            <meta itemprop="description" :content="annotationCurrent" />
            <b-textarea
                id="workflow-annotation"
                v-model="annotationCurrent"
                @keyup="$emit('update:annotationCurrent', annotationCurrent)" />
            <div class="form-text text-muted">
                This short description will be visible when this workflow is viewed and should be limited to a sentence
                or two.
            </div>
            <b-popover
                custom-class="best-practice-popover"
                target="workflow-annotation"
                boundary="window"
                placement="right"
                :show="highlight === 'annotation'"
                triggers="manual"
                title="Best Practice"
                :content="annotationBestPracticeMessage">
            </b-popover>
        </div>
        <div id="workflow-license-area" class="mt-2" :class="{ 'highlight-attribute': highlight === 'license' }">
            <b>License</b>
            <LicenseSelector id="license-selector" :input-license="license" @onLicense="onLicense" />
            <b-popover
                custom-class="best-practice-popover"
                target="license-selector"
                boundary="window"
                placement="right"
                :show="highlight === 'license'"
                triggers="manual"
                title="Best Practice"
                :content="bestPracticeWarningLicense">
            </b-popover>
        </div>
        <div id="workflow-creator-area" class="mt-2" :class="{ 'highlight-attribute': highlight === 'creator' }">
            <b>Creator</b>
            <CreatorEditor id="creator-editor" :creators="creatorAsList" @onCreators="onCreator" />
            <b-popover
                custom-class="best-practice-popover"
                target="creator-editor"
                boundary="window"
                placement="right"
                :show="highlight === 'creator'"
                triggers="manual"
                title="Best Practice"
                :content="bestPracticeWarningCreator">
            </b-popover>
        </div>

        <div id="workflow-doi-area" class="mt-2">
            <b>Digital Object Identifier (DOI)</b>
            <ItemListEditor
                :items="doi"
                item-name="DOI"
                :description="doiDescription"
                :item-format="doiRegex"
                @onItems="onDoi" />
        </div>

        <div class="mt-2">
            <b>Tags</b>
            <StatelessTags :value="tags" @input="onTags" />
            <div class="form-text text-muted">
                Apply tags to make it easy to search for and find items with the same tag.
            </div>
        </div>
        <div class="mt-2">
            <div>
                <b>Readme</b>
            </div>
            <b-button
                id="workflow-readme"
                class="w-100"
                size="sm"
                :pressed="readmeActive"
                @click="$emit('update:readme-active', !readmeActive)">
                {{ readmeActive ? "Hide" : "Show" }} Readme
            </b-button>
            <div class="form-text text-muted">
                A detailed description of what the workflow does. It is best to include descriptions of what kinds of
                data are required. Researchers looking for the workflow will see this text. Markdown is enabled.
            </div>
            <b-popover
                custom-class="best-practice-popover"
                target="workflow-readme"
                boundary="window"
                placement="right"
                :show="highlight === 'readme'"
                triggers="manual"
                title="Best Practice"
                :content="bestPracticeWarningReadme">
            </b-popover>
        </div>
        <div class="mt-2">
            <b>Help</b>
            <b-textarea id="workflow-help" v-model="helpCurrent" @keyup="$emit('update:helpCurrent', helpCurrent)" />
            <div class="form-text text-muted">
                A detailed description of how to use the workflow and debug problems with it. Researchers running this
                workflow will see this text. Markdown is enabled.
            </div>
        </div>
        <div class="mt-2">
            <b>Logo URL</b>
            <b-input
                id="workflow-logo-url"
                v-model="logoUrlCurrent"
                @keyup="$emit('update:logoUrlCurrent', logoUrlCurrent)" />
            <div class="form-text text-muted">
                An logo image used when generating publication artifacts for your workflow. This is completely optional.
            </div>
        </div>
    </ActivityPanel>
</template>

<script>
import { Services } from "@/components/Workflow/services";

import {
    bestPracticeWarningAnnotation,
    bestPracticeWarningAnnotationLength,
    bestPracticeWarningCreator,
    bestPracticeWarningLicense,
    bestPracticeWarningReadme,
} from "./modules/linting";
import { UntypedParameters } from "./modules/parameters";

import WorkflowVersionSelector from "../WorkflowVersionSelector.vue";
import GLink from "@/components/BaseComponents/GLink.vue";
import ItemListEditor from "@/components/Common/ItemListEditor.vue";
import LicenseSelector from "@/components/License/LicenseSelector.vue";
import ActivityPanel from "@/components/Panels/ActivityPanel.vue";
import CreatorEditor from "@/components/SchemaOrg/CreatorEditor.vue";
import StatelessTags from "@/components/TagsMultiselect/StatelessTags.vue";

const BEST_PRACTICE_HIGHLIGHT_TIME = 4000;

export default {
    name: "WorkflowAttributes",
    components: {
        StatelessTags,
        LicenseSelector,
        CreatorEditor,
        ItemListEditor,
        ActivityPanel,
        GLink,
        WorkflowVersionSelector,
    },
    props: {
        id: {
            type: String,
            required: true,
        },
        name: {
            type: String,
            default: null,
        },
        highlight: {
            type: String,
            default: null,
        },
        tags: {
            type: Array,
            required: true,
        },
        annotation: {
            type: String,
            default: null,
        },
        license: {
            type: String,
            default: "",
        },
        creator: {
            type: Array,
            default: null,
        },
        doi: {
            type: Array,
            default: null,
        },
        logoUrl: {
            type: String,
            default: null,
        },
        readmeActive: {
            type: Boolean,
            default: false,
        },
        help: {
            type: String,
            default: null,
        },
        version: {
            type: Number,
            default: null,
        },
        versions: {
            type: Array,
            default: null,
        },
        parameters: {
            type: UntypedParameters,
            default: null,
        },
    },
    data() {
        return {
            bestPracticeWarningCreator: bestPracticeWarningCreator,
            bestPracticeWarningLicense: bestPracticeWarningLicense,
            bestPracticeWarningReadme: bestPracticeWarningReadme,
            message: null,
            messageVariant: null,
            annotationCurrent: this.annotation,
            nameCurrent: this.name,
            logoUrlCurrent: this.logoUrl,
            helpCurrent: this.help,
            doiDescription: `
Acceptable format:
<ul>
    <li>https://doi.org/DOI-VALUE</li>
    <li>doi.org/DOI-VALUE</li>
    <li>doi:DOI-VALUE</li>
</ul>`,
            doiRegex: "^(https://doi.org/|doi.org/|doi:)10\\.\\d+/\\S+$",
        };
    },
    computed: {
        /** Determines if the current version is not the latest */
        canSwitchToLatestVersion() {
            return (
                this.versions?.length > 1 &&
                this.version !== null &&
                this.version !== this.versions[this.versions.length - 1].version
            );
        },
        creatorAsList() {
            let creator = this.creator;
            if (!creator) {
                creator = [];
            } else if (!(creator instanceof Array)) {
                creator = [creator];
            }
            return creator;
        },
        hasParameters() {
            return this.parameters && this.parameters.parameters.length > 0;
        },
        annotationBestPracticeMessage() {
            if (this.annotationCurrent) {
                return bestPracticeWarningAnnotationLength;
            } else {
                return bestPracticeWarningAnnotation;
            }
        },
    },
    watch: {
        license() {
            this.licenseCurrent = this.license;

            // Remove highlight if it exists for license
            if (this.highlight === "license") {
                this.$emit("update:highlight", null);
            }
        },
        creator() {
            let creator = this.creator;
            if (!creator) {
                creator = [];
            } else if (!(creator instanceof Array)) {
                creator = [creator];
            }
            this.creatorCurrent = creator;

            // Remove highlight if it exists for creator
            if (this.highlight === "creator") {
                this.$emit("update:highlight", null);
            }
        },
        annotation() {
            this.annotationCurrent = this.annotation;

            // Remove highlight if it exists for annotation
            if (this.highlight === "annotation") {
                this.$emit("update:highlight", null);
            }
        },
        name() {
            this.nameCurrent = this.name;
        },
        help() {
            this.helpCurrent = this.help;
        },
        logoUrl() {
            this.logoUrlCurrent = this.logoUrl;
        },
        highlight: {
            immediate: true,
            handler(newHighlight, oldHighlight) {
                if (newHighlight === oldHighlight) {
                    this.$emit("update:highlight", null);
                } else {
                    setTimeout(() => {
                        this.$emit("update:highlight", null);
                    }, BEST_PRACTICE_HIGHLIGHT_TIME);
                }
            },
        },
    },
    created() {
        this.services = new Services();
    },
    methods: {
        onTags(tags) {
            this.onAttributes({ tags });
            this.$emit("tags", tags);
        },
        onVersion(version) {
            this.$emit("version", version);
        },
        onLicense(license) {
            this.$emit("license", license);
        },
        onCreator(creator) {
            this.$emit("creator", creator);
        },
        onDoi(doiItems) {
            this.$emit("doi", doiItems);
        },
        onError(error) {
            this.message = error;
            this.messageVariant = "danger";
        },
        onAttributes(data) {
            if (!this.id.includes("workflow-editor")) {
                this.services.updateWorkflow(this.id, data).catch((error) => {
                    this.onError(error);
                });
            }
        },
    },
};
</script>

<style scoped lang="scss">
@import "@/style/scss/theme/blue.scss";

.highlight-attribute {
    border-radius: 10px;
    padding-top: 5px;
    padding-bottom: 5px;
    border: 4px solid $brand-primary;
    animation: blink-border 1s infinite;
}

@keyframes blink-border {
    0%,
    50% {
        border-color: $brand-primary;
    }
    51%,
    100% {
        border-color: transparent;
    }
}
</style>

<style>
.best-practice-popover {
    max-width: 250px !important;
}
</style>
