<template>
    <v-row no-gutters>
        <v-form v-model="valid">
            <v-row>
                <v-col cols="6">
                    <InputLabel class="text-capitalize font-weight-bold" :title="title" :required="required" />
                    <v-text-field v-model.number="count" type="number" density="comfortable" :rules="rules" :readonly="readOnly" />
                </v-col>

                <v-col cols="6">
                    <v-btn v-if="!readOnly" color="primary" class="text-none mt-6" size="large" variant="flat"
                        :disabled="!valid || disabled" :loading="loading || updating" text="Save" @click="handleSave" />
                </v-col>
            </v-row>
        </v-form>
        <Snackbar v-model="toastObject.show" :text="toastObject.message" :color="toastObject.color" />
        <v-dialog v-model="dialog.updateBlockPrompt" persistent max-width="450">
            <DialogReusablePrompt :promptTitle="`Reduce number of ${props.type === 'blocks' ? 'blocks' : 'guard posts'}?`" confirm-button-color="red"
                :message="`Lowering the ${props.type === 'blocks' ? 'block' : 'guard post'} count will remove option beyond the new limit. Are you sure you want to proceed?`"
                @close="dialog.updateBlockPrompt = false" @proceed="handleProceedSave" />
        </v-dialog>
    </v-row>
</template>

<script setup lang="ts">
import useSiteSettings from '../composables/useSiteSettings';

const props = defineProps({
    title: { type: String, required: true },
    required: { type: Boolean, default: true },
    loading: { type: Boolean, default: false },
    type: { type: String as PropType<'blocks' | 'guard_posts'>, required: true },
    disabled: { type: Boolean, default: false },
    siteId: { type: String, required: true },
    existingBlockNumber: { type: Number, default: 0 },
    existingGuardPostsNumber: { type: Number, default: 0 },
    readOnly: { type: Boolean, default: false },
});

const { updateSite, setSiteGuardPosts } = useSiteSettings()


const count = defineModel<number>({ default: 0 });
const valid = ref(false);
const updating = ref(false)

const toastObject = reactive({
    show: false,
    message: "",
    color: "",
});

const dialog = reactive({
  updateBlockPrompt: false,
})


const emits = defineEmits(["success", "error"]);


const { requiredRule } = useUtils();

function validNumber(value: number) {
    return value > 0 || "Number must be greater than zero.";
}

const rules = computed(() => {
    const arr = [];
    if (props.required) {
        arr.push(requiredRule);
        arr.push(validNumber);
    }
    return arr;
});


function handleSave() {
  const previousCount =
    props.type === 'blocks'
      ? props.existingBlockNumber
      : props.type === 'guard_posts'
      ? props.existingGuardPostsNumber
      : null;

  if (!previousCount) {
    handleProceedSave();
    return;
  }

  if (count.value < previousCount) {
    dialog.updateBlockPrompt = true;
    return;
  }

  handleProceedSave();
}



async function handleProceedSave() {
    if (!props.siteId) {
        return emits('error', 'Site ID is required')
    }

    dialog.updateBlockPrompt = false;
    updating.value = true;

    try {
        if (props.type === 'blocks') {
            await updateSite(props.siteId, { block: count.value });
            handleSuccess('The number of blocks has been updated successfully!')
        } else if (props.type) {
            await setSiteGuardPosts(props.siteId, count.value)
            handleSuccess('The number of guard posts has been updated successfully!')

        } else {
            throw new Error('Invalid type Prop provided.')
        }

        emits('success')
    } catch (error: any) {
        const message = error?.data?.message || `Error updating ${props.type.replace('_', ' ')}`;
        handleError(message)
    } finally {
        updating.value = false;
    }
}

const handleSuccess = (message: string) => {
    toastObject.show = true;
    toastObject.message = message;
    toastObject.color = "success";
};

const handleError = (message: string) => {
    toastObject.show = true;
    toastObject.message = message;
    toastObject.color = "error";
};

</script>
