<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { createCustomer, getCustomer, getCustomerOptions, updateCustomer } from '@/services/customerService'
import { getTenants } from '@/services/tenantService'
import { deleteFile, getTemporaryFileUrl, uploadFile } from '@/services/fileService'
import { getDesaOptions, getKabupatenOptions, getKecamatanOptions, getProvinsiOptions } from '@/services/wilayahService'
import { showConfirm, showError, showSuccess } from '@/utils/swal.js'
import { compressCustomerImage } from '@/utils/imageCompression'
import CustomerLocationMap from '@/components/customers/CustomerLocationMap.vue'

const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()
const loading = ref(true)
const saving = ref(false)
const uploading = ref(false)
const fileInput = ref(null)
const selectedImage = ref(0)
const tenants = ref([]), profiles = ref([]), mikrotiks = ref([]), billingProfiles = ref([])
const provinsi = ref([]), kabupaten = ref([]), kecamatan = ref([]), desa = ref([])
const gallery = ref([])
const isEdit = computed(() => !!route.params.id)
const isMaster = computed(() => authStore.user?.is_master || authStore.user?.access_level === 'master_admin')
const form = reactive({
  tenant_id: '', customer_code: '', name: '', identity_number: '', email: '', whatsapp_number: '',
  installation_address: '', provinsi_id: '', kabupaten_id: '', kecamatan_id: '', desa_id: '',
  latitude: '', longitude: '', package_profile_id: '', nas_mikrotik_id: '', external_username: '',
  billing_profile_id: '', order_stage: 'registration', notes: '',
})
const categoryOptions = [
  ['house', 'Rumah'], ['installation', 'Instalasi'], ['modem', 'Modem/ONT'],
  ['odp', 'ODP'], ['cable', 'Jalur Kabel'], ['identity', 'Identitas'], ['other', 'Lainnya'],
]
const activeImage = computed(() => gallery.value[selectedImage.value] || null)
const tenantProfiles = computed(() => !form.tenant_id ? profiles.value : profiles.value.filter((x) => Number(x.tenant_id) === Number(form.tenant_id)))
const tenantNas = computed(() => !form.tenant_id ? mikrotiks.value : mikrotiks.value.filter((x) => Number(x.tenant_id) === Number(form.tenant_id)))
const tenantBillingProfiles = computed(() => !form.tenant_id ? billingProfiles.value : billingProfiles.value.filter((x) => Number(x.tenant_id) === Number(form.tenant_id)))

function optionRows(response) { return Array.isArray(response?.data) ? response.data : [] }
async function loadReferences() {
  const calls = [getProvinsiOptions(), getCustomerOptions()]
  if (isMaster.value) calls.push(getTenants({ per_page: 100, sort_by: 'tenant_name', sort_direction: 'asc' }))
  const [provinceResponse, customerOptions, tenantResponse] = await Promise.all(calls)
  provinsi.value = optionRows(provinceResponse)
  profiles.value = customerOptions?.data?.package_profiles || []
  mikrotiks.value = customerOptions?.data?.nas_mikrotiks || []
  billingProfiles.value = customerOptions?.data?.billing_profiles || []
  tenants.value = tenantResponse?.data?.data || []
}
async function loadKabupaten(reset = true) {
  if (reset) Object.assign(form, { kabupaten_id: '', kecamatan_id: '', desa_id: '' })
  kabupaten.value = form.provinsi_id ? optionRows(await getKabupatenOptions(form.provinsi_id)) : []
}
async function loadKecamatan(reset = true) {
  if (reset) Object.assign(form, { kecamatan_id: '', desa_id: '' })
  kecamatan.value = form.kabupaten_id ? optionRows(await getKecamatanOptions(form.kabupaten_id)) : []
}
async function loadDesa(reset = true) {
  if (reset) form.desa_id = ''
  desa.value = form.kecamatan_id ? optionRows(await getDesaOptions(form.kecamatan_id)) : []
}
async function onProvinsiChange(event) { form.provinsi_id = event.target.value; await loadKabupaten() }
async function onKabupatenChange(event) { form.kabupaten_id = event.target.value; await loadKecamatan() }
async function onKecamatanChange(event) { form.kecamatan_id = event.target.value; await loadDesa() }

