<template>
  <SimpleScrollbar>
    <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
      <ACard
        :title="t('page.ratelimit.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"
              :show-add="false"
              @refresh="getData"
              @add="handleAdd"
            />
          </div>
        </template>
        <ATable
          ref="wrapperEl"
          :columns="columns"
          :data-source="data"
          :loading="loading"
          row-key="rateLimitName"
          size="small"
          :pagination="mobilePagination"
          :scroll="scrollConfig"
          class="h-full"
        />
      </ACard>

      <!-- 新增限速配置弹窗 -->
      <AModal
        v-model:visible="showModal"
        :title="isEdit ? t('page.ratelimit.change') : t('page.ratelimit.add')"
        @ok="handleOk"
        @cancel="handleCancel"
      >
        <AForm
          ref="formRef"
          :model="formState"
          :rules="rules"
          :label-col="{ span: 9 }"
          :wrapper-col="{ span: 13 }"
        >
          <AFormItem :label="t('page.ratelimit.name')" name="rateLimitName">
            <AInput v-model:value="formState.rateLimitName" :placeholder="t('page.ratelimit.plename')" />
          </AFormItem>

          <AFormItem :label="t('page.ratelimit.upratelimit')" name="upLimitEnable">
            <ACheckbox v-model:checked="formState.upLimitEnable">{{ t('page.ratelimit.useuplimit') }}</ACheckbox>
          </AFormItem>

          <AFormItem
            v-if="formState.upLimitEnable"
            :label="t('page.ratelimit.uplimit')"
            name="upLimit"
          >
            <div class="flex gap-2">
              <AFormItem name="upLimit" class="mb-0 flex-1">
                <AInputNumber
                  v-model:value="formState.upLimit"
                  :placeholder="t('page.ratelimit.pleuplimit')"
                  :min="1"
                  :max="1024"
                  :precision="0"
                  style="width: 100%"
                />
              </AFormItem>
              <AFormItem name="upLimitUnit" class="mb-0">
                <ASelect
                  v-model:value="formState.upLimitUnit"
                  :options="bandwidthUnits.map(unit => ({ label: unit, value: unit }))"
                  style="width: 100px"
                />
              </AFormItem>
            </div>
          </AFormItem>

          <AFormItem :label="t('page.ratelimit.downratelimit')" name="downLimitEnable">
            <ACheckbox v-model:checked="formState.downLimitEnable">{{ t('page.ratelimit.usedownlimit') }}</ACheckbox>
          </AFormItem>

          <AFormItem
            v-if="formState.downLimitEnable"
            :label="t('page.ratelimit.downlimit')"
            name="downLimit"
          >
            <div class="flex gap-2">
              <AFormItem name="downLimit" class="mb-0 flex-1">
                <AInputNumber
                  v-model:value="formState.downLimit"
                  :placeholder="t('page.ratelimit.pledownlimit')"
                  :min="1"
                  :max="1024"
                  :precision="0"
                  style="width: 100%"
                />
              </AFormItem>
              <AFormItem name="downLimitUnit" class="mb-0">
                <ASelect
                  v-model:value="formState.downLimitUnit"
                  :options="bandwidthUnits.map(unit => ({ label: unit, value: unit }))"
                  style="width: 100px"
                />
              </AFormItem>
            </div>
          </AFormItem>
        </AForm>
      </AModal>
    </div>
  </SimpleScrollbar>
</template>

<script setup lang="tsx">
import { useTable } from '@/hooks/common/table';
import { SimpleScrollbar } from '~/packages/materials/src';
import { computed, shallowRef, ref } from 'vue';
import { useElementSize } from '@vueuse/core';
import { fetchRateLimitList, addRateLimit, editRateLimit, removeRateLimit } from '@/service/api/auth';
import { message, Modal, Button } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import { PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { bandwidthUnits, convertBandwidth, formatBandwidth, type BandwidthUnit } from '@/utils/units';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
interface RateLimitForm extends Omit<Api.Auth.RateLimitAdd, 'upLimit' | 'downLimit'> {
  upLimit: number;
  downLimit: number;
  upLimitUnit: BandwidthUnit;
  downLimitUnit: BandwidthUnit;
}

const wrapperEl = shallowRef<HTMLElement | null>(null);
const { height: wrapperElHeight } = useElementSize(wrapperEl);

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

const showModal = ref(false);
const formRef = ref();
const formState = ref<RateLimitForm>({
  rateLimitName: '',
  upLimitEnable: false,
  downLimitEnable: false,
  upLimit: 0,
  downLimit: 0,
  upLimitUnit: 'Mbps',
  downLimitUnit: 'Mbps'
});

const rules: Record<string, Rule[]> = {
  rateLimitName: [{ required: true, message: t('page.ratelimit.plename'), trigger: 'blur' }],
  upLimit: [
    {
      required: true,
      message: t('page.ratelimit.pleuplimit'),
      trigger: 'blur',
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.upLimitEnable) return Promise.resolve();
        if (!value || value <= 0) return Promise.reject(t('page.ratelimit.reject'));
        return Promise.resolve();
      }
    }
  ],
  downLimit: [
    {
      required: true,
      message: t('page.ratelimit.pledownlimit'),
      trigger: 'blur',
      validator: (_rule: Rule, value: number) => {
        if (!formState.value.downLimitEnable) return Promise.resolve();
        if (!value || value <= 0) return Promise.reject(t('page.ratelimit.reject'));
        return Promise.resolve();
      }
    }
  ]
};

