<template>
  <div class="h-full">
    <SimpleScrollbar>
      <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
        <ACard
          :title="t('page.package.title')"
          :bordered="false"
          :body-style="{ flex: 1, overflow: 'hidden' }"
          class="flex-col-stretch sm:flex-1-hidden card-wrapper"
        >
          <template #extra>
            <div class="flex items-center gap-2">
              <TableHeaderOperation
                v-model:columns="columnChecks"
                :loading="loading"
                :show-delete="false"
                @add="handleAdd"
                @refresh="getData"
              />
            </div>
          </template>
          <ATable
            ref="wrapperEl"
            :columns="columns"
            :data-source="data"
            :loading="loading"
            row-key="id"
            size="small"
            :pagination="mobilePagination"
            :scroll="scrollConfig"
            class="h-full"
          />
        </ACard>
      </div>
    </SimpleScrollbar>

    <!-- 新增套餐弹窗 -->
    <AModal
      v-model:open="showModal"
      :title="t('page.package.add')"
      @ok="handleOk"
      @cancel="handleCancel"
      width="600px"
    >
      <AForm
        ref="formRef"
        :model="formState"
        :rules="rules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <AFormItem :label="t('page.package.packagename')" name="packageName">
          <AInput v-model:value="formState.packageName" :placeholder="t('page.package.plepackagename')" />
        </AFormItem>

        <AFormItem :label="t('page.package.period')" required>
          <div class="flex gap-2">
            <AFormItem name="periodNum" class="mb-0 flex-1">
              <AInputNumber
                v-model:value="formState.periodNum"
                :placeholder="t('page.package.pleperiod')"
                :min="1"
                style="width: 100%"
              />
            </AFormItem>
            <AFormItem name="periodType" class="mb-0 flex-1">
              <ASelect v-model:value="formState.periodType" :options="periodOptions" />
            </AFormItem>
          </div>
        </AFormItem>

        <AFormItem :label="t('page.package.price')" name="price" :rules="[{ required: true, message: t('page.package.pleprice') }]">
          <AInputNumber
            v-model:value="formState.price"
            :placeholder="t('page.package.pleprice')"
            :min="0.01"
            :precision="2"
            style="width: 100%"
            :addon-before="currencyStore.symbol"
          />
        </AFormItem>

        <AFormItem :label="t('page.package.traffic')" name="traffic">
          <div class="flex items-center gap-4">
            <ASwitch v-model:checked="formState.trafficEnable" />
            <div v-if="formState.trafficEnable" class="flex gap-2 flex-1">
              <AInputNumber
                v-model:value="formState.traffic"
                :placeholder="t('page.package.pletraffic')"
                :min="1"
                :max="1024"
                :precision="0"
                style="width: 100%"
              />
              <ASelect
                v-model:value="formState.trafficUnit"
                :options="storageUnits.map(unit => ({ label: unit, value: unit }))"
                style="width: 100px"
              />
            </div>
          </div>
        </AFormItem>

        <AFormItem :label="t('page.package.limit')" name="rateLimitId">
          <div class="flex items-center gap-4">
            <ASwitch v-model:checked="formState.rateLimitEnable" />
            <ASelect
              v-if="formState.rateLimitEnable"
              v-model:value="formState.rateLimitId"
              :placeholder="t('page.package.plelimit')"
              :options="rateLimitOptions"
              :loading="!rateLimitOptions.length"
              style="width: 100%"
            />
          </div>
        </AFormItem>

        <AFormItem :label="t('page.package.duration')" name="duration">
          <div class="flex items-center gap-4">
            <ASwitch v-model:checked="formState.durationEnable" />
            <div v-if="formState.durationEnable" class="flex gap-2 flex-1">
              <AInputNumber
                v-model:value="formState.duration"
                :placeholder="t('page.package.pleduration')"
                :min="1"
                style="width: 100%"
              />
              <ASelect
                v-model:value="formState.durationUnit"
                :options="timeUnits.map(item => ({
                label: item.label,
                value: item.key }))"
                style="width: 100px"
              />
            </div>
          </div>
        </AFormItem>

        <AFormItem :label="t('page.package.client')" name="clientNum">
          <div class="flex items-center gap-4">
            <ASwitch v-model:checked="formState.clientNumEnable" />
            <AInputNumber
              v-if="formState.clientNumEnable"
              v-model:value="formState.clientNum"
              :placeholder="t('page.package.pleclient')"
              :min="1"
              :addon-after="t('page.package.unit')"
              style="width: 100%"
            />
          </div>
        </AFormItem>

        <AFormItem :label="t('page.package.usepackage')">
          <ASwitch v-model:checked="formState.packageEnable" />
        </AFormItem>
      </AForm>
    </AModal>
  </div>
