<template>
  <v-card width="100%">
    <v-toolbar>
      <v-row no-gutters class="fill-height px-6" align="center">
        <span class="font-weight-bold text-h5">
          {{ props.title }}
        </span>
      </v-row>
    </v-toolbar>

    <v-card-text style="max-height: 100vh; overflow-y: auto">
      <v-form v-model="validForm" ref="form" :disabled="disable">
        <v-row no-gutters>

          <!-- EMAIL -->
          <v-col cols="12" class="mt-2">
            <InputLabel title="Email" required />
            <v-text-field
              v-model="invite.email"
              density="comfortable"
              :rules="[requiredRule, emailRule]"
              :loading="loading.verifyingEmail"
            />
            <div v-if="existingUserMessage" class="text-subtitle-2 text-error mt-n3 mb-2">
              {{ existingUserMessage }}
            </div>
          </v-col>

          <!-- APP MULTI SELECT -->
          <v-col v-if="APP" cols="12" class="mt-2">
            <InputLabel title="App" required />
            <v-autocomplete
              v-model="invite.app"
              :items="apps"
              item-title="title"
              item-value="value"
              multiple
              chips
              closable-chips
              density="comfortable"
              :rules="[requiredRule]"
              @update:model-value="handleUpdateApp"
            >
              <template #item="{ props: itemProps, item }">
                <v-list-item
                  v-bind="itemProps"
                  :disabled="item.raw.disabled"
                >
                  <template #prepend>
                    <v-checkbox-btn
                      :model-value="invite.app.includes(item.raw.value)"
                      :disabled="item.raw.disabled"
                      color="black"
                      density="comfortable"
                    />
                  </template>

                  <template #title>
                    <span :class="item.raw.disabled ? 'text-disabled' : ''">
                      {{ item.raw.title }}
                    </span>
                  </template>

                  <template #subtitle>
                    <span v-if="item.raw.disabled" class="text-error text-caption">
                      Already a member
                    </span>
                  </template>
                </v-list-item>
              </template>
            </v-autocomplete>
          </v-col>

          <!-- ROLE -->
          <v-col cols="12">
            <InputLabel title="Role" />
            <v-autocomplete
              v-model="invite.role"
              :items="roles"
              item-title="name"
              item-value="_id"
              density="comfortable"
              :rules="[requiredRule]"
            />
          </v-col>

          <!-- SITE -->
          <v-col v-if="hasSite" cols="12">
            <InputLabel title="Site" />
            <v-autocomplete
              v-model="invite.site"
              :items="sites"
              density="comfortable"
              :rules="[requiredRule]"
              @update:model-value="handleUpdateSite"
            />
          </v-col>


          <!-- ERROR -->
          <v-col cols="12" class="my-2 text-center">
            <span class="text-subtitle-2 text-error">
              {{ submitError }}
            </span>
          </v-col>

        </v-row>
      </v-form>
    </v-card-text>

    <!-- ACTION -->
    <v-toolbar density="compact">
      <v-row no-gutters>
        <v-col cols="6">
          <v-btn block variant="text" class="text-none" size="48" @click="cancel">
            Cancel
          </v-btn>
        </v-col>

        <v-col cols="6">
          <v-btn
            block
            variant="flat"
            color="black"
            class="text-none"
            size="48"
            :disabled="!validForm"
            :loading="loading.submittingForm"
            @click="submit"
          >
            Submit
          </v-btn>
        </v-col>
      </v-row>
    </v-toolbar>
  </v-card>
</template>

<script setup lang="ts">
import { computed, ref, reactive, watchEffect, watch } from 'vue'
import useCustomerSite from '../composables/useCustomerSite'
import useLocal from '../composables/useLocal'
import useRole from '../composables/useRole'
import useUser from '../composables/useUser'
import useUtils from '../composables/useUtils'
import useOrg from '../composables/useOrg'
import useMember from '../composables/useMember'

const APP = useRuntimeConfig().public.APP

/* ================= PROPS ================= */
const props = defineProps({
  title: { type: String, default: "Invite Form" },
  app: { type: String, default: "" },
  org: { type: String, default: "" },
  mode: { type: String, default: "create" },
})

const emit = defineEmits(["cancel", "success"])

const validForm = ref(false)
const form = ref()

const loading = reactive({
  submittingForm: false,
  verifyingEmail: false,
})

/* ================= FORM ================= */
const invite = ref({
  email: "",
  app: [] as string[],
  role: "",
  org: props.org ?? "",
  site: "",
  siteName: "",
  isMemberInvite: false,
})