const isEdit = ref(false);
const editId = ref<number>();

const handleAdd = () => {
  isEdit.value = false;
  editId.value = undefined;
  formState.value = {
    rateLimitName: '',
    upLimitEnable: false,
    downLimitEnable: false,
    upLimit: 0,
    downLimit: 0,
    upLimitUnit: 'Mbps',
    downLimitUnit: 'Mbps'
  };
  showModal.value = true;
};

const handleEdit = (record: Api.Auth.RateLimit) => {
  isEdit.value = true;
  editId.value = record.id;

  formState.value = {
    rateLimitName: record.rateLimitName,
    upLimitEnable: record.upLimitEnable,
    downLimitEnable: record.downLimitEnable,
    upLimit: convertBandwidth(record.upLimit, 'Kbps', 'Mbps'),
    downLimit: convertBandwidth(record.downLimit, 'Kbps', 'Mbps'),
    upLimitUnit: 'Mbps',
    downLimitUnit: 'Mbps'
  };

  showModal.value = true;
};

const handleDelete = (record: Api.Auth.RateLimit) => {
  Modal.confirm({
    title: t('page.ratelimit.confirmdelete'),
    icon: () => <ExclamationCircleOutlined />,
    content: `${t('page.ratelimit.deletecontant')} "${record.rateLimitName}"?`,
    async onOk() {
      try {
        await removeRateLimit(record.id);
        message.success(t('page.ratelimit.deletesuc'));
        getData();
      } catch (error) {
        // console.error('error:', error);
      }
    }
  });
};

const handleCancel = () => {
  showModal.value = false;
  formState.value = {
    rateLimitName: '',
    upLimitEnable: false,
    downLimitEnable: false,
    upLimit: 0,
    downLimit: 0,
    upLimitUnit: 'Mbps',
    downLimitUnit: 'Mbps'
  };
};

const handleOk = async () => {
  try {
    await formRef.value?.validate();
    const submitData = {
      ...formState.value,
      upLimit: formState.value.upLimitEnable
        ? Math.round(convertBandwidth(formState.value.upLimit, formState.value.upLimitUnit, 'Kbps'))
        : 0,
      downLimit: formState.value.downLimitEnable
        ? Math.round(convertBandwidth(formState.value.downLimit, formState.value.downLimitUnit, 'Kbps'))
        : 0
    };

    if (isEdit.value) {
      if (!editId.value) {
        message.error(t('page.ratelimit.idnull'));
        return;
      }
      await editRateLimit({
        id: editId.value,
        rateLimitName: submitData.rateLimitName,
        upLimitEnable: submitData.upLimitEnable,
        downLimitEnable: submitData.downLimitEnable,
        upLimit: submitData.upLimit,
        downLimit: submitData.downLimit
      });
      message.success(t('page.ratelimit.changesuc'));
    } else {
      await addRateLimit(submitData);
      message.success(t('page.ratelimit.addsuc'));
    }
    handleCancel();
    getData();
  } catch (error) {
    // message.error(isEdit.value ? 'change error' : 'add error');
  }
};

const {
  columns,
  columnChecks,
  data,
  loading,
  getData,
  mobilePagination
} = useTable({
  apiFn: async () => {
    try {
      const response = await fetchRateLimitList();
      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.RateLimit>[] => [
    {
      key: 'rateLimitName',
      dataIndex: 'rateLimitName',
      title: t('page.ratelimit.name'),
      align: 'center'
    },
    {
      key: 'upLimit',
      dataIndex: 'upLimit',
      title: t('page.ratelimit.upratelimit'),
      align: 'center',
      customRender: ({ text, record }) => {
        if (!record.upLimitEnable) return t('page.ratelimit.unlimit');
        const { value, unit } = formatBandwidth(text);
        return `${value} ${unit}`;
      }
    },
    {
      key: 'downLimit',
      dataIndex: 'downLimit',
      title: t('page.ratelimit.downratelimit'),
      align: 'center',
      customRender: ({ text, record }) => {
        if (!record.downLimitEnable) return t('page.ratelimit.unlimit');
        const { value, unit } = formatBandwidth(text);
        return `${value} ${unit}`;
      }
    },
    {
      title: t('page.ratelimit.operate'),
      key: 'operate',
      align: 'center',
      width: 200,
      fixed: 'right',
      customRender: ({ record }) => (
        <div class="flex justify-center gap-2">
          <Button type="link" onClick={() => handleEdit(record)}>
            { t('page.ratelimit.changed') }
          </Button>
          <Button type="link" danger onClick={() => handleDelete(record)}>
              {t('page.ratelimit.delete')}
          </Button>
        </div>
      )
    }
  ]
});
</script>

<style scoped></style>
