<template>
  <div class="subscription-plan">
    <a-card class="search-card" :bordered="false">
      <a-form
        class="search-form"
        layout="inline"
        :model="searchForm"
        :label-col="{ style: { width: '12rem' } }"
        :wrapper-col="{ style: { width: '22rem' } }"
      >
        <a-form-item label="ID">
          <a-input v-model:value="searchForm.id" allow-clear placeholder="Input the id" />
        </a-form-item>
        <a-form-item label="Name">
          <a-input
            v-model:value="searchForm.name"
            allow-clear
            placeholder="Input the name"
          />
        </a-form-item>
        <a-form-item label="Time Range">
          <a-range-picker
            v-model:value="searchForm.dateRange"
            value-format="X"
            allow-clear
          />
        </a-form-item>
        <a-form-item label="Organization">
          <a-select
            v-model:value="searchForm.organizationId"
            allow-clear
            placeholder="Select Organization"
            style="width: 180px"
            @popupScroll="handleOrganizationScroll"
          >
            <a-select-option
              v-for="item in organizationOptions"
              :key="item.id"
              :value="item.id"
            >
              {{ item.name }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="Admin Account">
          <a-select
            v-model:value="searchForm.adminAccId"
            allow-clear
            show-search
            :filter-option="filterOption"
            placeholder="Select Account"
            style="width: 180px"
            :options="allUserList"
          ></a-select>
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button type="primary" @click="handleSearch">Search</a-button>
            <a-button @click="handleReset">Reset</a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-card>

    <a-card class="table-card" :bordered="false">
      <div class="table-card__header">
        <div class="table-card__title">Subscription Plan</div>
        <a-button type="primary" @click="openCreate">New Subscription Plan</a-button>
      </div>
      <a-table
        :data-source="tableData"
        :columns="columns"
        :loading="tableLoading"
        row-key="id"
        :pagination="{
          showSizeChanger: true,
          current: searchForm.page,
          pageSize: searchForm.size,
          total: searchForm.total,
          showQuickJumper: true,
          bordered: false
        }"
      >
        <template #bodyCell="{ column, record }">
          <template
            v-if="
              column.key === 'currentPeriodStart' || column.key === 'currentPeriodEnd'
            "
          >
            {{ formatTime(record[column.key], 'YYYY-MM-DD hh:mm:ss') }}
          </template>
          <!-- <template v-if="column.key === 'organizationId'">
            {{ organizationOptions.find(item => item.id === record[column.key]).name }}
          </template> -->

          <template v-if="column.key === 'status'">
            <a-tag :color="statusColorMap[record.status]">
              {{ statusLabelMap[record.status] }}
            </a-tag>
          </template>
          <template v-if="column.key === 'adminAccId'">
            {{ allUserList.find(item => item.value === record.adminAccId)?.label }}
          </template>

          <template v-else-if="column.key === 'actions'">
            <a-space>
              <a @click="openEdit(record)">Edit</a>
              <a-popconfirm
                title="Confirm to delete this subscription plan?"
                ok-text="Confirm"
                cancel-text="Cancel"
                @confirm="removePlan(record.id)"
              >
                <a class="danger-text">Delete</a>
              </a-popconfirm>
            </a-space>
          </template>
        </template>
      </a-table>
    </a-card>

    <div class="subscriptionPlanModal" ref="subscriptionPlanModal"></div>
    <a-modal
      class="subscriptionPlan_modal generalModel"
      v-model:visible="modalVisible"
      :footer="null"
      :get-container="() => $refs.subscriptionPlanModal"
      width="50%"
      :maskClosable="false"
      :centered="true"
      :closable="false"
      :mask="true"
      wrapClassName="#app"
      :keyboard="false"
      destroy-on-close
    >
      <div class="generalModel_btn">
        <div class="generalModel_closeIcon" @click.stop="cancelModal">
          <svg
            width="100%"
            height="100%"
            viewBox="0 0 46 46"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <circle cx="23" cy="23" r="23" fill="#000" fill-opacity="0.3" />
            <rect
              x="32.5063"
              y="12"
              width="3"
              height="29"
              rx="1.5"
              transform="rotate(45 32.5063 12)"
              fill="white"
            />
            <rect
              x="34.6274"
              y="32.5059"
              width="3"
              height="29"
              rx="1.5"
              transform="rotate(135 34.6274 32.5059)"
              fill="white"
            />
          </svg>
        </div>
      </div>
      <div class="modal_title_text">
        <div>{{ modalTitle }}</div>
      </div>
      <div class="subscriptionPlan_center admin_page">
        <div class="form_content">
          <div class="admin_state_item">
            <span>
              Name:
              <span>*</span>
            </span>
            <a-input
              v-model:value="formState.name"
              placeholder="Input the name"
              style="width: 250px"
              :disabled="isEditMode"
            />
          </div>
          <div class="admin_state_item">
            <span>
              Organization:
              <span>*</span>
            </span>
            <a-select
              v-model:value="formState.organizationId"
              placeholder="Select the organization"
              allow-clear
              style="width: 250px"
              @popupScroll="handleOrganizationScroll"
              :disabled="isEditMode"
            >
              <a-select-option
                v-for="item in organizationOptions"
                :key="item.id"
                :value="item.id"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>
          </div>
          <div class="admin_state_item">
            <span>
              Admin Account:
              <span>*</span>
            </span>
            <a-select
              v-model:value="formState.adminAccId"
              placeholder="Select the admin account"
              allow-clear
              show-search
              :filter-option="filterOption"
              style="width: 250px"
              :options="allUserList"
            ></a-select>
          </div>
          <div class="admin_state_item">
            <span>
              Start Time:
              <span>*</span>
            </span>
            <a-date-picker
              v-model:value="formState.currentPeriodStart"
              value-format="X"
              style="width: 250px"
              class="range_picker"
              placeholder="Select the start time"
            >
              <template #suffixIcon>
                <span class="icon iconfont range_picker_icon icon-rili"></span>
              </template>
            </a-date-picker>
          </div>
          <div class="admin_state_item">
            <span>
              End Time:
              <span>*</span>
            </span>
            <a-date-picker
              v-model:value="formState.currentPeriodEnd"
              value-format="X"
              style="width: 250px"
              class="range_picker"
              placeholder="Select the end time"
            >
              <template #suffixIcon>
                <span class="icon iconfont range_picker_icon icon-rili"></span>
              </template>
            </a-date-picker>
          </div>
          <div class="admin_state_item">
            <span>
              Account Num:
              <span>*</span>
            </span>
            <a-input-number
              v-model:value="formState.accountNum"
              :min="0"
              style="width: 250px"
              placeholder="Input the account number"
            />
          </div>
          <div class="admin_state_item">
            <span>
              Credit Limit:
              <span>*</span>
            </span>
            <a-input-number
              v-model:value="formState.creditLimit"
              :min="0"
              style="width: 250px"
              placeholder="Input the credit limit"
            />
          </div>
        </div>
      </div>
      <div class="subscriptionPlan_btn admin_page">
        <div class="admin_search_item" @click="cancelModal">Close</div>
        <div class="admin_search_item" @click="handleSubmit">OK</div>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, computed } from 'vue'
