<template>
    <template v-if="userStore.isLoggedIn">
        <div class="user">
            <div class="user__container">
                <div class="user__user-data">
                    <SwitchableImage
                        class="user__image"
                        :value="localUserData.image"
                        :edited="userDataEdited"
                        @change="changeLocalImageValue"
                    />
                    <InputComp
                        class="user__name"
                        v-model="localUserData.name"
                        placeholder="Имя"
                        :hasWarning="fieldHasErrors('Имя')"
                        :readOnly="!userDataEdited"
                    ></InputComp>
                    <InputComp
                        class="user__surname"
                        v-model="localUserData.surname"
                        placeholder="Фамилия"
                        :hasWarning="fieldHasErrors('Фамилия')"
                        :readOnly="!userDataEdited"
                    ></InputComp>

                    <InputComp class="user__email" v-model="userStore.userData.email" :placeholder="'Почта'" :readOnly="true"></InputComp>

                    <ButtonComp
                        class="user__button"
                        v-if="userDataEdited"
                        value="Сохранить изменения"
                        type="primary"
                        @click="tryChangeUserData()"
                    />
                </div>

                <div class="user__password" v-if="userDataEdited">
                    <template v-if="userPasswordEdited">
                        <InputComp
                            class="user__name"
                            v-model="localPasswords.oldPassword"
                            type="password"
                            :hasWarning="fieldHasErrors('Старый пароль')"
                            placeholder="Старый пароль"
                        ></InputComp>
                        <InputComp
                            class="user__surname"
                            v-model="localPasswords.newPassword"
                            type="password"
                            :hasWarning="fieldHasErrors('Новый пароль')"
                            placeholder="Новый пароль"
                        ></InputComp>
                        <InputComp
                            class="user__surname"
                            v-model="localPasswords.newPassword2"
                            type="password"
                            :hasWarning="fieldHasErrors('Новый пароль')"
                            placeholder="Повторите новый пароль"
                        ></InputComp>
                    </template>

                    <ButtonComp
                        class="user__button"
                        value="Сменить пароль"
                        :type="passwordButtonStyle"
                        @click="changePasswordButtonHandler()"
                    />
                </div>

                <div class="user__edit-toggle">
                    <FontAwesomeIcon class="fa-icon" icon="user-pen" v-if="!userDataEdited" @click="startEdit()" />
                    <FontAwesomeIcon class="fa-icon" icon="xmark" v-else @click="stopEdit()" />
                </div>

                <ButtonComp class="user__button" v-if="!userDataEdited" value="Выйти" type="primary" @click="tryLogout()" />
                <ThemeSwitcher class="user__theme-switcher" />

                <NotificationsMain class="user__notifications" v-model="notifications" />
                <ModalComp ref="refModal">Вы действительно хотите выйти?</ModalComp>
            </div>
        </div>
    </template>
    <template v-else>
        <AuthorizationNeeded />
    </template>
</template>

<script setup lang="ts">
import { computed, onDeactivated, ref, watch } from "vue";
import SwitchableImage from "@/components/Common/SwitchableImage.vue";
import AuthorizationNeeded from "@/components/HomeView/AuthorizationNeeded.vue";
import NotificationsMain from "@/components/Notifications/NotificationsMain.vue";
import { useUserStore } from "@/store";
import { useRouter } from "vue-router";
import { useUserApi } from "@/composables/api";
import { convertFileToBase64String } from "@/composables/utils";
import { FieldChecks, FieldsContainer } from "@/modules/validator";
import { notification } from "@/types";
import ModalComp from "@/components/UI/ModalComp.vue";
import ThemeSwitcher from "@/components/Common/ThemeSwitcher.vue";

const refModal = ref<InstanceType<typeof ModalComp> | undefined>();

const router = useRouter();
const userStore = useUserStore();
const userApi = useUserApi();

async function tryLogout() {
    const result = await refModal.value?.open({ type: "cancel_leave" });
    if (result === "leave") {
        logout();
    }
}

function logout() {
    router.push("/login");
    userStore.resetData();
}

const userDataEdited = ref(false);
const userPasswordEdited = ref(false);

const localUserData = ref<{ name: string; surname: string; image: string; imageFile?: File }>({
    ...userStore.userData,
    imageFile: undefined,
});
const localPasswords = ref({ oldPassword: "", newPassword: "", newPassword2: "" });

const passwordButtonStyle = computed(() =>
    !userPasswordEdited.value ||
    (localPasswords.value.oldPassword !== "" && localPasswords.value.newPassword !== "" && localPasswords.value.newPassword2 !== "")
        ? "primary"
        : "disabled"
);