async function resolveImageUrl(image) {
  try {
    const response = await getTemporaryFileUrl(image.uuid)
    return response?.data?.url || '/customer-default.svg'
  } catch {
    return '/customer-default.svg'
  }
}
async function hydrateGallery(images = []) {
  gallery.value = await Promise.all(images.map(async (image) => ({
    ...image,
    url: await resolveImageUrl(image),
    isNew: false,
  })))
  selectedImage.value = Math.max(0, gallery.value.findIndex((image) => image.is_cover))
}
async function loadCustomer() {
  if (!isEdit.value) return
  const response = await getCustomer('orders', route.params.id)
  const customer = response?.data || {}
  Object.keys(form).forEach((key) => {
    if (Object.prototype.hasOwnProperty.call(customer, key)) form[key] = customer[key] ?? ''
  })
  if (form.provinsi_id) await loadKabupaten(false)
  if (form.kabupaten_id) await loadKecamatan(false)
  if (form.kecamatan_id) await loadDesa(false)
  await hydrateGallery(customer.images || [])
}
async function initialize() {
  loading.value = true
  try {
    await loadReferences()
    await loadCustomer()
  } catch (error) {
    showError(error?.response?.data?.message || 'Gagal memuat form customer.')
    router.replace('/customers/orders')
  } finally { loading.value = false }
}
async function addImages(event) {
  const files = [...(event.target.files || [])].filter((file) => file.type.startsWith('image/'))
  if (!files.length) return
  if (gallery.value.length + files.length > 20) {
    showError('Maksimal 20 gambar untuk satu customer.'); event.target.value = ''; return
  }
  uploading.value = true
  try {
    for (const file of files) {
      const compressedFile = await compressCustomerImage(file)
      const response = await uploadFile(compressedFile, 'customer-image')
      const uploaded = response?.data
      const tempResponse = await getTemporaryFileUrl(uploaded.uuid)
      gallery.value.push({
        stored_file_id: uploaded.id, uuid: uploaded.uuid, original_name: uploaded.original_name,
        category: 'other', caption: '', is_cover: gallery.value.length === 0,
        sort_order: gallery.value.length, url: tempResponse?.data?.url || URL.createObjectURL(compressedFile), isNew: true,
      })
    }
    selectedImage.value = gallery.value.length - 1
  } catch (error) { showError(error?.response?.data?.message || 'Gagal mengunggah gambar.') }
  finally { uploading.value = false; event.target.value = '' }
}
function setCover(index) {
  gallery.value.forEach((image, imageIndex) => { image.is_cover = imageIndex === index })
  selectedImage.value = index
}
async function removeImage(index) {
  const image = gallery.value[index]
  const result = await showConfirm('Hapus Gambar', `Hapus "${image.original_name}" dari galeri?`)
  if (!result.isConfirmed) return
  if (image.isNew) {
    try { await deleteFile(image.uuid) } catch { /* relasi tetap dibuang dari form */ }
  }
  gallery.value.splice(index, 1)
  gallery.value.forEach((item, itemIndex) => { item.sort_order = itemIndex })
  if (gallery.value.length && !gallery.value.some((item) => item.is_cover)) gallery.value[0].is_cover = true
  selectedImage.value = Math.min(selectedImage.value, Math.max(0, gallery.value.length - 1))
}
function useCurrentLocation() {
  if (!navigator.geolocation) return showError('Browser tidak mendukung geolocation.')
  navigator.geolocation.getCurrentPosition(
    ({ coords }) => { form.latitude = coords.latitude.toFixed(7); form.longitude = coords.longitude.toFixed(7) },
    () => showError('Lokasi tidak dapat diambil. Pastikan izin lokasi sudah diberikan.'),
    { enableHighAccuracy: true, timeout: 15000 },
  )
}
function payload() {
  const data = Object.fromEntries(Object.entries(form).map(([key, value]) => [key, value === '' ? null : value]))
  data.images = gallery.value.map((image, index) => ({
    stored_file_id: image.stored_file_id, category: image.category, caption: image.caption || null,
    is_cover: !!image.is_cover, sort_order: index,
  }))
  return data
}
async function save() {
  if (!form.name?.trim()) return showError('Nama customer wajib diisi.')
  if (isMaster.value && !form.tenant_id) return showError('Tenant wajib dipilih.')
  saving.value = true
  try {
    const response = isEdit.value
      ? await updateCustomer(route.params.id, payload())
      : await createCustomer(payload())
    showSuccess(`Customer berhasil ${isEdit.value ? 'diperbarui' : 'didaftarkan'}.`)
    router.replace(`/customers/orders/${response?.data?.id || route.params.id}/edit`)
    if (!isEdit.value) await initialize()
  } catch (error) { showError(error?.response?.data?.message || 'Gagal menyimpan customer.') }
  finally { saving.value = false }
}
onMounted(initialize)
</script>