</template>

<script setup lang="tsx">
import { useTable } from '@/hooks/common/table';
import { SimpleScrollbar } from '~/packages/materials/src';
import { computed, shallowRef, ref, onMounted } from 'vue';
import { useElementSize } from '@vueuse/core';
import { fetchPackageList, addPackage, fetchRateLimitList, updatePackage, deletePackage } from '@/service/api/auth';
import { Button as AButton, message, Modal, Form as AForm, Input as AInput, InputNumber as AInputNumber, Select as ASelect, Switch as ASwitch, Tag as ATag } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import { useCurrencyStore } from '@/views/billing/rule/modules/currency';
import {
  formatBandwidth,
  formatStorage,
  useFormatTime,
  convertStorage,
  convertTime,
  storageUnits,
  useTimeUnits,
  type StorageUnit,
  type TimeUnit
} from '@/utils/units';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const timeUnits = useTimeUnits();
const formatTime = useFormatTime();
const wrapperEl = shallowRef<HTMLElement | null>(null);
const { height: wrapperElHeight } = useElementSize(wrapperEl);
const currencyStore = useCurrencyStore();

const scrollConfig = computed(() => {
  return {
    y: wrapperElHeight.value - 72,
    x: 1000
  };
});

const periodMap: Record<number, string> = {
  1: t('page.package.day'),
  2: t('page.package.month'),
  3: t('page.package.year')
};

const { columns, columnChecks, data, loading, getData, mobilePagination } = useTable({
  apiFn: async () => {
    try {
      const response = await fetchPackageList();
      return {
        data: {
          rows: response.data || [],
          total: response.data?.length || 0
        }
      };
    } catch (err) {
      return {
        data: {
          rows: [],
          total: 0
        }
      };
    }
  },
  immediate: true,
  rowKey: 'id',
  columns: (): AntDesign.TableColumn<Api.Auth.Package>[] => [
    {
      key: 'packageName',
      dataIndex: 'packageName',
      title: t('page.package.packagename'),
      align: 'center'
    },
    {
      key: 'periodNum',
      dataIndex: 'periodNum',
      title: t('page.package.period'),
      align: 'center',
      customRender: ({ record }) => {
        const { periodNum, periodType } = record;
        const unit = periodMap[periodType as number] || '';
        return `${periodNum}${unit}`;
      }
    },
    {
      key: 'price',
      dataIndex: 'price',
      title: t('page.package.price')+currencyStore.symbol,
      align: 'center',
      customRender: ({ text }) => `${Number(text).toFixed(2)}  ${currencyStore.symbol}`
    },
    {
      key: 'traffic',
      dataIndex: 'traffic',
      title: t('page.package.traffic'),
      align: 'center',
      customRender: ({ text, record }) => {
        if (!record.trafficEnable) return t('page.package.unlimit');
        const { value, unit } = formatStorage(text);
        return `${value} ${unit}`;
      }
    },
    {
      key: 'rateLimitId',
      dataIndex: 'rateLimitId',
      title: t('page.package.limit'),
      align: 'center',
      customRender: ({ record }) => {
        if (!record.rateLimitEnable) return t('page.package.unlimit');
        const rateLimit = rateLimitData.value.find(item => item.id === record.rateLimitId);
        if (!rateLimit) return '-';
        const upLimitText = rateLimit.upLimitEnable
          ? `${t('page.package.up')}:${formatBandwidth(rateLimit.upLimit).value} ${formatBandwidth(rateLimit.upLimit).unit}`
          : `${t('page.package.up')}:${t('page.package.unlimit')}`;
        const downLimitText = rateLimit.downLimitEnable
          ? `${t('page.package.down')}:${formatBandwidth(rateLimit.downLimit).value} ${formatBandwidth(rateLimit.downLimit).unit}`
          : `${t('page.package.down')}:${t('page.package.unlimit')}`;
        return `${rateLimit.rateLimitName} (${upLimitText}/${downLimitText})`;
      }
    },
    {
      key: 'duration',
      dataIndex: 'duration',
      title: t('page.package.duration'),
      align: 'center',
      customRender: ({ text, record }) => {
        if (!record.durationEnable) return t('page.package.unlimit');
        const { value, unit } = formatTime(text);
        return `${value} ${unit}`;
      }
    },
    {
      key: 'clientNum',
      dataIndex: 'clientNum',
      title: t('page.package.client'),
      align: 'center',
      customRender: ({ text, record }) => {
        if (!record.clientNumEnable) return t('page.package.unlimit');
        return text;
      }
    },
    {
      key: 'packageEnable',
      dataIndex: 'packageEnable',
      title: t('page.package.status'),
      align: 'center',
      customRender: ({ text }) => (
        <ATag color={text ? 'success' : 'error'}>
          {text ? t('page.package.use') : t('page.package.unuse')}
        </ATag>
      )
    },
    {
      key: 'operate',
      title: t('page.package.operate'),
      align: 'center',
      width: 200,
      customRender: ({ record }) => (
        <div class="flex justify-center gap-2">
          <AButton type="link" onClick={() => handleEdit(record)}>
            {t('page.package.edit')}
          </AButton>
          <AButton type="link" danger onClick={() => handleDelete(record)}>
            {t('page.package.delete')}
          </AButton>
        </div>
      )
    }
  ]
});

