<script setup lang="ts">
import { inject, onMounted, ref, watch } from 'vue';
import { ColorPicker } from 'vue-color-kit';
import { message } from 'ant-design-vue';

import SvgIcon from '@/components/SvgIcon.vue';
import { useDictData } from '@/hooks/dict-data';
import { useRequest } from '@/hooks/request';
import { t } from '@/i18n';
import { addOrganization, addUploadLogo, getInfoListByOrgId, groupList, updateOrganization } from '@/api';
import { DictCode } from '@/constants';
import { SET_COLOR_PRIMARY } from '@/constants/inject-key';

import EquipmentLimitations from './EquipmentLimitations.vue';

import type {
  CreateCustomer,
  EquipmentLimitationsItem,
  EquipmentTypeItem,
  OrgDeviceLimit,
  UseGuideStepItemExpose,
  UseGuideStepItemProps,
} from '@/types';

import 'vue-color-kit/dist/vue-color-kit.css';

// 引入样式文件
interface ColorStyle {
  background: string;
  border: string;
  index: number;
  color: string;
}

interface NewColor {
  hex: string;
}

const { dictData: dataValidityPeriod, getDictData: getDataValidityPeriod } = useDictData(DictCode.DataValidityPeriod);
const equipmentLimitationsRefs = ref<InstanceType<typeof EquipmentLimitations>[]>([]);
const equipmentLimitationsList = ref<EquipmentLimitationsItem[]>([
  {
    deviceGlobalId: undefined,
    upperLimit: 0,
  },
]);
const orgDeviceLimits = ref<OrgDeviceLimit[]>([]);
const setColorPrimary = inject(SET_COLOR_PRIMARY, undefined);
const fileList = ref([]);
const fileImg = ref<Blob>();
const customizationColor = ref<boolean>(false);
const { handleRequest } = useRequest();
const equipmentType = ref<EquipmentTypeItem[]>([]);

const props = defineProps<UseGuideStepItemProps<CreateCustomer>>();
const colorStyle: ColorStyle[] = [
  {
    background: 'background:#32bac0',
    border: 'border:1px solid #32bac0',
    color: '#32BAC0',
    index: 0,
  },
  {
    background: 'background:#256AFE',
    border: 'border:1px solid #256AFE',
    color: '#256AFE',
    index: 1,
  },
  {
    background: 'background:#00A94D',
    border: 'border:1px solid #00A94D',
    color: '#00A94D',
    index: 2,
  },
  {
    background: 'background:#7866FF',
    border: 'border:1px solid #7866FF',
    color: '#7866FF',
    index: 3,
  },
];

// 预定义颜色组
const presetColors = ref<string[]>([
  '#000000',
  '#FFFFFF',
  '#FF1900',
  '#F47365',
  '#FFB243',
  '#FFE623',
  '#6EFF2A',
  '#1BC7B1',
  '#00BEFF',
  '#2E81FF',
  '#5D61FF',
  '#FF89CF',
  '#FC3CAD',
  '#BF3DCE',
  '#8E00A7',
]);

// 颜色变化回调函数
const handleColorChange = (newColor: NewColor) => {
  props.form.selectedColor = newColor.hex;
  setColorPrimary?.(props.form.selectedColor);
  props.form.themeColor = props.form.selectedColor;
};
const addCustomizationColor = () => {
  customizationColor.value = !customizationColor.value;
};
const colorClick = (color: string) => {
  setColorPrimary?.(color);
  props.form.themeColor = color;
};

const finish = async () => {
  orgDeviceLimits.value = [];
  // eslint-disable-next-line no-useless-catch
  try {
    // 创建校验任务队列（包含所有子组件+父组件自身）
    const allTasks = [...equipmentLimitationsRefs.value.map((c) => c.formRefSubmit())];
    // 并行执行所有校验（父+子）
    await Promise.all(allTasks);

    equipmentLimitationsList.value.forEach((item) => {
      orgDeviceLimits.value.push({
        deviceGlobalId: item.deviceGlobalId,
        upperLimit: item.upperLimit,
      });
    });

    orgDeviceLimits.value.push({
      deviceGlobalId: -1,
      upperLimit: props.form.stationsNumber,
    });
    if (props.form.id) {
      updateOrganization({
        orgName: props.form.orgName,
        logo: props.form.logo,
        themeColor: props.form.themeColor,
        dataValidityPeriod: props.form.dataValidityPeriod,
        enabled: '1',
        id: props.form.id,
        orgDeviceLimits: orgDeviceLimits.value,
        startTenancy: props.form.leaseTerm[0].format('YYYY-MM-DD'),
        endTenancy: props.form.leaseTerm[1].format('YYYY-MM-DD'),
      });
    } else {
      props.form.id = await addOrganization({
        orgName: props.form.orgName,
        logo: props.form.logo,
        themeColor: props.form.themeColor,
        dataValidityPeriod: props.form.dataValidityPeriod,
        enabled: '1',
        orgDeviceLimits: orgDeviceLimits.value,
        startTenancy: props.form.leaseTerm[0].format('YYYY-MM-DD'),
        endTenancy: props.form.leaseTerm[1].format('YYYY-MM-DD'),
      });
    }
  } catch (err) {
    throw err;
  }
};
const beforeUpload = (file: Blob) => {
  fileImg.value = file;
  const isJpgOrPng = file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg';
  console.log(isJpgOrPng);
  if (!isJpgOrPng) {
    message.error(t('organizationManage.imageFormat'));
    return false;
  }
};

