<template>
    <div class="box-header">
        <h5>
            {{ trans("product::products.group.variations") }}
        </h5>

        <div class="d-flex">
            <span
                class="toggle-accordion"
                :class="{
                    collapsed: isCollapsedVariationsAccordion,
                }"
                data-toggle="tooltip"
                data-placement="top"
                :data-original-title="
                    isCollapsedVariationsAccordion
                        ? trans('product::products.section.expand_all')
                        : trans('product::products.section.collapse_all')
                "
                @click="
                    toggleAccordions({
                        selector: '.variations-group .panel-heading',
                        state: isCollapsedVariationsAccordion,
                        data: form.variations,
                    })
                "
            >
                <i class="fa fa-angle-double-up" aria-hidden="true"></i>
            </span>

            <div class="drag-handle">
                <i class="fa fa-ellipsis-h" aria-hidden="true"></i>
                <i class="fa fa-ellipsis-h" aria-hidden="true"></i>
            </div>
        </div>
    </div>

    <div class="box-body">
        <div class="accordion-box-content">
            <draggable
                animation="150"
                class="variations-group"
                force-fallback="true"
                item-key="uid"
                handle=".drag-handle"
                @start="disableContentSelection"
                @end="enableContentSelection"
                @change="reorderVariations"
                :list="form.variations"
            >
                <template #item="{ element: variation, index }">
                    <div
                        :id="`variation-${variation.uid}`"
                        class="content-accordion panel-group options-group-wrapper"
                        :class="`variation-${variation.uid}`"
                    >
                        <div class="panel panel-default">
                            <div
                                class="panel-heading"
                                @click.stop="toggleAccordion($event, variation)"
                            >
                                <h4 class="panel-title">
                                    <div
                                        :aria-expanded="variation.is_open"
                                        data-toggle="collapse"
                                        data-transition="false"
                                        :class="{
                                            collapsed: !variation.is_open,
                                            'has-error': hasAnyError({
                                                name: 'variations',
                                                uid: variation.uid,
                                            }),
                                        }"
                                    >
                                        <div class="d-flex align-items-center">
                                            <span class="drag-handle">
                                                <i class="fa">&#xf142;</i>
                                                <i class="fa">&#xf142;</i>
                                            </span>

                                            <span
                                                v-text="
                                                    variation.name ||
                                                    trans(
                                                        'product::products.variations.new_variation'
                                                    )
                                                "
                                            ></span>
                                        </div>

                                        <span
                                            class="delete-option"
                                            @click.stop="
                                                deleteVariation(
                                                    index,
                                                    variation.uid
                                                )
                                            "
                                        >
                                            <i class="fa fa-trash"></i>
                                        </span>
                                    </div>
                                </h4>
                            </div>

                            <div
                                class="panel-collapse"
                                :class="{
                                    collapse: !variation.is_open,
                                }"
                            >
                                <div class="panel-body">
                                    <div class="new-option">
                                        <div class="row">
                                            <div class="col-sm-6">
                                                <div class="form-group row">
                                                    <label
                                                        :for="`variations-${variation.uid}-name`"
                                                    >
                                                        {{
                                                            trans(
                                                                "product::products.form.variations.name"
                                                            )
                                                        }}
                                                        <span
                                                            v-if="
                                                                variation.name ||
                                                                variation.type
                                                            "
                                                            class="text-red"
                                                            >*</span
                                                        >
                                                    </label>

                                                    <input
                                                        type="text"
                                                        :name="`variations.${variation.uid}.name`"
                                                        :id="`variations-${variation.uid}-name`"
                                                        class="form-control"
                                                        v-model="variation.name"
                                                    />

                                                    <span
                                                        class="help-block text-red"
                                                        v-if="
                                                            errors.has(
                                                                `variations.${variation.uid}.name`
                                                            )
                                                        "
                                                        v-text="
                                                            errors.get(
                                                                `variations.${variation.uid}.name`
                                                            )
                                                        "
                                                    >
                                                    </span>
                                                </div>
                                            </div>

                                            <div class="col-sm-3">
                                                <div class="form-group row">
                                                    <label
                                                        :for="`variations-${variation.uid}-type`"
                                                    >
                                                        {{
                                                            trans(
                                                                "product::products.form.variations.type"
                                                            )
                                                        }}
                                                        <span
                                                            v-if="
                                                                variation.name ||
                                                                variation.type
                                                            "
                                                            class="text-red"
                                                            >*</span
                                                        >
                                                    </label>

                                                    <select
                                                        :name="`variations.${variation.uid}.type`"
                                                        :id="`variations-${variation.uid}-type`"
                                                        class="form-control custom-select-black"
                                                        @change="
                                                            changeVariationType(
                                                                $event.target
                                                                    .value,
                                                                index,
                                                                variation.uid
                                                            )
                                                        "
                                                        v-model="variation.type"
                                                    >
                                                        <option value="">
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.variation_types.please_select"
                                                                )
                                                            }}
                                                        </option>
                                                        <option value="text">
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.variation_types.text"
                                                                )
                                                            }}
                                                        </option>
                                                        <option value="color">
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.variation_types.color"
                                                                )
                                                            }}
                                                        </option>
                                                        <option value="image">
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.variation_types.image"
                                                                )
                                                            }}
                                                        </option>
                                                    </select>

                                                    <span
                                                        class="help-block text-red"
                                                        v-if="
                                                            errors.has(
                                                                `variations.${variation.uid}.type`
                                                            )
                                                        "
                                                        v-text="
                                                            errors.get(
                                                                `variations.${variation.uid}.type`
                                                            )
                                                        "
                                                    >
                                                    </span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    <div
                                        class="variation-values"
                                        v-if="variation.type !== ''"
                                    >
                                        <div class="table-responsive">
                                            <table
                                                class="options table table-bordered table-striped"
                                                :class="
                                                    variation.type !== ''
                                                        ? `type-${variation.type}`
                                                        : ''
                                                "
                                            >
                                                <thead>
                                                    <tr>
                                                        <th></th>
                                                        <th>
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.label"
                                                                )
                                                            }}
                                                            <span
                                                                class="text-red"
                                                                >*</span
                                                            >
                                                        </th>
                                                        <th
                                                            v-if="
                                                                variation.type ===
                                                                'color'
                                                            "
                                                        >
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.color"
                                                                )
                                                            }}
                                                            <span
                                                                class="text-red"
                                                                >*</span
                                                            >
                                                        </th>
                                                        <th
                                                            v-else-if="
                                                                variation.type ===
                                                                'image'
                                                            "
                                                        >
                                                            {{
                                                                trans(
                                                                    "product::products.form.variations.image"
                                                                )
                                                            }}
                                                            <span
                                                                class="text-red"
                                                                >*</span
                                                            >
                                                        </th>
                                                        <th></th>
                                                    </tr>
                                                </thead>

                                                <tbody
                                                    is="vue:draggable"
                                                    animation="150"
                                                    handle=".drag-handle"
                                                    item-key="uid"
                                                    tag="tbody"
                                                    @change="
                                                        reorderVariationValues
                                                    "
                                                    :list="variation.values"
                                                >
                                                    <template
                                                        #item="{
                                                            element: value,
                                                            index: valueIndex,
                                                        }"
                                                    >
                                                        <tr class="option-row">
                                                            <td
                                                                class="text-center"
                                                            >
                                                                <span
                                                                    class="drag-handle"
                                                                >
                                                                    <i
                                                                        class="fa"
                                                                        >&#xf142;</i
                                                                    >
                                                                    <i
                                                                        class="fa"
                                                                        >&#xf142;</i
                                                                    >
                                                                </span>
                                                            </td>
                                                            <td>
                                                                <input
                                                                    type="text"
                                                                    :name="`variations.${variation.uid}.values.${value.uid}.label`"
                                                                    :id="`variations-${variation.uid}-values-${value.uid}-label`"
                                                                    class="form-control"
                                                                    @input="
                                                                        generateVariants
                                                                    "
                                                                    @keyup.enter="
                                                                        addVariationRowOnPressEnter(
                                                                            $event,
                                                                            index,
                                                                            valueIndex
                                                                        )
                                                                    "
                                                                    v-model="
                                                                        value.label
                                                                    "
                                                                />

                                                                <span
                                                                    class="help-block text-red"
                                                                    v-if="
                                                                        errors.has(
                                                                            `variations.${variation.uid}.values.${value.uid}.label`
                                                                        )
                                                                    "
                                                                    v-text="
                                                                        errors.get(
                                                                            `variations.${variation.uid}.values.${value.uid}.label`
                                                                        )
                                                                    "
                                                                >
                                                                </span>
                                                            </td>
                                                            <td
                                                                v-if="
                                                                    variation.type ===
                                                                    'color'
                                                                "
                                                            >
                                                                <div>
                                                                    <input
                                                                        type="text"
                                                                        :name="`variations.${variation.uid}.values.${value.uid}.color`"
                                                                        :id="`variations-${variation.uid}-values-${value.uid}-color`"
                                                                        class="form-control variation-color-picker"
                                                                        v-model="
                                                                            value.color
                                                                        "
                                                                    />
                                                                </div>

                                                                <span
                                                                    class="help-block text-red"
                                                                    v-if="
                                                                        errors.has(
                                                                            `variations.${variation.uid}.values.${value.uid}.color`
                                                                        )
                                                                    "
                                                                    v-text="
                                                                        errors.get(
                                                                            `variations.${variation.uid}.values.${value.uid}.color`
                                                                        )
                                                                    "
                                                                >
                                                                </span>
                                                            </td>
                                                            <td
                                                                v-else-if="
                                                                    variation.type ===
                                                                    'image'
                                                                "
                                                            >
                                                                <div
                                                                    class="d-flex"
                                                                >
                                                                    <div
                                                                        class="image-holder"
                                                                        @click="
                                                                            chooseVariationImage(
                                                                                index,
                                                                                variation.uid,
                                                                                valueIndex,
                                                                                value.uid
                                                                            )
                                                                        "
                                                                    >
                                                                        <template
                                                                            v-if="
                                                                                value
                                                                                    .image
                                                                                    .id
                                                                            "
                                                                        >
                                                                            <img
                                                                                :src="
                                                                                    value
                                                                                        .image
                                                                                        .path
                                                                                "
                                                                                alt="variation image"
                                                                            />
                                                                        </template>

                                                                        <img
                                                                            v-else
                                                                            src="@admin/images/placeholder_image.png"
                                                                            class="placeholder-image"
                                                                            alt="Placeholder Image"
                                                                        />
                                                                    </div>
                                                                </div>

                                                                <span
                                                                    class="help-block text-red"
                                                                    v-if="
                                                                        errors.has(
                                                                            `variations.${variation.uid}.values.${value.uid}.image`
                                                                        )
                                                                    "
                                                                    v-text="
                                                                        errors.get(
                                                                            `variations.${variation.uid}.values.${value.uid}.image`
                                                                        )
                                                                    "
                                                                >
                                                                </span>
                                                            </td>
                                                            <td
                                                                class="text-center"
                                                            >
                                                                <button
                                                                    type="button"
                                                                    tabindex="-1"
                                                                    class="btn btn-default delete-row"
                                                                    @click="
                                                                        deleteVariationRow(
                                                                            index,
                                                                            variation.uid,
                                                                            valueIndex,
                                                                            value.uid
                                                                        )
                                                                    "
                                                                >
                                                                    <i
                                                                        class="fa fa-trash"
                                                                    ></i>
                                                                </button>
                                                            </td>
                                                        </tr>
                                                    </template>
                                                </tbody>
                                            </table>
                                        </div>

                                        <button
                                            type="button"
                                            class="btn btn-default"
                                            @click="
                                                addVariationRow(
                                                    index,
                                                    variation.uid
                                                )
                                            "
                                        >
                                            {{
                                                trans(
                                                    "product::products.variations.add_row"
                                                )
                                            }}
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </template>
            </draggable>

            <div class="accordion-box-footer">
                <button
                    type="button"
                    class="btn btn-default"
                    @click="addVariation"
                >
                    {{ trans("product::products.variations.add_variation") }}
                </button>

                <div
                    v-if="hasAccess('admin.variations.index')"
                    class="insert-template"
                >
                    <select
                        class="form-control custom-select-black"
                        v-model="globalVariationId"
                    >
                        <option value="">
                            {{
                                trans(
                                    "product::products.form.variations.select_template"
                                )
                            }}
                        </option>

                        <option
                            v-for="globalVariation in globalVariations"
                            :key="globalVariation.id"
                            :value="globalVariation.id"
                        >
                            {{ globalVariation.name }}
                        </option>
                    </select>

                    <button
                        type="button"
                        class="btn btn-default"
                        :class="{
                            'btn-loading': addingGlobalVariation,
                        }"
                        :disabled="isAddGlobalVariationDisabled"
                        @click="addGlobalVariation"
                    >
                        {{ trans("product::products.variations.insert") }}
                    </button>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, nextTick } from "vue";