const showModal = ref(false);
const formRef = ref();

interface PackageForm {
  id?: string;
  packageName: string;
  periodNum: number;
  periodType: number;
  price: string;
  trafficEnable: boolean;
  traffic: number;
  trafficUnit: StorageUnit;
  rateLimitEnable: boolean;
  rateLimitId?: number;
  durationEnable: boolean;
  duration: number;
  durationUnit: TimeUnit;
  clientNumEnable: boolean;
  clientNum: number;
  packageEnable: boolean;
}

const formState = ref<PackageForm>({
  packageName: '',
  periodNum: 1,
  periodType: 2,
  price: '',
  trafficEnable: false,
  traffic: 0,
  trafficUnit: 'GB',
  rateLimitEnable: false,
  rateLimitId: undefined,
  durationEnable: false,
  duration: 0,
  durationUnit: 'hour',
  clientNumEnable: false,
  clientNum: 0,
  packageEnable: true
});

const rules: Record<string, Rule[]> = {
  packageName: [{ required: true, message: t('page.package.plepackagename'), trigger: 'blur' }],
  periodNum: [{ required: true, message: t('page.package.pleperiod'), trigger: 'blur' }],
  periodType: [{ required: true, message: t('page.package.pleunit'), trigger: 'change' }],
  price: [{ required: true, message: t('page.package.pleprice'), trigger: 'blur' }],
  traffic: [
    {
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.trafficEnable) return Promise.resolve();
        if (!value || value <= 0) return Promise.reject(t('page.package.rejtraffic'));
        return Promise.resolve();
      },
      trigger: 'blur'
    }
  ],
  rateLimitId: [
    {
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.rateLimitEnable) return Promise.resolve();
        if (!value) return Promise.reject(t('page.package.plelimit'));
        return Promise.resolve();
      },
      trigger: 'change'
    }
  ],
  duration: [
    {
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.durationEnable) return Promise.resolve();
        if (!value || value <= 0) return Promise.reject(t('page.package.rejduration'));
        return Promise.resolve();
      },
      trigger: 'blur'
    }
  ],
  clientNum: [
    {
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.clientNumEnable) return Promise.resolve();
        if (!value || value <= 0) return Promise.reject(t('page.package.rejclient'));
        return Promise.resolve();
      },
      trigger: 'blur'
    }
  ]
};

const periodOptions =computed(()=> [
  { label: t('page.package.hour'), value: 0 },
  { label: t('page.package.day'), value: 1 },
  { label: t('page.package.month'), value: 2 },
  { label: t('page.package.year'), value: 3 }
]);

const rateLimitOptions = ref<{ label: string; value: number }[]>([]);

const rateLimitData = ref<Api.Auth.RateLimit[]>([]);