const addClick = () => {
  equipmentLimitationsList.value.push({
    deviceGlobalId: undefined,
    upperLimit: 0,
  });
};

const deleteClick = (index: number) => {
  equipmentLimitationsList.value.splice(index, 1);
};

const handleChange = () => {
  if (fileImg.value) {
    // 上传接口
    handleRequest(async () => {
      const { fileName } = await addUploadLogo(fileImg.value as Blob);
      props.form.imageUrl = URL.createObjectURL(fileImg.value as Blob);
      props.form.logo = fileName;
    });
  }
};

defineExpose<UseGuideStepItemExpose>({
  finish,
});

const getInfoListByOrg = () => {
  handleRequest(async () => {
    if (props.form.id) {
      equipmentLimitationsList.value = [];
      const data = await getInfoListByOrgId(props.form.id);
      data.forEach((item) => {
        if (item.deviceGlobalId === -1) {
          props.form.stationsNumber = item.upperLimit;
        }
        if (item.deviceGlobalId !== -1) {
          equipmentLimitationsList.value.push({
            deviceGlobalId: item.deviceGlobalId,
            upperLimit: item.upperLimit,
          });
        }
      });
    }
  });
};

watch(
  () => props.form.id,
  (count) => {
    if (count) {
      getInfoListByOrg();
    }
  },
);

onMounted(() => {
  handleRequest(async () => {
    await getDataValidityPeriod();
    equipmentType.value = await groupList({
      dataType: 1,
    });
    getInfoListByOrg();
  });
});
</script>

<template>
  <div class="organization text">
    <AFormItem :label="t('organizationManage.organizationName')" name="orgName">
      <AInput v-model:value="form.orgName" class="organization-input" :placeholder="$t('common.pleaseEnter')" />
    </AFormItem>
    <AFormItem :label="t('organizationManage.leaseTerm')" name="leaseTerm">
      <ARangePicker
        class="organization-input"
        v-model:value="form.leaseTerm"
        :allow-clear="false"
        :separator="$t('common.to')"
      />
    </AFormItem>
    <div class="upper-limit">{{ t('organizationManage.quantityLimit') }}</div>
    <AFormItem :label="t('organizationManage.numberStations')" name="stationsNumber">
      <AInputNumber
        :placeholder="t('common.pleaseEnter')"
        v-model:value="form.stationsNumber"
        class="organization-input"
        addon-after="个"
      />
    </AFormItem>
    <div v-for="(item, index) in equipmentLimitationsList" :key="index">
      <EquipmentLimitations
        ref="equipmentLimitationsRefs"
        :index="index"
        :form="item"
        :equipment-type="equipmentType"
        @addClick="addClick"
        @deleteClick="deleteClick"
      />
    </div>

    <AFormItem :label="t('organizationManage.dataRetentionPeriod')" name="dataValidityPeriod">
      <ASelect
        class="organization-input"
        v-model:value="form.dataValidityPeriod"
        :options="dataValidityPeriod"
        :field-names="{ label: 'dictValue', value: 'dictEngValue' }"
        :placeholder="$t('common.plzSelect')"
      />
    </AFormItem>

    <AFormItem label="Logo">
      <div class="upload-dev">
        <AUpload
          v-model:file-list="fileList"
          name="file"
          list-type="picture-card"
          class="avatar-uploader"
          action=""
          :show-upload-list="false"
          :before-upload="beforeUpload"
          :custom-request="handleChange"
        >
          <template v-if="form.imageUrl">
            <div class="img-dev">
              <img class="img-style" :src="form.imageUrl" alt="avatar" />
              <div class="background-style"></div>
            </div>
          </template>

          <div v-else>
            <SvgIcon class="icon-size" name="upload-pictures" />
            <div class="text">{{ t('organizationManage.uploadImage') }}</div>
          </div>
        </AUpload>
        <div class="format-text">{{ t('organizationManage.supportedImageFormats') }}</div>
      </div>
    </AFormItem>

    <AFlex>
      <AFlex align="center">
        <div class="text">{{ t('organizationManage.themeColor') }}</div>
        <AFlex class="color-list">
          <div v-for="(item, index) in colorStyle" :key="index">
            <div @click="colorClick(item.color)">
              <AFlex
                justify="center"
                align="center"
                :style="form.themeColor === item.color ? item.border : 'border:1px solid #fff;'"
                class="color-div"
              >
                <div :style="item.background" class="color-style"></div>
              </AFlex>
            </div>
          </div>

          <AFlex class="flex-relative">
            <div @click="addCustomizationColor">
              <AFlex class="color-customization" justify="space-between" align="center">
                <div class="customization-style" :style="'background:' + form.selectedColor"></div>
                <div class="customization-text">{{ form.selectedColor }}</div>
              </AFlex>
            </div>

            <div class="color-selection">
              <ColorPicker
                v-show="customizationColor"
                v-model:color="form.selectedColor"
                :colors-default="presetColors"
                theme="dark"
                @changeColor="handleColorChange"
                style="width: 220px"
                class="picker-color"
              />
            </div>
          </AFlex>
        </AFlex>
      </AFlex>
    </AFlex>
    <div class="display-effect">
      <div class="display-effect-top">
        <span class="desktop-header-dot" v-for="i in 3" :key="i"></span>
      </div>
      <AFlex class="desktop-content" wrap="wrap" justify="space-between">
        <div class="desktop-content-div" v-for="i in 6" :key="i">
          <AFlex>
            <div class="desktop-content-top-left"></div>
            <AFlex :vertical="true">
              <div class="desktop-content-top-right"></div>
              <div class="desktop-content-top-right-div"></div>
            </AFlex>
          </AFlex>
          <div class="desktop-content-bottom"></div>
          <div class="desktop-content-bottom-div"></div>
        </div>
      </AFlex>
    </div>
  </div>