import { useForm } from "../composables/useForm";
import { useVariations } from "../composables/useVariations";
import { useVariants } from "../composables/useVariants";
import { useProductMethods } from "../composables/useProductMethods";
import { useDraggableSections } from "../composables/useDraggableSections";
import { generateUid } from "@admin/js/functions";
import { toaster } from "@admin/js/Toaster";
import draggable from "vuedraggable";

const globalVariationId = ref("");
const addingGlobalVariation = ref(false);
const globalVariations = ref(FleetCart.data["global-variations"] ?? []);

const {
    form,
    errors,
    focusField,
    hasAnyError,
    clearErrors,
    clearValuesError,
    clearValueRowErrors,
} = useForm();
const { initVariationsColorPicker } = useVariations();
const { generateVariants, notifyVariantsReordered } = useVariants();
const { toggleAccordions, toggleAccordion } = useProductMethods();
const { enableContentSelection, disableContentSelection } =
    useDraggableSections();

const isAddGlobalVariationDisabled = computed(
    () => globalVariationId.value === "" || addingGlobalVariation.value
);

const isCollapsedVariationsAccordion = computed(() =>
    form.variations.every(({ is_open }) => is_open === false)
);

function reorderVariations() {
    generateVariants();
    notifyVariantsReordered();
}