import { message } from 'ant-design-vue'
import { Https } from '@/tool/https'
import { formatTime } from '@/tool/util'
import store from '@/store'
import type { FormInstance, Rule } from 'ant-design-vue/es/form'

type PlanStatus = 'active' | 'paused' | 'ended'
interface SubscriptionPlan {
  id: number
  name: string
  currentPeriodStart: string
  currentPeriodEnd: string
  organizationId: string
  adminAccId: string
  status: PlanStatus
  creditLimit: number
  accountNum?: number
  startStamp: number
  endStamp: number
}

const searchForm = reactive({
  name: '',
  startTime: '',
  endTime: '',
  organizationId: undefined as string | undefined,
  adminAccId: undefined as string | undefined,
  id: '',
  page: 1,
  size: 10,
  total: 0
})

const toSeconds = (dateStr: string) => Math.floor(new Date(dateStr).getTime() / 1000)

const tableData = ref<SubscriptionPlan[]>([])
const tableLoading = ref(false)

const modalVisible = ref(false)
const confirmLoading = ref(false)
const modalTitle = ref('New Subscription Plan')
const isEditMode = ref(false)
const formState = reactive({
  name: '',
  currentPeriodStart: '',
  currentPeriodEnd: '',
  organizationId: undefined as string | undefined,
  adminAccId: undefined as string | undefined,
  creditLimit: null as number | null,
  accountNum: null as number | null
})