</template>

<style lang="scss">
.organization {
  .ant-form-item .ant-form-item-label {
    width: 130px;
  }
}
</style>

<style lang="scss" scoped>
.upper-limit {
  margin-top: 40px;
  margin-bottom: 16px;
  font-size: 16px;
  font-style: normal;
  font-weight: 500;
  line-height: 24px;
  color: #333;
  text-align: left;
}

.background-style {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99999;
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: rgb(0 0 0 / 50%);
  opacity: 0;
  transition: opacity 0.3s;
}

.img-dev {
  position: relative;
  width: 100%;
  height: 100%;
}

.img-style {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.color-selection {
  position: absolute;
  top: -270px;
  left: 80px;
  width: 100%;
  height: 100%;
}

.picker-color {
  :deep(.color-alpha) {
    display: none !important;
  }

  :deep(.color-type) {
    display: none !important;
  }

  :deep(.hue) {
    margin-left: 20px;
  }
}

.customization-text {
  font-size: 12px;
  font-style: normal;
  font-weight: 400;
  line-height: 20px;
  color: #999;
  text-align: left;
}

.customization-style {
  width: 24px;
  height: 24px;
  border-radius: 4px;
}

.flex-relative {
  position: relative;
}

.color-customization {
  width: 90px;
  height: 32px;
  padding: 4px;
  cursor: pointer;
  border: 1px solid #d6d6d6;
  border-radius: 4px;
}

.desktop-content {
  position: relative;
  top: -30px;
  left: 16px;
  width: 288px;
}

.desktop-content-bottom-div {
  width: 48px;
  height: 3px;
  background: #d8d8d8;
  border-radius: 2px;
}

.desktop-content-bottom {
  width: 71px;
  height: 3px;
  margin: 6px 0;
  background: #d8d8d8;
  border-radius: 2px;
}

.desktop-content-top-right-div {
  width: 26px;
  height: 3px;
  background: #d8d8d8;
  border-radius: 2px;
}

.desktop-content-top-right {
  width: 40px;
  height: 3px;
  margin: 6px 0;
  background: #d8d8d8;
  border-radius: 2px;
}

.desktop-content-top-left {
  width: 24px;
  height: 24px;
  margin-right: 8px;
  background: var(--antd-color-primary-opacity-50);
  border: 1px solid var(--antd-color-primary);
  border-radius: 4px;
}

.desktop-content-div {
  width: 88px;
  height: 57px;
  padding: 6px;
  margin-bottom: 12px;
  background: #fff;
  border: 1px solid #d9dbe2;
  border-radius: 4px;
}

.display-effect-top {
  display: flex;
  width: 319px;
  height: 94px;
  padding-top: 9px;
  padding-left: 16px;
  background-color: var(--antd-color-primary);
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
}

.display-effect {
  width: 320px;
  height: 206px;
  margin-top: 24px;
  margin-left: 138px;
  background: #fafafa;
  border: 1px solid var(--antd-color-primary);
  border-radius: 8px;
}

.desktop-header-dot {
  width: 6px;
  height: 6px;
  background-color: white;
  border-radius: 50%;

  & + & {
    margin-left: 6px;
  }
}

.color-list {
  margin-left: 95px;
}

.color-style {
  width: 24px;
  height: 24px;
  border-radius: 4px;
}

.color-div {
  width: 32px;
  height: 32px;
  margin-right: 4px;
  cursor: pointer;
  border-radius: 6px;
}

.upload-dev {
  margin-top: 8px;
  margin-left: 10px;
}

.icon-size {
  font-size: 24px;
}

.format-text {
  font-size: 12px;
  font-style: normal;
  font-weight: 400;
  line-height: 20px;
  color: #999;
  text-align: left;
}

.organization-input {
  width: 256px;
  height: 32px;
  margin-left: 10px;
}

.text {
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;
  color: rgb(0 0 0 / 65%);
  text-align: left;
}

:deep(.organization-input) {
  .ant-input-number-group .ant-input-number-group-addon {
    background-color: #fff;
  }
}
</style>