function reorderVariationValues() {
    generateVariants(true);
}

function addVariation({ preventFocus }) {
    const uid = generateUid();

    form.variations.push({
        uid,
        type: "",
        is_global: false,
        is_open: true,
        values: [
            {
                uid: generateUid(),
                image: {
                    id: null,
                    path: null,
                },
            },
        ],
    });

    if (!preventFocus) {
        focusField({
            selector: `#variations-${uid}-name`,
        });
    }
}

function deleteVariation(index, uid) {
    form.variations.splice(index, 1);

    clearErrors({ name: "variations", uid });
    generateVariants();
}

function changeVariationType(value, index, uid) {
    const variation = form.variations[index];

    if (value !== "" && variation.values.length === 1) {
        focusField({
            selector: `#variations-${uid}-values-${variation.values[0].uid}-label`,
        });
    }

    if (value === "text") {
        variation.values.forEach((value) => {
            errors.clear([
                `variations.${uid}.values.${value.uid}.color`,
                `variations.${uid}.values.${value.uid}.image`,
            ]);
        });
    } else if (value === "color") {
        variation.values.forEach((value) => {
            errors.clear(`variations.${uid}.values.${value.uid}.image`);
        });

        nextTick(() => {
            initVariationsColorPicker();
        });
    } else if (value === "image") {
        variation.values.forEach((value, valueIndex) => {
            if (!value.image) {
                variation.values[valueIndex].image = {
                    id: null,
                    path: null,
                };
            }
        });

        variation.values.forEach((value) => {
            errors.clear(`variations.${uid}.values.${value.uid}.color`);
        });
    } else {
        clearValuesError(index, uid);
    }
}