<template>
  <div class="customer-form-page">
    <div class="customer-page-header">
      <div>
        <CButton color="secondary" variant="ghost" size="sm" @click="router.push('/customers/orders')">&larr; Kembali</CButton>
        <h4 class="mb-1 mt-1">{{ isEdit ? 'Lengkapi Data Customer' : 'Registrasi Customer' }}</h4>
        <p class="text-body-secondary mb-0">Identitas, lokasi pemasangan, layanan, dan dokumentasi customer.</p>
      </div>
      <CButton color="primary" size="sm" :disabled="loading || saving || uploading" @click="save">
        {{ saving ? 'Menyimpan...' : 'Simpan Customer' }}
      </CButton>
    </div>
    <div v-if="loading" class="form-loading"><CSpinner color="primary" /><span>Memuat data...</span></div>
    <CRow v-else class="g-3">
      <CCol :xl="8">
        <CCard class="form-card mb-3"><CCardHeader><strong>Informasi Customer</strong></CCardHeader><CCardBody>
          <CRow class="g-3">
            <CCol v-if="isMaster" :md="6"><CFormLabel>Tenant</CFormLabel><CFormSelect v-model="form.tenant_id"><option value="">Pilih tenant</option><option v-for="x in tenants" :key="x.id" :value="x.id">{{ x.tenant_name }}</option></CFormSelect></CCol>
            <CCol :md="6"><CFormLabel>ID Customer</CFormLabel><CFormInput v-model="form.customer_code" placeholder="Dibuat otomatis jika kosong" /></CCol>
            <CCol :md="6"><CFormLabel>Nama Lengkap</CFormLabel><CFormInput v-model="form.name" /></CCol>
            <CCol :md="6"><CFormLabel>NIK/Identitas</CFormLabel><CFormInput v-model="form.identity_number" /></CCol>
            <CCol :md="6"><CFormLabel>Email</CFormLabel><CFormInput v-model="form.email" type="email" /></CCol>
            <CCol :md="6"><CFormLabel>WhatsApp</CFormLabel><CFormInput v-model="form.whatsapp_number" /></CCol>
          </CRow>
        </CCardBody></CCard>

        <CCard class="form-card mb-3"><CCardHeader><strong>Lokasi Pemasangan</strong></CCardHeader><CCardBody>
          <CRow class="g-3">
            <CCol :xs="12"><CFormLabel>Alamat</CFormLabel><CFormTextarea v-model="form.installation_address" rows="2" /></CCol>
            <CCol :md="6" :xl="3"><CFormLabel>Provinsi</CFormLabel><CFormSelect v-model="form.provinsi_id" @change="onProvinsiChange"><option value="">Pilih</option><option v-for="x in provinsi" :key="x.id" :value="x.id">{{ x.nama }}</option></CFormSelect></CCol>
            <CCol :md="6" :xl="3"><CFormLabel>Kabupaten</CFormLabel><CFormSelect v-model="form.kabupaten_id" @change="onKabupatenChange"><option value="">Pilih</option><option v-for="x in kabupaten" :key="x.id" :value="x.id">{{ x.nama }}</option></CFormSelect></CCol>
            <CCol :md="6" :xl="3"><CFormLabel>Kecamatan</CFormLabel><CFormSelect v-model="form.kecamatan_id" @change="onKecamatanChange"><option value="">Pilih</option><option v-for="x in kecamatan" :key="x.id" :value="x.id">{{ x.nama }}</option></CFormSelect></CCol>
            <CCol :md="6" :xl="3"><CFormLabel>Desa</CFormLabel><CFormSelect v-model="form.desa_id"><option value="">Pilih</option><option v-for="x in desa" :key="x.id" :value="x.id">{{ x.nama }}</option></CFormSelect></CCol>
          </CRow>
          <div class="map-shell mt-3">
            <CustomerLocationMap
              v-model:latitude="form.latitude"
              v-model:longitude="form.longitude"
            />
            <div class="map-coordinates">
              <div><CFormLabel>Latitude</CFormLabel><CFormInput v-model="form.latitude" type="number" step="any" /></div>
              <div><CFormLabel>Longitude</CFormLabel><CFormInput v-model="form.longitude" type="number" step="any" /></div>
              <CButton color="primary" variant="outline" @click="useCurrentLocation">Gunakan Lokasi Saya</CButton>
            </div>
          </div>
        </CCardBody></CCard>

        <CCard class="form-card"><CCardHeader class="d-flex justify-content-between"><strong>Dokumentasi Lokasi</strong><small>{{ gallery.length }}/20 gambar</small></CCardHeader><CCardBody>
          <div class="gallery-main">
            <img :src="activeImage?.url || '/customer-default.svg'" alt="Dokumentasi customer" class="image-previewable" />
            <div v-if="activeImage" class="gallery-overlay"><CBadge color="primary">{{ categoryOptions.find(([value]) => value === activeImage.category)?.[1] }}</CBadge><span>{{ activeImage.caption || activeImage.original_name }}</span></div>
          </div>
          <div class="gallery-thumbnails">
            <button v-for="(image, index) in gallery" :key="image.uuid" type="button" class="gallery-thumb" :class="{ active: index === selectedImage }" @click="selectedImage = index">
              <img :src="image.url" :alt="image.original_name" /><span v-if="image.is_cover">Cover</span>
            </button>
            <button type="button" class="gallery-add" :disabled="uploading || gallery.length >= 20" @click="fileInput?.click()"><strong>+</strong><span>{{ uploading ? 'Upload...' : 'Tambah' }}</span></button>
            <input ref="fileInput" type="file" accept="image/*" multiple hidden @change="addImages" />
          </div>
          <CRow v-if="activeImage" class="g-2 mt-2 align-items-end">
            <CCol :md="4"><CFormLabel>Kategori</CFormLabel><CFormSelect v-model="activeImage.category"><option v-for="[value, label] in categoryOptions" :key="value" :value="value">{{ label }}</option></CFormSelect></CCol>
            <CCol :md="5"><CFormLabel>Keterangan</CFormLabel><CFormInput v-model="activeImage.caption" /></CCol>
            <CCol :md="3" class="d-flex gap-2"><CButton color="primary" variant="outline" class="flex-fill" @click="setCover(selectedImage)">Jadikan Cover</CButton><CButton color="danger" variant="outline" @click="removeImage(selectedImage)">Hapus</CButton></CCol>
          </CRow>
        </CCardBody></CCard>
      </CCol>

      <CCol :xl="4">
        <div class="customer-sidebar">
          <CCard class="form-card mb-3"><CCardHeader><strong>Layanan Customer</strong></CCardHeader><CCardBody class="d-grid gap-3">
            <div><CFormLabel>Profile Paket</CFormLabel><CFormSelect v-model="form.package_profile_id"><option value="">Pilih profile paket</option><option v-for="x in tenantProfiles" :key="x.id" :value="x.id">{{ x.name }}</option></CFormSelect></div>
            <div><CFormLabel>NAS Mikrotik</CFormLabel><CFormSelect v-model="form.nas_mikrotik_id"><option value="">Pilih NAS</option><option v-for="x in tenantNas" :key="x.id" :value="x.id">{{ x.name }}</option></CFormSelect></div>
            <div><CFormLabel>Profile Tagihan</CFormLabel><CFormSelect v-model="form.billing_profile_id"><option value="">Pilih profile tagihan</option><option v-for="x in tenantBillingProfiles" :key="x.id" :value="x.id">{{ x.name }}</option></CFormSelect></div>
            <div><CFormLabel>Username Eksternal</CFormLabel><CFormInput v-model="form.external_username" /></div>
            <div><CFormLabel>Tahap Order</CFormLabel><CFormSelect v-model="form.order_stage"><option value="registration">Registrasi</option><option value="data_completion">Melengkapi Data</option><option value="ready_activation">Siap Aktivasi</option><option value="activation_failed">Aktivasi Gagal</option></CFormSelect></div>
            <div><CFormLabel>Catatan</CFormLabel><CFormTextarea v-model="form.notes" rows="4" /></div>
          </CCardBody></CCard>
          <CButton color="primary" class="w-100 save-mobile" :disabled="saving || uploading" @click="save">{{ saving ? 'Menyimpan...' : 'Simpan Customer' }}</CButton>
        </div>
      </CCol>
    </CRow>
  </div>