if (props.mode === "create") {
  invite.value.app = props.app ? [props.app] : []
}

/* ================= APP LIST ================= */
const APP_LIST = [
  { title: "Property Management Agency", value: "property_management_agency" },
  { title: "Security Agency", value: "security_agency" },
  { title: "Cleaning Services", value: "cleaning_services" },
  { title: "Mechanical & Electrical Services", value: "mechanical_electrical_services" },
  { title: "Pest Control Services", value: "pest_control_services" },
  { title: "Landscaping Services", value: "landscaping_services" },
  { title: "Pool Maintenance Services", value: "pool_maintenance_services" },
]

const { getByName } = useOrg()
const org = ref<any>(null)

watch(
  () => props.org,
  async (name) => {
    if (!name) return
    org.value = await getByName(name)
  },
  { immediate: true }
)

const apps = computed(() => {
  return APP_LIST.map(app => {
    const disabled = userAccess.value.some(
      (a: any) => a.type === app.value
    )
    return { ...app, disabled }
  })
})

/* ================= SITE ================= */
const { natureOfBusiness } = useLocal()

const hasSite = computed(() =>
  natureOfBusiness.some(i => i.value === invite.value.app)
)

const sites = ref<any[]>([])
const { getAll: getAllCustomerSite } = useCustomerSite()

const { data: siteData, refresh: refreshSiteData } = await useLazyAsyncData(
  "sites",
  () => getAllCustomerSite({ org: org.value?._id, limit: 50 })
)

watchEffect(() => {
  if (siteData.value) {
    sites.value = siteData.value.items.map((i: any) => ({
      title: i.name,
      value: i.site,
    }))
  }
})

watch(
  () => org.value?._id,
  async (id) => {
    if (!id) return
    await refreshSiteData()
  }
)

/* ================= ROLE ================= */
const roles = ref<any[]>([])
const { getRoles } = useRole()

const { data: roleData, refresh: refreshRoles } = await useLazyAsyncData(
  "roles",
  () => getRoles({ org: org.value?._id, type: props.app, limit: 50 }),
  { watch: [() => props.app] }
)

watchEffect(() => {
  if (roleData.value) roles.value = roleData.value.items
})

watch(
  () => org.value?._id,
  async (id) => {
    if (!id) return
    await refreshRoles()
  }
)

/* ================= EVENTS ================= */
async function handleUpdateApp(value: string[]) {
  invite.value.role = ""
  invite.value.site = ""
  await refreshRoles()
}

function handleUpdateSite(id: string) {
  const obj = sites.value.find(x => x.value === id)
  invite.value.siteName = obj?.title || ""
}

/* ================= EMAIL CHECK ================= */
const { inviteUserClient, getUserByEmail } = useUser()
const { getAllByUserId } = useMember()
const { requiredRule, emailRule } = useUtils()

const existingUserMessage = ref("")
const submitError = ref("")
const disable = ref(false)
const existingUser = ref<any>(null)
const userAccess = ref<any[]>([])

let timeout: any = null

watch(
  () => invite.value.email,
  (email) => {
    clearTimeout(timeout)
    existingUserMessage.value = ""
    existingUser.value = null
    userAccess.value = []

    if (!email || email.length < 3) return

    timeout = setTimeout(async () => {
      await checkEmail(email)
    }, 400)
  }
)

async function checkEmail(email: string) {
  loading.verifyingEmail = true
  existingUserMessage.value = ""

  try {
    const user = await getUserByEmail(email)

    if (user?._id) {
      existingUser.value = user
      existingUserMessage.value = `User already exists: ${email}`

     const memberRes = await getAllByUserId(user._id)

    userAccess.value = memberRes?.items || []
    } else {
      existingUser.value = null
      userAccess.value = []
    }
  } catch (e) {
    existingUser.value = null
    userAccess.value = []
  } finally {
    loading.verifyingEmail = false
  }
}

/* ================= SUBMIT ================= */
async function submit() {
  loading.submittingForm = true
  submitError.value = ""

  try {

    for (const app of invite.value.app) {

      await inviteUserClient({
        email: invite.value.email,

        app: [app],

        role: invite.value.role,

        org: org.value?._id,

        siteId: invite.value.site,
        siteName: invite.value.siteName,
      })
    }

    emit("success", true)

  } catch (e: any) {

    submitError.value =
      e?.response?._data?.message || "Error"

  } finally {

    loading.submittingForm = false
  }
}

function cancel() {
  emit("cancel")
}
</script>