const statusLabelMap: Record<PlanStatus, string> = {
  active: 'Active',
  paused: 'Paused',
  ended: 'Ended'
}
const statusColorMap: Record<PlanStatus, string> = {
  active: 'green',
  paused: 'orange',
  ended: 'red'
}

const columns = [
  { title: 'Name', dataIndex: 'name', key: 'name' },
  { title: 'ID', dataIndex: 'id', key: 'id' },
  { title: 'Organization', dataIndex: 'organizationName', key: 'organizationName' },
  { title: 'Admin Account', dataIndex: 'adminAccId', key: 'adminAccId' },
  { title: 'Account Num', dataIndex: 'accountNum', key: 'accountNum' },
  {
    title: 'Start Time',
    dataIndex: 'currentPeriodStart',
    key: 'currentPeriodStart'
  },
  {
    title: 'End Time',
    dataIndex: 'currentPeriodEnd',
    key: 'currentPeriodEnd'
  },
  { title: 'Status', dataIndex: 'status', key: 'status' },
  { title: 'Credit Limit', dataIndex: 'creditLimit', key: 'creditLimit' },
  { title: 'Operations', key: 'actions', width: 160 }
]
onMounted(async () => {
  await getOrganizationList()
  await handleSearch()
})

const handleFetchTableData = async () => {
  tableLoading.value = true
  return Https.axiosPost(Https.httpUrls.searchAllSubscribePlan, searchForm)
    .then(res => {
      tableData.value = res.records.map(item => {
        const organization = organizationOptions.value.find(
          el => el.id === item.organizationId
        ) || { name: '' }
        return {
          ...item,
          organizationName: organization.name || ''
        }
        debugger
      })
      searchForm.total = res.total
    })
    .finally(() => {
      tableLoading.value = false
    })
}

const resetFormState = () => {
  formState.name = ''
  formState.currentPeriodStart = ''
  formState.currentPeriodEnd = ''
  formState.organizationId = undefined
  formState.adminAccId = undefined
  formState.creditLimit = null
  formState.accountNum = null
}

const handleSearch = () => {
  searchForm.page = 1
  handleFetchTableData()
}

const handleReset = () => {
  searchForm.name = ''
  searchForm.startTime = ''
  searchForm.endTime = ''
  searchForm.organizationId = undefined
  searchForm.adminAccId = undefined
  searchForm.id = ''
  handleSearch()
}

const allUserList = computed(() => {
  return store.state.adminPage.allUserList
})
const openCreate = () => {
  modalTitle.value = 'New Subscription Plan'
  isEditMode.value = false
  resetFormState()
  modalVisible.value = true
}

const openEdit = (record: SubscriptionPlan) => {
  modalTitle.value = 'Edit Subscription Plan'
  isEditMode.value = true
  formState.name = record.name
  formState.currentPeriodStart = record.currentPeriodStart
  formState.currentPeriodEnd = record.currentPeriodEnd
  formState.organizationId = record.organizationId
  formState.adminAccId = record.adminAccId
  formState.creditLimit = record.creditLimit
  formState.accountNum = (record as any).accountNum || null
  modalVisible.value = true
}

const validateForm = (): boolean => {
  interface FieldRule {
    value: any
    message: string
    checkNull?: boolean
  }

  const requiredFields: FieldRule[] = [
    { value: formState.currentPeriodStart, message: 'Please select the start time' },
    { value: formState.currentPeriodEnd, message: 'Please select the end time' },
    { value: formState.adminAccId, message: 'Please select the admin account' },
    {
      value: formState.creditLimit,
      message: 'Please input credit limit',
      checkNull: true
    },
    {
      value: formState.accountNum,
      message: 'Please input account number',
      checkNull: true
    }
  ]

  if (!isEditMode.value) {
    requiredFields.push(
      { value: formState.name, message: 'Please input the name' },
      { value: formState.organizationId, message: 'Please select organization' }
    )
  }

  for (const field of requiredFields) {
    const isEmpty = field.checkNull
      ? field.value === null || field.value === undefined
      : !field.value
    if (isEmpty) {
      message.warning(field.message)
      return false
    }
  }

  return true
}

