<template>
  <v-card width="100%" :loading="processing">
    <v-toolbar>
      <v-row no-gutters class="fill-height px-6" align="center">
        <span class="font-weight-bold text-h5 text-capitalize">
          {{ prop.mode }} {{ prop.type }}
        </span>
      </v-row>
    </v-toolbar>
    <v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-5 my-3">
      <div class="w-100 d-flex justify-space-between ga-2">
        <span v class="text-subtitle-1 w-100 font-weight-bold mb-3">
          <span v-if="step === 1">General Information</span>
          <span v-else-if="step === 2">Pass Information</span>
        </span>
        <span class="text-subtitle-2 font-weight-bold" style="text-wrap: nowrap;">Step
          <span class="text-primary-button">{{ step }}</span>/2</span>
      </div>
      <v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorMessage = ''">
        <v-row no-gutters class="pt-4">

          <template v-if="step === 1">
            <v-col cols="12">
              <v-row>
                <v-col cols="12">
                  <InputLabel class="text-capitalize" title="Full Name" required />
                  <v-text-field v-model.trim="form.name" density="comfortable" :rules="[requiredRule]" />
                </v-col>
              </v-row>
            </v-col>


            <v-col cols="12">
              <v-row>
                <v-col cols="12">
                  <InputLabel class="text-capitalize" title="NRIC" />
                  <InputNRICNumber v-model.trim="form.nric"  density="comfortable" />
                </v-col>
              </v-row>
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Phone Number" required />
              <InputPhoneNumberV2 v-model="form.contact" density="comfortable" :rules="[requiredRule]" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Vehicle Number" />
              <InputVehicleNumber v-model.trim="form.plateNumber" density="comfortable" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Block" required />
              <v-select v-model="form.block" :items="blocksArray" item-value="value" item-title="title" attached
                :loading="blockStatus === 'pending'" @update:model-value="handleChangeBlock" density="comfortable"
                :rules="[requiredRule]" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Level" required />
              <v-select v-model="form.level" :items="levelsArray" density="comfortable" :disabled="!form.block"
                :loading="levelsStatus === 'pending'" @update:model-value="handleChangeLevel" :rules="[requiredRule]" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Unit" required />
              <v-select v-model="form.unit" :items="unitsArray" @update:model-value="handleUpdateUnit"
                density="comfortable" :disabled="!form.level" :loading="unitsStatus === 'pending'"
                :rules="[requiredRule]" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Start Date" required />
              <InputDateTimePicker v-model:utc="form.start" ref="startDateRef" name="start_date" :rules="[validStartDateRule]" />
            </v-col>
            <v-col cols="12">
              <InputLabel class="text-capitalize" title="End Date" required />
              <InputDateTimePicker v-model:utc="form.end" ref="endDateRef" name="end_date" :rules="[validExpiryDateRule]" />
            </v-col>

            <v-col cols="12">
              <InputLabel class="text-capitalize" title="Remarks" />
              <v-textarea v-model="form.remarks" density="comfortable" :rows="3" no-resize />
            </v-col>
          </template>


          <template v-else-if="step === 2">
            <v-col cols="12">
              <PassInformation />
            </v-col>

            <v-col v-if="prop.mode === 'add'" cols="12" class="mt-2">
              <v-checkbox v-model="createMore" density="comfortable" hide-details>
                <template #label>
                  <span class="text-subtitle-2 font-weight-bold">
                    Create more
                  </span>
                </template>
              </v-checkbox>
            </v-col>
          </template>

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

    <v-row no-gutters class="w-100" v-if="errorMessage">
      <p class="text-error w-100 text-center text-subtitle-2">{{ errorMessage }}</p>
    </v-row>
    <v-toolbar density="compact">
      <v-row no-gutters>
        <v-col cols="6">
          <v-btn v-if="step > 1" tile block variant="text" class="text-none" size="48" @click="back" text="Back" />
          <v-btn v-else tile block variant="text" class="text-none" size="48" @click="close" text="Close" />
        </v-col>
        <v-col cols="6">
          <v-btn tile block variant="flat" color="primary-button" class="text-none" size="48" :disabled="processing"
            @click="handleNextPage" :text="step === 2 ? 'Submit' : 'Next'" />
        </v-col>
      </v-row>
    </v-toolbar>
  </v-card>