const getRateLimitData = async () => {
  try {
    const response = await fetchRateLimitList();
    rateLimitData.value = response.data || [];
    rateLimitOptions.value = rateLimitData.value.map(item => {
      const upLimitText = item.upLimitEnable
        ? `${t('page.package.up')}:${formatBandwidth(item.upLimit).value} ${formatBandwidth(item.upLimit).unit}`
        : `${t('page.package.up')}:${t('page.package.unlimit')}`;
      const downLimitText = item.downLimitEnable
        ? `${t('page.package.down')}:${formatBandwidth(item.downLimit).value} ${formatBandwidth(item.downLimit).unit}`
        : `${t('page.package.down')}:${t('page.package.unlimit')}`;

      return {
        label: `${item.rateLimitName} (${upLimitText}/${downLimitText})`,
        value: item.id
      };
    });
  } catch (error) {
    // console.error('error:', error);
  }
};

// 编辑状态
const isEdit = ref(false);
const editId = ref<string>();

const handleAdd = () => {
  isEdit.value = false;
  editId.value = undefined;
  showModal.value = true;
  getRateLimitData();
};

const handleCancel = () => {
  showModal.value = false;
  isEdit.value = false;
  editId.value = undefined;
  formState.value = {
    packageName: '',
    periodNum: 1,
    periodType: 2,
    price: '',
    trafficEnable: false,
    traffic: 0,
    trafficUnit: 'GB',
    rateLimitEnable: false,
    rateLimitId: undefined,
    durationEnable: false,
    duration: 0,
    durationUnit:'hour',
    clientNumEnable: false,
    clientNum: 0,
    packageEnable: true
  };
};

const handleOk = async () => {
  try {
    await formRef.value?.validate();
    // 准备基础数据
    const baseData = {
      packageName: formState.value.packageName,
      periodNum: formState.value.periodNum,
      periodType: formState.value.periodType,
      price: formState.value.price,
      trafficEnable: formState.value.trafficEnable,
      rateLimitEnable: formState.value.rateLimitEnable,
      rateLimitId: formState.value.rateLimitId,
      durationEnable: formState.value.durationEnable,
      clientNumEnable: formState.value.clientNumEnable,
      clientNum: formState.value.clientNum,
      packageEnable: formState.value.packageEnable
    };

    // 计算流量和时长
    const traffic = formState.value.trafficEnable
      ? Math.round(convertStorage(formState.value.traffic, formState.value.trafficUnit, 'B'))
      : 0;

    const duration = formState.value.durationEnable
      ? Math.round(convertTime(formState.value.duration, formState.value.durationUnit, 'second'))
      : 0;

    if (isEdit.value) {
      if (!editId.value) {
        message.error(t('page.package.isnull'));
        return;
      }
      // 编辑模式
      await updatePackage({
        ...baseData,
        id: editId.value,
        traffic,
        duration
      });
      message.success(t('page.package.editsuc'));
    } else {
      // 新增模式
      await addPackage({
        ...baseData,
        traffic,
        duration
      });
      message.success(t('page.package.addsuc'));
    }
    handleCancel();
    getData();
  } catch (error) {
    // message.error(isEdit.value ? t('page.package.editerr') : t('page.package.adderr'));
  }
};

const handleEdit = async (record: Api.Auth.Package) => {
  isEdit.value = true;
  editId.value = record.id;
  showModal.value = true;
  await getRateLimitData();

  const traffic = formatStorage(record.traffic);
  const duration = formatTime(record.duration);

  formState.value = {
    packageName: record.packageName,
    periodNum: record.periodNum,
    periodType: record.periodType,
    price: record.price,
    trafficEnable: record.trafficEnable,
    traffic: traffic.value,
    trafficUnit: traffic.unit,
    rateLimitEnable: record.rateLimitEnable,
    rateLimitId: record.rateLimitId,
    durationEnable: record.durationEnable,
    duration: duration.value,
    durationUnit: duration.unit,
    clientNumEnable: record.clientNumEnable,
    clientNum: record.clientNum,
    packageEnable: record.packageEnable
  };
};

const handleDelete = (record: Api.Auth.Package) => {
  Modal.confirm({
    title: t('page.package.confirmdelete'),
    content: t('page.package.deletecontent'),
    okText: t('page.package.confirm'),
    cancelText: t('page.package.close'),
    okType: 'danger',
    async onOk() {
      try {
        await deletePackage(record.id);
        message.success(t('page.package.deletesuc'));
        getData();
      } catch (error) {
        // message.error(t('page.package.deleteerr'));
      }
    }
  });
};

onMounted(() => {
  getRateLimitData();
});
</script>

<style scoped>
.h-full {
  height: 100%;
}
</style>