function startEdit() {
    userDataEdited.value = true;
}
function stopEdit() {
    userDataEdited.value = false;
    userPasswordEdited.value = false;
    localUserData.value = { ...userStore.userData };
    localPasswords.value = { oldPassword: "", newPassword: "", newPassword2: "" };
}

const notifications = ref<notification[]>([]);

async function tryChangeUserData() {
    let errors = getUserDataFieldErrors();

    notifications.value = errors;

    if (errors.length > 0) return;

    const resp = await userApi.changeUserData(localUserData.value);
    userStore.setFieldValue("name", resp.name);
    userStore.setFieldValue("surname", resp.surname);
    userStore.setFieldValue("image", resp.image);

    notifications.value = [{ text: "Данные успешно изменены", type: "success" }];

    stopEdit();
}

async function changeLocalImageValue(file: File) {
    console.log(file);
    if (!file.type.includes("image")) {
        alert("Необходимо выбрать изображение");
        return;
    }

    localUserData.value.imageFile = file;
    localUserData.value.image = await convertFileToBase64String(file);
}

function getUserDataFieldErrors() {
    const container = new FieldsContainer();

    container.addField("Имя", localUserData.value.name, [
        FieldChecks.nonEmpty,
        FieldChecks.onlyLettersWhitespaces,
        FieldChecks.minLength(2),
        FieldChecks.maxLength(20),
    ]);
    container.addField("Фамилия", localUserData.value.surname, [
        FieldChecks.nonEmpty,
        FieldChecks.onlyLettersWhitespaces,
        FieldChecks.minLength(2),
        FieldChecks.maxLength(20),
    ]);

    let errors: notification[] = [];
    for (let [key, value] of container.fields) {
        const error = value.tryGetFirstError();
        if (error !== "") {
            errors.push({ field: key, text: error, type: "warning" });
        }
    }

    return errors;
}

function changePasswordButtonHandler() {
    if (!userPasswordEdited.value) {
        userPasswordEdited.value = true;
    } else {
        tryChangeUserPassword();
    }
}

async function tryChangeUserPassword() {
    let errors = getUserPasswordFieldErrors();

    notifications.value = errors;

    if (errors.length > 0) return;

    const resp = await userApi.changeUserPassword(localPasswords.value);

    notifications.value = [{ text: "Пароль успешно изменён", type: "success" }];

    stopEdit();
}

function getUserPasswordFieldErrors() {
    const container = new FieldsContainer();

    container.addField("Старый пароль", localPasswords.value.oldPassword, [FieldChecks.nonEmpty]);

    container.addField("Новый пароль", localPasswords.value.newPassword, [
        FieldChecks.nonEmpty,
        FieldChecks.minLength(6),
        FieldChecks.maxLength(32),
    ]);

    let errors: notification[] = [];
    for (let [key, value] of container.fields) {
        const error = value.tryGetFirstError();
        if (error !== "") {
            errors.push({ field: key, text: error, type: "warning" });
        }
    }

    if (localPasswords.value.newPassword !== localPasswords.value.newPassword2) {
        errors.push({ field: "Новый пароль", text: "Пароли не совпадают.", type: "warning" });
    }

    return errors;
}

function fieldHasErrors(field: string) {
    return notifications.value.some((x) => x.field === field);
}

watch(
    () => userStore.userData.name,
    (to) => (localUserData.value.name = to)
);
watch(
    () => userStore.userData.surname,
    (to) => (localUserData.value.surname = to)
);

onDeactivated(() => {
    stopEdit();
    notifications.value = [];
});
</script>

<style lang="scss">
.user {
    position: absolute;
    top: 0;
    width: 100%;
    min-height: 100%;
    padding: r(20);

    &__container {
        @include main-container;

        position: relative;
        display: flex;
        flex-direction: column;
        height: 100%;
        padding: r(20);
    }

    &__user-data {
        display: flex;
        flex-direction: column;
    }

    &__image {
        flex: 0 0 auto;
        margin: 0 auto r(15) auto;
    }

    &__email {
        //display: flex;
        //align-items: center;
    }

    &__password {
        display: flex;
        flex-direction: column;
        margin-top: r(25);
    }

    &__button {
        align-self: center;
        margin-top: r(15);
    }

    &__edit-toggle {
        position: absolute;
        top: r(20);
        right: r(20);
        width: r(30);
        height: r(30);
        color: color("ui-background");
        cursor: pointer;
    }

    &__theme-switcher {
        position: absolute;
        top: r(20);
        left: r(20);
        width: r(30);
        height: r(30);
        color: color("ui-background");
        cursor: pointer;
    }

    &__notifications {
        position: fixed;
        inset: auto 0 r(90) 0;
    }
}
</style>
