import { faSave as farSave } from "@fortawesome/free-regular-svg-icons";
import {
    faDownload,
    faEdit,
    faHistory,
    faMagic,
    faPencilAlt,
    faPlay,
    faPlus,
    faRecycle,
    faSave,
    faSignOutAlt,
    faSitemap,
    faWrench,
} from "@fortawesome/free-solid-svg-icons";
import { watchImmediate } from "@vueuse/core";
import { faDiagramNext, faSearch } from "font-awesome-6";
import { computed, type ComputedRef, type Ref } from "vue";

import { useActivityStore } from "@/stores/activityStore";
import type { Activity } from "@/stores/activityStoreTypes";

import type { LintData } from "./useLinting";

export function useWorkflowActivities(
    /** The ID of the activity bar these activities belong to (set to "workflow-editor" for now) */
    activityBarId: string,
    /** Whether the workflow being edited is a new workflow that has not been created/saved yet */
    isNewTempWorkflow: Ref<boolean>,
    /** Whether the workflow has unsaved changes */
    hasChanges: Ref<boolean>,
    /** How many changes before we get back to the last saved state */
    undoStackLength: Ref<number>,
    /** Whether the user can use custom tools */
    canUseUnprivilegedTools: Ref<boolean>,
): ComputedRef<Activity[]> {
    const store = useActivityStore(activityBarId);

    // Disable running the workflow if it is new and has not been created
    watchImmediate(
        () => isNewTempWorkflow.value,
        (value) => {
            store.setMeta("workflow-run", "disabled", value);
        },
    );

    // Disable saving the workflow if there are no changes to save
    watchImmediate(
        () => hasChanges.value,
        (value) => {
            store.setMeta("save-workflow", "disabled", !value);
        },
    );

    // Return a computed list of workflow editor activities
    return computed(() => [
        {
            title: "Attributes",
            id: "workflow-editor-attributes",
            tooltip: "Edit workflow attributes",
            description: "View and edit the attributes of this workflow.",
            panel: true,
            icon: faPencilAlt,
            visible: true,
        },
        {
            title: "Search",
            id: "workflow-editor-search",
            tooltip: "Search the contents of this workflow",
            description: "Search the contents of this workflow.",
            panel: true,
            icon: faSearch,
            visible: true,
        },
        {
            title: "Inputs",
            id: "workflow-editor-inputs",
            tooltip: "Add input steps to your workflow",
            description: "Add input steps to your workflow.",
            icon: faDiagramNext,
            panel: true,
            visible: true,
        },
        {
            title: "Tools",
            id: "workflow-editor-tools",
            description: "Displays the tool panel to search and place all available tools.",
            icon: faWrench,
            panel: true,
            tooltip: "Search tools to use in your workflow",
            visible: true,
        },
        {
            title: "Workflows",
            id: "workflow-editor-workflows",
            description: "Browse other workflows and add them as sub-workflows.",
            tooltip: "Search workflows to use in your workflow",
            icon: faSitemap,
            panel: true,
            visible: true,
            optional: true,
        },
        {
            title: "Report",
            id: "workflow-editor-report",
            description: "Edit the report for this workflow.",
            tooltip: "Edit workflow report",
            icon: faEdit,
            panel: true,
            visible: true,
            optional: true,
        },

        {
            title: "Changes",
            id: "workflow-undo-redo",
            description: "View, undo, and redo your latest changes.",
            tooltip: "Show and manage latest changes",
            icon: faHistory,
            panel: true,
            visible: true,
            optional: true,
            indicator: undoStackLength.value,
            indicatorVariant: "primary",
        },
        {
            title: "Run",
            id: "workflow-run",
            description: "Run this workflow with specific parameters.",
            tooltip: "Run workflow",
            icon: faPlay,
            visible: true,
            click: true,
            optional: true,
        },
        {
            description: "Save this workflow.",
            icon: faSave,
            id: "save-workflow",
            title: "Save",
            tooltip: hasChanges.value ? "Save current changes" : "No changes to save",
            visible: true,
            click: true,
            optional: true,
        },
        {
            description: "Save this workflow with a different name and annotation.",
            icon: farSave,
            id: "save-workflow-as",
            title: "Save as",
            tooltip: "Save a copy of this workflow",
            visible: true,
            click: true,
            optional: true,
        },
        {
            title: "Upgrade",
            id: "workflow-upgrade",
            description: "Update all tools used in this workflow.",
            tooltip: "Update all tools",
            icon: faRecycle,
            visible: true,
            click: true,
            optional: true,
        },
        ...(canUseUnprivilegedTools.value
            ? [
                  {
                      description: "Insert custom tools.",
                      icon: faWrench,
                      id: "workflow-editor-user-defined-tools",
                      optional: true,
                      panel: true,
                      title: "Custom Tools",
                      to: null,
                      tooltip: "List and create user-defined tools",
                      visible: true,
                  },
              ]
            : []),
        {
            title: "Download",
            id: "workflow-download",
            description: "Download this workflow in '.ga' format.",
            tooltip: "Download workflow",
            icon: faDownload,
            visible: true,
            click: true,
            optional: true,
        },
        {
            description: "Save this workflow and create a new workflow.",
            icon: faPlus,
            title: "Create new",
            id: "workflow-create",
            tooltip: "Save this workflow and create a new one",
            visible: true,
            click: true,
            optional: true,
        },
        {
            description: "Exit the workflow editor and return to the start screen.",
            icon: faSignOutAlt,
            id: "exit",
            title: "Exit",
            tooltip: "Exit workflow editor",
            visible: false,
            click: true,
            optional: true,
        },
    ]);
}