function chooseVariationImage(
    variationIndex,
    variationUid,
    valueIndex,
    valueUid
) {
    let picker = new MediaPicker({ type: "image" });

    picker.on("select", ({ id, path }) => {
        form.variations[variationIndex].values[valueIndex].image = {
            id: +id,
            path,
        };

        errors.clear(`variations.${variationUid}.values.${valueUid}.image`);
    });
}

async function addVariationRow(index, variationUid) {
    const valueUid = generateUid();

    form.variations[index].values.push({
        uid: valueUid,
        image: {
            id: null,
            path: null,
        },
    });

    await nextTick(() => {
        initVariationsColorPicker();

        $(`#variations-${variationUid}-values-${valueUid}-label`).trigger(
            "focus"
        );
    });
}

function addVariationRowOnPressEnter(event, variationIndex, valueIndex) {
    const variation = form.variations[variationIndex];
    const values = variation.values;

    if (event.target.value === "") return;

    if (values.length - 1 === valueIndex) {
        addVariationRow(variationIndex, variation.uid);

        return;
    }

    if (valueIndex < values.length - 1) {
        $(
            `#variations-${variation.uid}-values-${
                values[valueIndex + 1].uid
            }-label`
        ).trigger("focus");
    }
}

function deleteVariationRow(
    variationIndex,
    variationUid,
    valueIndex,
    valueUid
) {
    const variation = form.variations[variationIndex];

    variation.values.splice(valueIndex, 1);

    clearValueRowErrors({
        name: "variations",
        uid: variationUid,
        valueUid,
    });

    if (variation.values.length === 0) {
        addVariationRow(variationIndex, variationUid);
    }

    generateVariants();
}

function hideColorPicker() {
    $(document).on("click", "#clr-swatches button", (e) => {
        $(e.currentTarget).parents("#clr-picker").removeClass("clr-open");
    });
}

function addGlobalVariation() {
    if (globalVariationId.value === "") return;

    addingGlobalVariation.value = true;

    axios
        .get(`/variations/${globalVariationId.value}`)
        .then(({ data }) => {
            data.uid = generateUid();
            data.is_open = true;

            data.values.forEach((value) => {
                value.uid = generateUid();

                if (!value.image) {
                    value.image = {
                        id: null,
                        path: null,
                    };
                }
            });

            form.variations.push(data);

            generateVariants();

            nextTick(() => {
                $(`#variations-${data.uid}-name`).trigger("focus");
            });
        })
        .catch((error) => {
            toaster(error.response.data.message, {
                type: "error",
            });
        })
        .finally(() => {
            globalVariationId.value = "";
            addingGlobalVariation.value = false;
        });
}

watch(
    () => form.variations,
    (newValue) => {
        if (newValue.length === 0) {
            addVariation({ preventFocus: true });
        }
    },
    { deep: true, immediate: true }
);

onMounted(() => {
    initVariationsColorPicker();
    hideColorPicker();
});
</script>
