<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import Swal from 'sweetalert2'
import { useMaterialStore } from '@/stores/materialStore'
import { materialService } from '@/services/materialService'

import MaterialTable from '@/components/materials/MaterialTable.vue'
import MaterialHistory from '@/components/materials/MaterialHistory.vue'
import AssignMaterialModal from '@/components/materials/AssignMaterialModal.vue'
import TransferMaterialModal from '@/components/materials/TransferMaterialModal.vue'
import ReturnMaterialModal from '@/components/materials/ReturnMaterialModal.vue'
import MaterialDetailModal from '@/components/materials/MaterialDetailModal.vue'

const store = useMaterialStore()

const currentTab = ref('user')
const searchBarcode = ref('')
const searchMaterial = ref('')
const selectedUser = ref(null)
const selectedBarcode = ref('')

const currentPage = ref(1)
const perPage = ref(15)

const filterType = ref('')

const assignModal = ref(false)
const transferModal = ref(false)
const returnModal = ref(false)
const detailModal = ref(false)

const saving = ref(false)

const assignForm = reactive({
  user_id: null,
  barcode_id: '',
  material_name: '',
  type: 'serialized',
  serial_number: '',
  qty: 1,
  unit: '',
})

const transferForm = reactive({
  barcode_id: '',
  from_user_id: null,
  to_user_id: null,
})

const returnForm = reactive({
  barcode_id: '',
  user_id: null,
})

const detailItem = ref({})

const filteredMaterials = computed(() => {
  return store.materials.filter((item) => {
    const barcodeMatch =
      !searchBarcode.value ||
      item.barcode_id?.toLowerCase().includes(searchBarcode.value.toLowerCase())

    const materialMatch =
      !searchMaterial.value ||
      item.material_name?.toLowerCase().includes(searchMaterial.value.toLowerCase())

    const userMatch = !selectedUser.value || item.user_id == selectedUser.value

    const typeMatch = !filterType.value || item.type === filterType.value

    return barcodeMatch && materialMatch && userMatch && typeMatch
  })
})

const isFilteringActive = computed(() => {
  return (
    searchBarcode.value !== '' ||
    searchMaterial.value !== '' ||
    selectedUser.value !== null ||
    filterType.value !== ''
  )
})

const currentMaterialsSource = computed(() => {
  return isFilteringActive.value ? filteredMaterials.value : store.materials
})

const totalPages = computed(() => Math.ceil(currentMaterialsSource.value.length / perPage.value))

const paginatedMaterials = computed(() => {
  const start = (currentPage.value - 1) * perPage.value
  return currentMaterialsSource.value.slice(start, start + perPage.value)
})

const assignedMaterial = computed(
  () => store.materials.filter((i) => i.status === 'Assigned').length,
)
const returnedMaterial = computed(
  () => store.materials.filter((i) => i.status === 'Returned').length,
)
const serializedMaterial = computed(
  () => store.materials.filter((i) => i.type === 'serialized').length,
)
const consumableMaterial = computed(
  () => store.materials.filter((i) => i.type === 'consumable').length,
)

const totalMaterial = computed(() => store.materials.length)

watch(searchBarcode, () => {
  currentPage.value = 1
})
watch(searchMaterial, () => {
  currentPage.value = 1
})
watch(filterType, () => {
  currentPage.value = 1
})

watch([selectedUser], async ([newSelectedUser]) => {
  currentPage.value = 1
  if (newSelectedUser) {
    await store.fetchByUser(newSelectedUser)
  } else {
    await store.fetchAll()
  }
})

watch(selectedBarcode, async (val) => {
  if (val) await store.fetchHistory(val)
})

onMounted(() => {
  store.fetchAll()
})

function openTransferModal(item) {
  transferForm.barcode_id = item.barcode_id
  transferForm.from_user_id = item.user_id
  transferForm.to_user_id = null
  transferModal.value = true
}

function openReturnModal(item) {
  returnForm.barcode_id = item.barcode_id
  returnForm.user_id = item.user_id
  returnModal.value = true
}