interface SpecialActivityOptions {
    hasInvalidConnections: boolean;
    lintData: LintData;
}

export function useSpecialWorkflowActivities(options: Ref<SpecialActivityOptions>) {
    const saveHover = computed(() => {
        if (options.value.hasInvalidConnections) {
            return "Workflow has invalid connections, review and remove invalid connections";
        } else {
            return "Save this workflow, then exit the workflow editor";
        }
    });

    /** Indicator for best practices activity
     * @returns
     * - `number`: count of critical issues remaining
     * - `true`: non-critical issues remaining (renders exclamation icon)
     * - `undefined`: no issues remaining
     */
    const bestPracticesIndicator = computed<number | true | undefined>(() => {
        const { resolvedPriorityIssues, totalPriorityIssues, resolvedAttributeIssues, totalAttributeIssues } =
            options.value.lintData;
        if (totalPriorityIssues.value > resolvedPriorityIssues.value) {
            return totalPriorityIssues.value - resolvedPriorityIssues.value;
        } else if (totalAttributeIssues.value > resolvedAttributeIssues.value) {
            return true;
        }
        return undefined;
    });

    /** Helper function to create issue description with proper pluralization */
    function getIssueDescription(count: number, type: "critical" | "minor"): string {
        const issueWord = count === 1 ? "issue" : "issues";
        const remainWord = count === 1 ? "remains" : "remain";
        return `${count} ${type} best practice ${issueWord} ${remainWord}`;
    }

    /** Tooltip for best practices activity */
    const bestPracticeHover = computed(() => {
        const { resolvedPriorityIssues, totalPriorityIssues, resolvedAttributeIssues, totalAttributeIssues } =
            options.value.lintData;

        const criticalCount = totalPriorityIssues.value - resolvedPriorityIssues.value;
        const nonCriticalCount = totalAttributeIssues.value - resolvedAttributeIssues.value;

        if (criticalCount > 0) {
            return getIssueDescription(criticalCount, "critical");
        } else if (nonCriticalCount > 0) {
            return getIssueDescription(nonCriticalCount, "minor");
        } else {
            return "Test workflow for best practices";
        }
    });

    const specialWorkflowActivities = computed<Activity[]>(() => [
        {
            title: "Best Practices",
            id: "workflow-best-practices",
            description: "Show and test for the best practices in this workflow.",
            tooltip: bestPracticeHover.value,
            indicator: bestPracticesIndicator.value,
            indicatorVariant: typeof bestPracticesIndicator.value === "number" ? "danger" : "primary",
            icon: faMagic,
            panel: true,
            visible: true,
            optional: true,
        },
    ]);

    const exitWorkflowActivity = computed<Activity>(() => ({
        description: "",
        icon: faSave,
        id: "save-and-exit",
        title: "Save + Exit",
        tooltip: saveHover.value,
        visible: false,
        click: true,
        mutable: false,
    }));

    return {
        specialWorkflowActivities,
        exitWorkflowActivity,
    };
}
