<script setup>
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { useAuthStore } from '@/stores/auth'
import { getMyProfile, updateMyProfile } from '@/services/profileService'
import { deleteFile, getTemporaryFileUrl, uploadFile } from '@/services/fileService'
import {
  getDesaOptions,
  getKabupatenOptions,
  getKecamatanOptions,
  getProvinsiOptions,
} from '@/services/wilayahService'
import { showError, showSuccess } from '@/utils/swal'

const authStore = useAuthStore()
const loading = ref(false)
const saving = ref(false)
const profile = ref(null)
const selectedPhoto = ref(null)
const photoUrl = ref('')
const localPhotoUrl = ref('')
const photoInput = ref(null)
const photoDragging = ref(false)
const wilayahOptions = reactive({ provinsi: [], kabupaten: [], kecamatan: [], desa: [] })
const wilayahLoading = reactive({ provinsi: false, kabupaten: false, kecamatan: false, desa: false })

const form = reactive({
  name: '',
  username: '',
  email: '',
  whatsapp_number: '',
  nik: '',
  address: '',
  provinsi_id: '',
  kabupaten_id: '',
  kecamatan_id: '',
  desa_id: '',
  current_password: '',
  password: '',
  password_confirmation: '',
})

const accessLevelLabel = computed(() => {
  const labels = {
    customer: 'Customer',
    staff: 'Staff',
    tenant_owner: 'Pemilik Tenant',
    master_admin: 'Master Admin',
  }

  return labels[profile.value?.access_level] || profile.value?.access_level || '-'
})

const tenants = computed(() => profile.value?.user_tenants || [])
const menuGroups = computed(() => profile.value?.user_menu_groups || [])
const displayedPhotoUrl = computed(() => localPhotoUrl.value || photoUrl.value)

function fillForm(user) {
  const userProfile = user?.user_profile || {}

  Object.assign(form, {
    name: user?.name || '',
    username: user?.username || '',
    email: user?.email || '',
    whatsapp_number: user?.whatsapp_number || '',
    nik: userProfile.nik || '',
    address: userProfile.address || '',
    provinsi_id: userProfile.provinsi_id ? String(userProfile.provinsi_id) : '',
    kabupaten_id: userProfile.kabupaten_id ? String(userProfile.kabupaten_id) : '',
    kecamatan_id: userProfile.kecamatan_id ? String(userProfile.kecamatan_id) : '',
    desa_id: userProfile.desa_id ? String(userProfile.desa_id) : '',
    current_password: '',
    password: '',
    password_confirmation: '',
  })
}

function optionRows(response) {
  return Array.isArray(response?.data) ? response.data : []
}

async function loadWilayahOptions(level, parentId = null) {
  wilayahLoading[level] = true
  try {
    const loaders = {
      provinsi: () => getProvinsiOptions(),
      kabupaten: () => getKabupatenOptions(parentId),
      kecamatan: () => getKecamatanOptions(parentId),
      desa: () => getDesaOptions(parentId),
    }
    const response = await loaders[level]()
    wilayahOptions[level] = optionRows(response)
  } catch (error) {
    wilayahOptions[level] = []
    showError(error?.response?.data?.message || `Gagal memuat pilihan ${level}.`)
  } finally {
    wilayahLoading[level] = false
  }
}

async function hydrateWilayahOptions() {
  await loadWilayahOptions('provinsi')
  if (form.provinsi_id) await loadWilayahOptions('kabupaten', form.provinsi_id)
  if (form.kabupaten_id) await loadWilayahOptions('kecamatan', form.kabupaten_id)
  if (form.kecamatan_id) await loadWilayahOptions('desa', form.kecamatan_id)
}

async function onProvinsiChange(event) {
  form.provinsi_id = event.target.value
  form.kabupaten_id = ''
  form.kecamatan_id = ''
  form.desa_id = ''
  wilayahOptions.kabupaten = []
  wilayahOptions.kecamatan = []
  wilayahOptions.desa = []
  if (form.provinsi_id) await loadWilayahOptions('kabupaten', form.provinsi_id)
}

async function onKabupatenChange(event) {
  form.kabupaten_id = event.target.value
  form.kecamatan_id = ''
  form.desa_id = ''
  wilayahOptions.kecamatan = []
  wilayahOptions.desa = []
  if (form.kabupaten_id) await loadWilayahOptions('kecamatan', form.kabupaten_id)
}