function openDetail(item) {
  detailItem.value = { ...item }
  detailModal.value = true
}

async function assignMaterial() {
  saving.value = true
  try {
    await materialService.assign({
      ...assignForm,
      qty: Number(assignForm.qty),
    })
    assignModal.value = false
    Swal.fire({
      icon: 'success',
      title: 'Berhasil',
      text: 'Material berhasil di-assign',
      timer: 1500,
      showConfirmButton: false,
    })
    const userId = selectedUser.value || assignForm.user_id
    if (userId) {
      selectedUser.value = userId
      await store.fetchByUser(userId)
    } else {
      await store.fetchAll()
    }
    assignForm.barcode_id = ''
    assignForm.user_id = null
    assignForm.material_name = ''
    assignForm.type = 'serialized'
    assignForm.serial_number = ''
    assignForm.qty = 1
    assignForm.unit = ''
  } catch (err) {
    Swal.fire({ icon: 'error', title: 'Gagal', text: err.response?.data?.message || err.message })
  } finally {
    saving.value = false
  }
}

async function transferMaterial() {
  const confirm = await Swal.fire({
    title: 'Transfer Material?',
    text: 'Pastikan user tujuan sudah benar.',
    icon: 'question',
    showCancelButton: true,
    confirmButtonText: 'Transfer',
    cancelButtonText: 'Batal',
  })
  if (!confirm.isConfirmed) return

  saving.value = true
  try {
    await materialService.transfer({ ...transferForm })
    transferModal.value = false
    Swal.fire({
      icon: 'success',
      title: 'Berhasil',
      text: 'Material berhasil dipindahkan',
      timer: 1500,
      showConfirmButton: false,
    })
    if (selectedUser.value) {
      await store.fetchByUser(selectedUser.value)
    } else {
      await store.fetchAll()
    }
    if (selectedBarcode.value) await store.fetchHistory(selectedBarcode.value)
  } catch (err) {
    Swal.fire({ icon: 'error', title: 'Gagal', text: err.response?.data?.message || err.message })
  } finally {
    saving.value = false
  }
}