</template>

<style scoped>
.customer-form-page { padding: 0.5rem; }
.customer-page-header { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.form-loading { min-height: 16rem; display: flex; align-items: center; justify-content: center; gap: 0.75rem; }
.form-card { border: 1px solid var(--cui-border-color); border-radius: 0.85rem; box-shadow: 0 0.2rem 0.7rem rgba(0, 0, 0, 0.04); overflow: hidden; }
.map-shell { overflow: hidden; border: 1px solid var(--cui-border-color); border-radius: 0.75rem; }
.map-coordinates { display: grid; grid-template-columns: 1fr 1fr auto; align-items: end; gap: 0.75rem; padding: 0.75rem; background: var(--cui-tertiary-bg); }
.gallery-main { position: relative; overflow: hidden; aspect-ratio: 16 / 8; border-radius: 0.75rem; background: var(--cui-tertiary-bg); }
.gallery-main img { width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; }
.gallery-overlay { position: absolute; inset: auto 0 0; display: flex; align-items: center; gap: 0.5rem; padding: 1rem; color: white; background: linear-gradient(transparent, rgba(0, 0, 0, 0.75)); }
.gallery-thumbnails { display: flex; gap: 0.6rem; overflow-x: auto; padding: 0.75rem 0 0.25rem; }
.gallery-thumb, .gallery-add { position: relative; width: 5.5rem; height: 4.5rem; flex: 0 0 auto; overflow: hidden; border: 2px solid transparent; border-radius: 0.65rem; background: var(--cui-tertiary-bg); }
.gallery-thumb.active { border-color: var(--cui-primary); }
.gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery-thumb span { position: absolute; right: 0.2rem; bottom: 0.2rem; padding: 0.05rem 0.25rem; border-radius: 0.25rem; color: white; font-size: 0.65rem; background: var(--cui-primary); }
.gallery-add { display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--cui-primary); border-style: dashed; border-color: var(--cui-primary); }
.gallery-add strong { font-size: 1.5rem; line-height: 1; }
.gallery-add span { font-size: 0.72rem; }
.customer-sidebar { position: sticky; top: 5.5rem; }
@media (max-width: 1199.98px) { .customer-sidebar { position: static; } }
@media (max-width: 767.98px) {
  .customer-form-page { padding: 0; }
  .customer-page-header { align-items: flex-start; flex-direction: column; }
  .customer-page-header > button { display: none; }
  .map-coordinates { grid-template-columns: 1fr; }
  .gallery-main { aspect-ratio: 4 / 3; }
  .save-mobile { position: sticky; bottom: 0.5rem; z-index: 5; }
}
</style>