async function onKecamatanChange(event) {
  form.kecamatan_id = event.target.value
  form.desa_id = ''
  wilayahOptions.desa = []
  if (form.kecamatan_id) await loadWilayahOptions('desa', form.kecamatan_id)
}

async function fetchProfile() {
  loading.value = true

  try {
    const response = await getMyProfile()
    profile.value = response?.data || null
    fillForm(profile.value)
    await hydrateWilayahOptions()
    await loadProfilePhoto(profile.value)
    authStore.setUser(profile.value)
  } catch (error) {
    showError(error?.response?.data?.message || 'Gagal memuat profile.')
  } finally {
    loading.value = false
  }
}

async function loadProfilePhoto(user) {
  photoUrl.value = ''

  if (!user?.profile_photo?.uuid) return

  try {
    const response = await getTemporaryFileUrl(user.profile_photo.uuid)
    photoUrl.value = response?.data?.url || ''
  } catch {
    photoUrl.value = ''
  }
}

function setSelectedPhoto(file, input = null) {

  if (file && !file.type.startsWith('image/')) {
    if (input) input.value = ''
    showError('Foto profil harus berupa file gambar.')
    return
  }

  if (file && file.size > 5 * 1024 * 1024) {
    if (input) input.value = ''
    showError('Ukuran foto profil maksimal 5 MB.')
    return
  }

  if (localPhotoUrl.value) URL.revokeObjectURL(localPhotoUrl.value)
  selectedPhoto.value = file
  localPhotoUrl.value = file ? URL.createObjectURL(file) : ''
}

function selectPhoto(event) {
  setSelectedPhoto(event.target.files?.[0] || null, event.target)
}

function dropPhoto(event) {
  photoDragging.value = false
  setSelectedPhoto(event.dataTransfer?.files?.[0] || null)
}

function clearSelectedPhoto() {
  if (localPhotoUrl.value) URL.revokeObjectURL(localPhotoUrl.value)
  selectedPhoto.value = null
  localPhotoUrl.value = ''
  if (photoInput.value) photoInput.value.value = ''
}

function nullableNumber(value) {
  return value === '' || value === null ? null : Number(value)
}

function buildPayload() {
  const payload = {
    name: form.name.trim(),
    username: form.username.trim() || null,
    email: form.email.trim(),
    whatsapp_number: form.whatsapp_number.trim() || null,
    user_profile: {
      nik: form.nik.trim() || null,
      address: form.address.trim() || null,
      provinsi_id: nullableNumber(form.provinsi_id),
      kabupaten_id: nullableNumber(form.kabupaten_id),
      kecamatan_id: nullableNumber(form.kecamatan_id),
      desa_id: nullableNumber(form.desa_id),
    },
  }

  if (form.password) {
    payload.current_password = form.current_password
    payload.password = form.password
    payload.password_confirmation = form.password_confirmation
  }

  return payload
}

async function saveProfile() {
  saving.value = true

  try {
    const payload = buildPayload()
    let uploadedPhoto = null

    if (selectedPhoto.value) {
      const uploadResponse = await uploadFile(selectedPhoto.value, 'profile')
      uploadedPhoto = uploadResponse?.data || null
      payload.profile_photo_file_id = uploadedPhoto?.id
    }

    let response
    try {
      response = await updateMyProfile(payload)
    } catch (error) {
      if (uploadedPhoto?.uuid) {
        await deleteFile(uploadedPhoto.uuid).catch(() => {})
      }
      throw error
    }

    profile.value = response?.data || null
    fillForm(profile.value)
    selectedPhoto.value = null
    if (localPhotoUrl.value) URL.revokeObjectURL(localPhotoUrl.value)
    localPhotoUrl.value = ''
    await loadProfilePhoto(profile.value)
    authStore.setUser(profile.value)
    showSuccess('Profile berhasil diperbarui.')
  } catch (error) {
    const errors = error?.response?.data?.errors
    const firstError = errors ? Object.values(errors).flat()[0] : null
    showError(firstError || error?.response?.data?.message || 'Gagal memperbarui profile.')
  } finally {
    saving.value = false
  }
}

onMounted(fetchProfile)
onBeforeUnmount(() => {
  if (localPhotoUrl.value) URL.revokeObjectURL(localPhotoUrl.value)
})
</script>