const handleSubmit = async () => {
  if (!validateForm()) return
  confirmLoading.value = true
  const params = {
    ...formState,
    currentPeriodStart: Number(formState.currentPeriodStart),
    currentPeriodEnd: Number(formState.currentPeriodEnd)
  }
  let res = null
  try {
    if (isEditMode.value) {
      res = await Https.axiosPost(Https.httpUrls.updateSubscribePlan, params)
    } else {
      res = await Https.axiosPost(Https.httpUrls.createSubscribePlan, params)
    }
    message.success(
      `${isEditMode.value ? 'Subscription plan updated' : 'Subscription plan created'}`
    )
  } catch (error: any) {
    message.error(error.message)
    console.error(error)
  } finally {
    confirmLoading.value = false
    modalVisible.value = false
    resetFormState()
    isEditMode.value = false
    handleSearch()
  }
}

const cancelModal = () => {
  modalVisible.value = false
  resetFormState()
  isEditMode.value = false
}

const removePlan = (id: number) => {
  tableLoading.value = true
  Https.axiosGet(Https.httpUrls.deleteSubscribePlan, { params: { id } })
    .then(res => {
      message.success('Subscription plan deleted')
      handleReset()
    })
    .catch((error: any) => {
      message.error(error.message)
      console.error(error)
    })
    .finally(() => {
      tableLoading.value = false
    })
}

const organizationOptions = ref([])
const organizationParams = reactive({
  page: 1,
  size: 10,
  total: 0
})
const organizationLoading = ref(false)
const getOrganizationList = async (isLoadMore = false) => {
  if (organizationLoading.value) return
  if (isLoadMore) {
    const loaded = organizationParams.page * organizationParams.size
    if (organizationParams.total && loaded >= organizationParams.total) return
    organizationParams.page += 1
  } else {
    organizationParams.page = 1
    organizationOptions.value = []
  }
  organizationLoading.value = true
  try {
    const rv: any = await Https.axiosPost(
      Https.httpUrls.queryOrganization,
      organizationParams
    )
    if (rv) {
      organizationOptions.value = [...organizationOptions.value, ...(rv.records || [])]
      organizationParams.total = rv.total || 0
    }
  } finally {
    organizationLoading.value = false
  }
}
const handleOrganizationScroll = (e: any) => {
  const target = e?.target
  if (!target) return
  const nearBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 20
  if (nearBottom) {
    getOrganizationList(true)
  }
}
const filterOption = (input: string, option: any) => {
  const label = option?.label ?? option?.children ?? option?.key?.label ?? ''
  return String(label).toLowerCase().includes(input.toLowerCase())
}
</script>

<style lang="less" scoped>
.subscription-plan {
  padding: 20px 24px 32px 0;

  .search-card {
    margin-bottom: 16px;
  }

  .table-card {
    .table-card__header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 12px;

      .table-card__title {
        font-size: 18px;
        font-weight: 500;
      }
    }

    .danger-text {
      color: #ff4d4f;
    }
  }
}
</style>

<style lang="less" scoped>
:deep(.subscriptionPlan_modal) {
  .ant-modal-body {
    height: calc(65rem * 1.2);
    display: flex;
    flex-direction: column;
    padding: 2.5rem 3rem;
    position: relative;
  }
}

.subscriptionPlan_modal {
  > .admin_state_item {
    > span {
      width: 15rem;
    }
  }
  .modal_title_text {
    margin-bottom: 2rem;
    flex-shrink: 0;
  }
  .subscriptionPlan_center {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    padding: 2rem 0;
  }
  .subscriptionPlan_btn {
    display: flex;
    flex-direction: row;
    height: auto;
    justify-content: flex-end;
    padding: 1.5rem 0 0 0;
    margin-top: auto;
    flex-shrink: 0;
    .admin_search_item {
      margin-bottom: 0;
    }
  }
}

:deep(.search-form) {
  column-gap: 2rem;
  row-gap: 2rem;
  .ant-select {
    width: 100% !important;
  }
}
</style>