async function returnMaterial() {
  const confirm = await Swal.fire({
    title: 'Return Material?',
    text: 'Material akan dikembalikan.',
    icon: 'warning',
    showCancelButton: true,
    confirmButtonText: 'Ya',
  })
  if (!confirm.isConfirmed) return

  saving.value = true
  try {
    await materialService.returnMaterial({ ...returnForm })
    returnModal.value = false
    Swal.fire({
      icon: 'success',
      title: 'Berhasil',
      text: 'Material berhasil dikembalikan',
      timer: 1500,
      showConfirmButton: false,
    })
    if (selectedUser.value) {
      await store.fetchByUser(selectedUser.value)
    } else {
      await store.fetchAll()
    }
    if (selectedBarcode.value) await store.fetchHistory(selectedBarcode.value)
  } catch (err) {
    Swal.fire({ icon: 'error', title: 'Gagal', text: err.response?.data?.message || err.message })
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <CRow>
    <CCol :xs="12">
      <CCard class="mb-4">
        <CCardHeader class="d-flex justify-content-between align-items-center">
          <div>
            <strong>Material Management</strong>
            <div class="small text-body-secondary">
              Assign, Transfer, Return dan History Material
            </div>
          </div>
          <CButton color="primary" @click="assignModal = true">+ Tambah Material</CButton>
        </CCardHeader>

        <CCardBody>
          <CRow class="mb-4">
            <CCol md
              ><CCard class="border-start border-primary border-4"
                ><CCardBody
                  ><div>Total Material</div>
                  <h3>{{ totalMaterial }}</h3></CCardBody
                ></CCard
              ></CCol
            >
            <CCol md
              ><CCard class="border-start border-success border-4"
                ><CCardBody
                  ><div>Assigned</div>
                  <h3>{{ assignedMaterial }}</h3></CCardBody
                ></CCard
              ></CCol
            >
            <CCol md
              ><CCard class="border-start border-secondary border-4"
                ><CCardBody
                  ><div>Returned</div>
                  <h3>{{ returnedMaterial }}</h3></CCardBody
                ></CCard
              ></CCol
            >
            <CCol md
              ><CCard class="border-start border-info border-4"
                ><CCardBody
                  ><div>Serialized</div>
                  <h3>{{ serializedMaterial }}</h3></CCardBody
                ></CCard
              ></CCol
            >
            <CCol md
              ><CCard class="border-start border-warning border-4"
                ><CCardBody
                  ><div>Consumable</div>
                  <h3>{{ consumableMaterial }}</h3></CCardBody
                ></CCard
              ></CCol
            >
          </CRow>

          <CTabs :active-item-key="currentTab" @change="(key) => (currentTab = key)">
            <CTabList variant="tabs">
              <CTab item-key="user">Material User</CTab>
              <CTab item-key="history">History</CTab>
            </CTabList>

            <CTabPanel item-key="user" class="mt-4">
              <CRow class="mb-3">
                <CCol md="3"
                  ><CFormLabel>Barcode</CFormLabel><CFormInput v-model="searchBarcode"
                /></CCol>
                <CCol md="3"
                  ><CFormLabel>Material</CFormLabel><CFormInput v-model="searchMaterial"
                /></CCol>
                <CCol md="2">
                  <CFormLabel>Type</CFormLabel>
                  <CFormSelect v-model="filterType">
                    <option value="">Semua Type</option>
                    <option value="serialized">Serialized</option>
                    <option value="consumable">Consumable</option>
                  </CFormSelect>
                </CCol>
                <CCol md="2">
                  <CFormLabel>User ID</CFormLabel>
                  <CFormInput v-model="selectedUser" placeholder="Filter by User ID" />
                </CCol>
                <CCol md="2" class="d-flex align-items-end">
                  <CButton
                    color="secondary"
                    @click="
                      ((searchBarcode = ''),
                      (searchMaterial = ''),
                      (selectedUser = null),
                      (filterType = ''))
                    "
                    >Reset</CButton
                  >
                </CCol>
              </CRow>

              <MaterialTable
                :data="paginatedMaterials"
                :totalPages="totalPages"
                :currentPage="currentPage"
                :perPage="perPage"
                :totalItems="currentMaterialsSource.length"
                :loading="store.loading"
                @update:perPage="
                  (val) => {
                    perPage = val
                    currentPage = 1
                  }
                "
                @page="(p) => (currentPage = p)"
                @detail="openDetail"
                @transfer="openTransferModal"
                @return="openReturnModal"
              />
            </CTabPanel>

            <CTabPanel item-key="history" class="mt-4">
              <CRow class="mb-3">
                <CCol md="4">
                  <CFormLabel>Barcode</CFormLabel>
                  <CFormInput v-model="selectedBarcode" placeholder="Masukkan Barcode" />
                </CCol>
                <CCol md="2" class="d-flex align-items-end">
                  <CButton color="primary" @click="store.fetchHistory(selectedBarcode)"
                    >Lihat History</CButton
                  >
                </CCol>
              </CRow>

              <MaterialHistory :histories="store.histories" />
            </CTabPanel>
          </CTabs>
        </CCardBody>
      </CCard>
    </CCol>
  </CRow>

  <AssignMaterialModal
    :visible="assignModal"
    :form="assignForm"
    :saving="saving"
    @close="assignModal = false"
    @save="assignMaterial"
  />

  <TransferMaterialModal
    :visible="transferModal"
    :form="transferForm"
    :saving="saving"
    @close="transferModal = false"
    @save="transferMaterial"
  />

  <ReturnMaterialModal
    :visible="returnModal"
    :form="returnForm"
    :saving="saving"
    @close="returnModal = false"
    @save="returnMaterial"
  />

  <MaterialDetailModal
    :visible="detailModal"
    :item="detailItem"
    @close="detailModal = false"
    @transfer="openTransferModal"
    @return="openReturnModal"
  />
</template>