<template>
  <CRow class="brdvx-page-row g-0 m-0">
    <CCol :xs="12" class="brdvx-page-column p-0">
      <div class="brdvx-page-container">
        <div class="brdvx-page-header">
          <h5 class="mb-1 fw-semibold">Profile Saya</h5>
        </div>

        <div v-if="loading" class="text-center py-5">
          <CSpinner color="primary" />
        </div>

        <CRow v-else-if="profile" class="g-3">
          <CCol :lg="4">
            <CCard class="h-100">
              <CCardBody class="text-center">
                <CAvatar
                  :src="displayedPhotoUrl || undefined"
                  color="primary"
                  text-color="white"
                  class="image-previewable profile-photo-avatar"
                  :data-preview-alt="`Foto ${profile.name}`"
                >
                  <template v-if="!displayedPhotoUrl">
                    {{ profile.name?.charAt(0)?.toUpperCase() || 'U' }}
                  </template>
                </CAvatar>
                <div
                  class="profile-photo-uploader"
                  :class="{ 'is-dragging': photoDragging }"
                  @dragenter.prevent="photoDragging = true"
                  @dragover.prevent="photoDragging = true"
                  @dragleave.prevent="photoDragging = false"
                  @drop.prevent="dropPhoto"
                >
                  <div class="profile-photo-uploader-icon">
                    <CIcon icon="cil-cloud-download" size="xl" />
                  </div>
                  <div class="fw-semibold">Ganti foto profil</div>
                  <div class="small text-body-secondary">
                    Tarik gambar ke sini atau pilih dari perangkat
                  </div>
                  <div class="d-flex flex-wrap justify-content-center gap-2 mt-3">
                    <CButton color="primary" variant="outline" size="sm" @click="photoInput?.click()">
                      <CIcon icon="cil-camera" class="me-1" />
                      Pilih Gambar
                    </CButton>
                    <CButton
                      v-if="selectedPhoto"
                      color="secondary"
                      variant="ghost"
                      size="sm"
                      @click="clearSelectedPhoto"
                    >
                      Batal
                    </CButton>
                  </div>
                  <div v-if="selectedPhoto" class="profile-photo-file mt-3">
                    <CIcon icon="cil-check-circle" class="text-success" />
                    <span>{{ selectedPhoto.name }}</span>
                  </div>
                </div>
                <input
                  ref="photoInput"
                  type="file"
                  accept="image/jpeg,image/png,image/webp,image/gif"
                  class="d-none"
                  aria-label="Pilih foto profile"
                  @change="selectPhoto"
                />
                <div class="small text-body-secondary mt-2 mb-3">
                  JPG, PNG, WebP, atau GIF. Maksimal 5 MB.
                </div>
                <h5 class="mb-1">{{ profile.name }}</h5>
                <div class="text-body-secondary mb-2">{{ profile.email }}</div>
                <CBadge color="primary">{{ accessLevelLabel }}</CBadge>

                <hr />

                <div class="text-start">
                  <div class="small text-body-secondary">Status</div>
                  <div class="mb-3">{{ profile.status }}</div>
                  <div class="small text-body-secondary">Tenant</div>
                  <div v-if="tenants.length" class="d-flex flex-wrap gap-1 mt-1">
                    <CBadge
                      v-for="membership in tenants"
                      :key="membership.id"
                      :color="membership.is_default ? 'primary' : 'secondary'"
                    >
                      {{ membership.tenant?.tenant_name || `Tenant #${membership.tenant_id}` }}
                    </CBadge>
                  </div>
                  <div v-else>-</div>

                  <div class="small text-body-secondary mt-3">Menu Group</div>
                  <div v-if="menuGroups.length" class="d-flex flex-wrap gap-1 mt-1">
                    <CBadge v-for="assignment in menuGroups" :key="assignment.id" color="info">
                      {{ assignment.menu_group?.name || `Group #${assignment.menu_group_id}` }}
                    </CBadge>
                  </div>
                  <div v-else>-</div>
                </div>
              </CCardBody>
            </CCard>
          </CCol>

          <CCol :lg="8">
            <CForm @submit.prevent="saveProfile">
              <CCard class="mb-3">
                <CCardHeader class="fw-semibold">Informasi Akun</CCardHeader>
                <CCardBody>
                  <CRow class="g-3">
                    <CCol :md="6">
                      <CFormLabel>Nama</CFormLabel>
                      <CFormInput v-model="form.name" required />
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Username</CFormLabel>
                      <CFormInput v-model="form.username" autocomplete="username" />
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Email</CFormLabel>
                      <CFormInput v-model="form.email" type="email" required />
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Nomor WhatsApp</CFormLabel>
                      <CFormInput v-model="form.whatsapp_number" />
                    </CCol>
                  </CRow>
                </CCardBody>
              </CCard>

              <CCard class="mb-3">
                <CCardHeader class="fw-semibold">Data Profile</CCardHeader>
                <CCardBody>
                  <CRow class="g-3">
                    <CCol :md="6">
                      <CFormLabel>NIK</CFormLabel>
                      <CFormInput v-model="form.nik" />
                    </CCol>
                    <CCol :xs="12">
                      <CFormLabel>Alamat</CFormLabel>
                      <CFormTextarea v-model="form.address" rows="3" />
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Provinsi</CFormLabel>
                      <CFormSelect
                        v-model="form.provinsi_id"
                        :disabled="wilayahLoading.provinsi"
                        @change="onProvinsiChange"
                      >
                        <option value="">{{ wilayahLoading.provinsi ? 'Memuat provinsi...' : 'Pilih provinsi' }}</option>
                        <option v-for="row in wilayahOptions.provinsi" :key="row.id" :value="String(row.id)">
                          {{ row.kode }} — {{ row.nama }}
                        </option>
                      </CFormSelect>
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Kabupaten</CFormLabel>
                      <CFormSelect
                        v-model="form.kabupaten_id"
                        :disabled="!form.provinsi_id || wilayahLoading.kabupaten"
                        @change="onKabupatenChange"
                      >
                        <option value="">{{ wilayahLoading.kabupaten ? 'Memuat kabupaten...' : 'Pilih kabupaten' }}</option>
                        <option v-for="row in wilayahOptions.kabupaten" :key="row.id" :value="String(row.id)">
                          {{ row.kode }} — {{ row.nama }}
                        </option>
                      </CFormSelect>
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Kecamatan</CFormLabel>
                      <CFormSelect
                        v-model="form.kecamatan_id"
                        :disabled="!form.kabupaten_id || wilayahLoading.kecamatan"
                        @change="onKecamatanChange"
                      >
                        <option value="">{{ wilayahLoading.kecamatan ? 'Memuat kecamatan...' : 'Pilih kecamatan' }}</option>
                        <option v-for="row in wilayahOptions.kecamatan" :key="row.id" :value="String(row.id)">
                          {{ row.kode }} — {{ row.nama }}
                        </option>
                      </CFormSelect>
                    </CCol>
                    <CCol :md="6">
                      <CFormLabel>Desa</CFormLabel>
                      <CFormSelect
                        v-model="form.desa_id"
                        :disabled="!form.kecamatan_id || wilayahLoading.desa"
                      >
                        <option value="">{{ wilayahLoading.desa ? 'Memuat desa...' : 'Pilih desa' }}</option>
                        <option v-for="row in wilayahOptions.desa" :key="row.id" :value="String(row.id)">
                          {{ row.kode }} — {{ row.nama }}
                        </option>
                      </CFormSelect>
                    </CCol>
                  </CRow>
                </CCardBody>
              </CCard>

              <CCard class="mb-3">
                <CCardHeader class="fw-semibold">Ubah Password</CCardHeader>
                <CCardBody>
                  <p class="small text-body-secondary">Kosongkan jika tidak ingin mengubah password.</p>
                  <CRow class="g-3">
                    <CCol :md="4">
                      <CFormLabel>Password Saat Ini</CFormLabel>
                      <CFormInput v-model="form.current_password" type="password" autocomplete="current-password" />
                    </CCol>
                    <CCol :md="4">
                      <CFormLabel>Password Baru</CFormLabel>
                      <CFormInput v-model="form.password" type="password" autocomplete="new-password" />
                    </CCol>
                    <CCol :md="4">
                      <CFormLabel>Konfirmasi Password</CFormLabel>
                      <CFormInput v-model="form.password_confirmation" type="password" autocomplete="new-password" />
                    </CCol>
                  </CRow>
                </CCardBody>
              </CCard>

              <div class="d-flex justify-content-end">
                <CButton color="primary" type="submit" :disabled="saving">
                  {{ saving ? 'Menyimpan...' : 'Simpan Perubahan' }}
                </CButton>
              </div>
            </CForm>
          </CCol>
        </CRow>
      </div>
    </CCol>
  </CRow>
</template>