</template>

<script setup lang="ts">
import { property } from 'zod/v4';

const prop = defineProps({
  org: {
    type: String,
    required: true
  },
  site: {
    type: String,
    required: true
  },
  mode: {
    type: String as PropType<'add' | 'edit'>,
    default: 'add'
  },
  type: {
    type: String as PropType<TPeopleType>,
    required: true
  },
  activeId: {
    type: String as PropType<string | null>, // id of person you are trying to update
    default: null
  },
  people: {
    type: Object as PropType<TPeople>,
    required: false
  }
});

const { requiredRule, formatDateISO8601 } = useUtils();
const { getSiteById, getSiteLevels, getSiteUnits } = useSiteSettings();
const { create, updateById } = usePeople();

const emit = defineEmits(['back', 'select', 'done', 'done:more', 'error', 'close']);


const form = reactive<Partial<TPeoplePayload>>({
  name: "",
  nric: "",
  contact: "",
  plateNumber: "",
  block: "",
  level: "",
  unit: "",
  unitName: "",
  remarks: "",
  start: "",
  end: "",
  type: prop.type
})


const validForm = ref(false);
const formRef = ref<HTMLFormElement | null>(null);
const processing = ref(false);
const message = ref('');
const errorMessage = ref('');
const createMore = ref(false)

const startDateRef = ref<HTMLElement>()
const endDateRef = ref<HTMLElement>()

const step = ref(1)

const blocksArray = ref<TDefaultOptionObj[]>([]);
const levelsArray = ref<TDefaultOptionObj[]>([]);
const unitsArray = ref<TDefaultOptionObj[]>([]);



const contractorTypes = [
  { title: "Estate Contractor", value: "estate-contractor" },
  { title: "Home Contractor", value: "home-contractor" },
  { title: "Property Agent", value: "property-agent" },
  { title: "House Mover", value: "house-mover" },
]



const { data: siteData, refresh: refreshSiteData, status: blockStatus } = useLazyAsyncData(
  `fetch-site-data-${prop.site}`,
  () => getSiteById(prop.site),);

const { data: levelsData, refresh: refreshLevelsData, status: levelsStatus } = useLazyAsyncData(
  `fetch-levels-data-${prop.site}-${form.block}`,
  async () => {
    if (!form.block) return Promise.resolve(null);
    return await getSiteLevels(prop.site, { block: Number(form.block) })
  }, { watch: [() => form.block],});

const { data: unitsData, refresh: refreshUnitsData, status: unitsStatus } = useLazyAsyncData(
  `fetch-units-data-${prop.site}-${form.level}`,
  async () => {
    if (!form.level) return Promise.resolve(null);
    return await getSiteUnits(prop.site, Number(form.block), form.level)
  }, { watch: [()=> form.level]});

watch(
  siteData,
  (newVal) => {
    const siteDataValue = newVal as any;
    if (siteDataValue) {
      const numberOfBlocks = siteDataValue.metadata?.block || 0;
      for (let i = 1; i <= numberOfBlocks; i++) {
        blocksArray.value.push({
          title: `Block ${i}`,
          value: i
        });
      }

    } else {
      blocksArray.value = [];
    }
  }, { immediate: true });


watch(
  levelsData,
  (newVal: any) => {
    if (newVal) {
      const arr = newVal.levels || [];
      levelsArray.value = arr?.map((level: any) => ({
        title: level,
        value: level
      }));
    } else {
      levelsArray.value = [];
    }
  }, { immediate: true });

