<script>
    import {afterUpdate, getContext, onMount} from "svelte";
    import {isEqual} from "lodash";
    import Manager from "./Manager.svelte";
    import EditHeader from "./EditHeader.svelte"
    import StatusSelect from "./StatusSelect.svelte"
    import FilePreview from "./FilePreview.svelte"
    import ContentTabs from "./ContentTabs.svelte"
    import FormField from "./FormField.svelte"
    import Graph from "./Graph.svelte"
    import Info from "./Info.svelte"
    import ErrorAlert from "../common/ErrorAlert.svelte"

    const channel = getContext("channel");

    export let schema;
    export let record;
    export let graph = {
        records: [],
        edges: []
    };
    export let recordHistory;
    export let isCreateMode;
    export let isWritable = false;
    export let users;
    let originalContent;
    let activeContentTab = "";
    $: hasUnsavedData = false;
    $: validationErrors = null;
    $: errorMessage = validationErrors
        ? `Record submission failed. ${
            Object.entries(validationErrors).length
        } error(s)`
        : null;

    let activeFields = schema.fields.filter(
        (f) => f.name !== "id"
    );


    onMount(() => {
        setOriginalContent();
    });

    function setOriginalContent() {
        originalContent = {
            data: JSON.parse(JSON.stringify(record.data)),
            schema: record.schema,
            status: record.status,
            _sys: JSON.parse(JSON.stringify(record._sys)),
            _file: JSON.parse(JSON.stringify(record._file)),
            edges: JSON.parse(JSON.stringify(graph.edges)),
        };
    }

    afterUpdate(() => {
        hasUnsavedData = checkUnsavedData();
    });

    function beforeUnload(e) {
        // Cancel the event as stated by the standard.
        // e.preventDefault();
        // console.log(hasUnsavedData);
        if (hasUnsavedData) {
            return (e.returnValue =
                "You have unsaved changes. Are you sure you want to exit?");
        }
        // Chrome requires returnValue to be set.
        // e.returnValue = "";
        delete e["returnValue"];
        // more compatibility
        // return true;
        return "...";
    }

    function checkUnsavedData() {
        if (isCreateMode) {
            return false;
        }
        return !isEqual(originalContent, {
            data: record.data,
            schema: record.schema,
            status: record.status,
            _sys: record._sys,
            _file: record._file,
            edges: graph.edges,
        });
    }

    function save(e) {
        e.preventDefault();

        console.log("SAVE: Attempt");
        validationErrors = null;
        errorMessage = "";
        return new Promise(function (resolve, reject) {
            if (!hasUnsavedData && !isCreateMode) {
                resolve(null);
                return;
            }
            if (!record) {
                resolve(null);
                return;
            }

            // remove trashed edges
            graph.edges = graph.edges?.filter((edge) => !edge._isTrashed && edge.source === record.id);
            axios
                .post(channel.lucentUrl + "/records", {
                    record: record,
                    edges: graph.edges,
                    isCreateMode: isCreateMode,
                })
                .then(function (response) {
                    console.log("SAVE: SAVED");

                    if (isCreateMode) {
                        window.location = channel.lucentUrl + "/records/" + record.id;
                    } else {
                        record = response.data.records[0] ?? null;
                        if (!record) {
                            // means trashed
                            hasUnsavedData = false;
                            window.location = channel.lucentUrl;
                            return;
                        }
                        graph = response.data;
                        setOriginalContent();
                    }

                    resolve(null);
                })
                .catch(function (error) {
                    // setOriginalContent();
                    if (error.response) {
                        if (typeof error.response.data.error === "string") {
                            errorMessage = error.response.data.error;
                        } else {
                            validationErrors = error.response.data.error;
                            console.log(validationErrors)
                        }
                    }
                    resolve(null);
                    // msgSuccess = null;
                    // msgError = error.response.data.error;
                    // submitted = false;
                });
        });
    }
</script>

<svelte:window on:beforeunload={beforeUnload}/>

<div class="wrapper-normal transparent">
    <Manager managerRecords={recordHistory} {graph}/>
    <EditHeader {schema} {record} {isCreateMode} {graph} bind:activeContentTab/>

    {#if !["_graph", "_info"].includes(activeContentTab) && isWritable}
        <div class="shadow-lg "
             style="position:fixed;bottom:0;left:0px;width:100%;background: rgb(206, 223, 210);z-index:1050"
        >
            <div
                    class="d-flex mt-3 mb-3  align-items-center justify-content-center"
            >
                <StatusSelect bind:status={record.status} {record} {schema}/>
                {#if isCreateMode}
                    <button
                            class="ms-2 btn btn-primary btn-spinner"
                            on:click={save}
                    >
                            <span
                                    class="spinner-border spinner-border-sm"
                                    role="status"
                                    aria-hidden="true"
                            />
                        Create
                    </button>
                {:else if hasUnsavedData}
                    <button
                            type="button"
                            class="ms-2 btn btn-primary btn-spinner"
                            on:click={save}
                    >
                            <span
                                    class="spinner-border spinner-border-sm"
                                    role="status"
                                    aria-hidden="true"
                            />
                        Save
                    </button>
                {/if}
            </div>
        </div>
    {/if}

    <ErrorAlert message={errorMessage}/>

    <div class=" mt-4" style="margin-bottom:150px">
        <ContentTabs
                {schema}
                {isCreateMode}
                bind:active={activeContentTab}
        />
        {#if !["_graph", "_info"].includes(activeContentTab)}
            <FilePreview {record} {schema}/>
            <!-- <fieldset disabled="disabled"> -->
            {#each activeFields as field (field.name)}
                {#if activeContentTab === field.group}
                    <FormField
                            bind:data={record.data}
                            bind:graph={graph}
                            {field}
                            {schema}
                            {record}
                            {validationErrors}
                            {isCreateMode}
                    />
                {/if}
            {/each}
            <!-- </fieldset> -->
        {:else if activeContentTab === "_graph"}
            <Graph {graph} {record}/>
        {:else if activeContentTab === "_info"}
            <Info {record} {graph} {users} {schema}/>
        {/if}
    </div>
</div>