watch(
  unitsData,
  (newVal: any) => {
    if (newVal && Array.isArray(newVal)) {
      const arr = newVal || [];
      unitsArray.value = arr?.map((unit: any) => ({
        title: unit?.name,
        value: unit?._id
      }));
    } else {
      unitsArray.value = [];
    }
  }, { immediate: true });



function handleChangeBlock(value: any) {
  form.level = '';
  form.unit = '';
}

function handleChangeLevel(value: any) {
  form.unit = '';
}

function handleUpdateUnit(value: any) {
  const selectedUnit = unitsArray.value?.find((x: any) => x.value === value)
  form.unitName = selectedUnit?.title || ''
}

function dateToday() {
  const today = new Date()
  return today.toISOString()
}


function back() {
  if (step.value > 1) {
    step.value--
  }
  emit("back");
  message.value = '';
}

function close() {
  emit("close");
  message.value = '';
}



async function handleNextPage() {
  errorMessage.value = ''
  formRef.value!.validate()
  if (!validForm.value) {
    errorMessage.value = "Please complete all required fields *"
    return
  }
  const stepVal = step.value
  if (stepVal < 2) step.value++
  else if (stepVal === 2) {
    await submit()
  }

}

function resetForm() {
  formRef.value?.resetValidation();

  Object.assign(form, {
    name: "",
    nric: "",
    contact: "",
    plateNumber: "",
    block: "",
    level: "",
    unit: "",
    remarks: ""
  });

  validForm.value = false;
}

function validStartDateRule(value: string) {
  if (!value) {
    return 'Start Date is required';
  }

  return true;
}

function validExpiryDateRule(value: string) {
  const startDateISO = form.start;
  if (!value) {
    return 'End Date is required';
  }

  if (value && startDateISO) {
    const expiry = new Date(value);
    const start = new Date(startDateISO as string);
    return expiry > start || 'End date must be later than start date';
  }
  return true;
}



async function submit() {
  formRef.value!.validate()
  errorMessage.value = '';
  processing.value = true;

  let payload: Partial<TPeoplePayload> = {}

  if (prop.mode === 'add') {
    payload = {
      ...payload,
      org: prop.org,
      site: prop.site,
      ...form,
    }

  } else if (prop.mode === 'edit') {
    const { type, ...rest } = form
    payload = {
      ...payload,
      ...rest
    }

  }
  try {
    if (prop.mode === 'add') {
      await create(payload)
    } else if (prop.mode === 'edit'){
      const userId = prop.activeId
      if(!userId) {
        throw new Error('User Id prop is not defined')
      }

      await updateById(userId, payload)
    }

    if (createMore.value) {
      resetForm()
      step.value = 1;
      errorMessage.value = ""
      emit("done:more")
      createMore.value = false
    } else emit("done")

  } catch (error: any) {
    const err = error?.data?.message
    errorMessage.value = err || `Failed to ${prop.mode === 'add' ? 'add' : 'update'} ${prop.type}. Please try again.`;
  } finally {
    processing.value = false;
  }
}

watch(() => form.plateNumber, (newVal) => {
  form.plateNumber = newVal?.toUpperCase()
})

watch(() => [form.end, form.start], () => {
  (endDateRef.value as any)?.validate();
  (startDateRef.value as any)?.validate();
});

async function mountExistingData() {
  setTimeout(() => {
    const people = prop.people
    if (!people) return

    (Object.keys(form) as (keyof typeof form)[]).forEach((key) => {
      if (key in people) {
        form[key] = people[key as keyof TPeople]
      }
    })
  }, 100)
}

onMounted(() => {
  step.value = 1;
  createMore.value = false;
  if(prop.mode === 'edit'){
    mountExistingData()
  } else {
    form.start = dateToday()
  }
})

</script>
<style scoped>
.button-outline-class {
  border: 1px solid rgba(var(--v-theme-primary));
}
</style>
