<script setup lang="ts">
import { nextTick, watch, computed, ref, watchEffect, reactive, onBeforeMount } from 'vue';
import { VxeUI, type VxeFormProps, type VxeFormListeners } from 'vxe-pc-ui';
import type { SupplierModel } from '@/model/care.model';
import { useRequest } from 'alova/client';
import { supplierMethod, supplierEditMethod } from '@/request/api/care.api';
import { getDictionaryMethod } from '@/request/api/dictionary.api';
import { branchMethod } from '@/request/api/system.api';
import { notification } from 'ant-design-vue';
import { TreeSelect, Checkbox } from 'ant-design-vue';
import dayjs, { type Dayjs } from 'dayjs';
const SHOW_ALL = TreeSelect.SHOW_ALL;

type FormModel = Partial<SupplierModel>;

const defaultModel = {};

const props = defineProps<{ data: FormModel }>();
const emits = defineEmits<{
  submit: [data?: SupplierModel];
}>();

const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
const dayLabels = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期天'];

// 营业时间
function parseBusinessTime(businessTime?: string): Record<string, { enabled: boolean; start: string; end: string }> {
  const defaultTime = { start: '08:00', end: '20:00' };
  const result: Record<string, { enabled: boolean; start: string; end: string }> = {};

  // 如果没有数据，默认全选
  if (!businessTime) {
    days.forEach((day) => {
      result[day] = {
        enabled: true,
        start: defaultTime.start,
        end: defaultTime.end,
      };
    });
    return result;
  }


  const parts = businessTime.split(',').map(s => s.trim());

  days.forEach((day, i) => {
    const start = parts[i * 2] || '';
    const end = parts[i * 2 + 1] || '';
    const enabled = !!(start && end);

    result[day] = {
      enabled,
      start: enabled ? start.padStart(5, '0') : defaultTime.start,
      end: enabled ? end.padStart(5, '0') : defaultTime.end,
    };
  });

  return result;
}

// 营业时间
function formatBusinessTime(businessHours: Record<string, { enabled: boolean; start: string; end: string }>): string {
  return days.flatMap(day => {
    const { enabled, start, end } = businessHours[day] || {};
    return enabled && start && end ? [start, end] : ['', ''];
  }).join(',');
}

// 初始化营业时间
function initBusinessHours(data?: any) {
  return data?.businessTime ? parseBusinessTime(data.businessTime) : parseBusinessTime();
}

const model = ref<Record<string, any>>({
  collaborateDepts: [],
  businessHours: initBusinessHours(),
  dayLabels: dayLabels,
});

watchEffect(() => {
  const data = props.data;
  const collaborateDepts = data?.collaborateDepts?.map((item: any) => ({ value: String(item.deptId), label: item.deptName })) ?? [];

  model.value = {
    ...model.value,
    collaborateDepts,
    businessHours: initBusinessHours(data),
  }
});

const branch = ref<any[]>([]);
const { loading: branchLoading } = useRequest(branchMethod).onSuccess(({ data }) => {
  const to = (data?: any[]): any[] => {
    return Array.isArray(data)
      ? data.map(item => ({
        ...item,
        value: String(item.id),
        key: String(item.id),
        label: item.label,
        title: item.label,
        children: to(item.children)
      }))
      : [];
  }
  branch.value = to(data);
});


function getSafePopupContainer(triggerNode?: HTMLElement): HTMLElement {
  try {

    if (typeof document !== 'undefined' && document?.body) return document.body;
  } catch (e) {
    console.log(e);
  }
  return (triggerNode?.parentNode as HTMLElement) || document.body;
}


function findNode(nodes: any[], id: string | number): any | undefined {
  for (const n of nodes) {
    if (String(n.value) === String(id)) return n;
    const x = n.children && findNode(n.children, id);
    if (x) return x;
  }
}
function collectChildren(node?: any): string[] {
  const res: string[] = [];
  if (!node?.children) return res;
  const dfs = (n: any) => {
    if (!n?.children) return;
    for (const c of n.children) {
      res.push(String(c.value));
      dfs(c);
    }
  };
  dfs(node);
  return res;
}
function findLabel(nodes: any[], id: string | number): string {
  const stack = [...nodes];
  while (stack.length) {
    const n = stack.pop();
    if (String(n.value) === String(id)) return n.label;
    if (n.children) stack.push(...n.children);
  }
  return '';
}

function collectAllKeys(nodes: any[]): string[] {
  const keys: string[] = [];
  const stack = [...nodes];
  while (stack.length) {
    const n = stack.pop();
    if (!n) continue;
    keys.push(String(n.value));
    if (n.children) stack.push(...n.children);
  }
  return keys;
}
const expandedKeys = ref<string[]>([]);
function onVisibleChange(visible: boolean) {
  if (visible) {
    expandedKeys.value = collectAllKeys(branch.value);
  }
}
const { loading, send: load } = useRequest((params) => supplierMethod(1, 10, params), {
  immediate: false,
  initialData: props.data ?? defaultModel,
});
const { loading: submitting, send: submit } = useRequest(supplierEditMethod, { immediate: false }).onSuccess(({ data }) => {
  emits('submit');
});

const projectList = ref<Array<{ label: string; value: string }>>([]);
// 线上权益
const onlineCPList = ref<Array<{ label: string; value: string }>>([]);
// 营业时间
// 全选/取消全选
const selectAllBusinessHours = computed({
  get: () => {
    if (!model.value.businessHours) return false;
    return days.every(day => model.value.businessHours[day]?.enabled);
  },
  set: (value: boolean) => {
    if (!model.value.businessHours) return;
    days.forEach(day => {
      if (model.value.businessHours[day]) {
        model.value.businessHours[day].enabled = value;
        // 初始化时间范围值
        if (value && !timeRangeValues.value[day]) {
          const dayData = model.value.businessHours[day];
          if (dayData.start && dayData.end) {
            try {
              timeRangeValues.value[day] = [dayjs(dayData.start, 'HH:mm'), dayjs(dayData.end, 'HH:mm')];
            } catch {
              timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
            }
          } else {
            timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
          }
        }
      }
    });
    // 触发表单验证
    nextTick(() => {
      formRef?.value?.validateField('businessTime');
    });
  }
});

// 处理单个日期选择
const handleDayToggle = (day: string) => {
  if (!model.value.businessHours || !model.value.businessHours[day]) return;
  const wasEnabled = model.value.businessHours[day].enabled;
  model.value.businessHours[day].enabled = !wasEnabled;

  // 如果启用日期，初始化时间范围值
  if (!wasEnabled && !timeRangeValues.value[day]) {
    const dayData = model.value.businessHours[day];
    if (dayData.start && dayData.end) {
      try {
        timeRangeValues.value[day] = [dayjs(dayData.start, 'HH:mm'), dayjs(dayData.end, 'HH:mm')];
      } catch {
        timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
      }
    } else {
      timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
    }
  }

  // 触发表单验证
  nextTick(() => {
    formRef?.value?.validateField('businessTime');
  });
};

// 处理时间范围变化
const handleTimeRangeChange = (day: string, timeRange: [Dayjs, Dayjs] | null) => {
  if (!model.value.businessHours || !model.value.businessHours[day]) return;
  if (timeRange && timeRange.length === 2) {
    model.value.businessHours[day].start = timeRange[0].format('HH:mm');
    model.value.businessHours[day].end = timeRange[1].format('HH:mm');
  }
  // 触发表单验证
  nextTick(() => {
    formRef?.value?.validateField('businessTime');
  });
};

const timeRangeValues = ref<Record<string, [Dayjs, Dayjs] | null>>({});

function initTimeRangeValues() {
  days.forEach(day => {
    if (!(day in timeRangeValues.value)) {
      timeRangeValues.value[day] = null;
    }
  });
}

watch(() => model.value.businessHours, (newVal) => {
  if (newVal) {
    days.forEach(day => {
      const dayData = newVal[day];
      if (dayData?.enabled) {
        if (dayData?.start && dayData?.end) {
          try {
            timeRangeValues.value[day] = [dayjs(dayData.start, 'HH:mm'), dayjs(dayData.end, 'HH:mm')];
          } catch {
            timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
          }
        } else {
          timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
        }
      } else {
        if (!timeRangeValues.value[day]) {
          timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
        }
      }
    });
  } else {
    // 初始化所有日期
    initTimeRangeValues();
  }
}, { immediate: true, deep: true });

// 初始化所有日期的时间范围值
initTimeRangeValues();

const formRef = ref<any>(null);


const baseFormItems = [
  {
    field: 'name',
    title: '供应商',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  },
  {
    field: 'detailAddress',
    title: '地址',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  },
  {
    field: 'kahuna',
    title: '负责人',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  },
  {
    field: 'phone',
    title: '联系电话',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  },
  {
    field: 'collaborateDepts',
    title: '合作机构',
    span: 24,
    slots: {
      default: 'initiate',
    },
  },
  {
    field: 'onlineCPTypes',
    title: '实体商品',
    span: 24,
    itemRender: {
      name: 'VxeSelect',
      props: {
        placeholder: '请选择',
        options: computed(() => projectList.value),
        optionProps: {
          value: 'value',
          label: 'label',
        },
        multiple: true,
        collapseTags: true,
        clearable: true,
      },
    },
  },
  {
    field: 'offlineCPTypes',
    title: '线下服务',
    span: 24,
    itemRender: {
      name: 'VxeSelect',
      props: {
        placeholder: '请选择',
        options: computed(() => projectList.value),
        optionProps: {
          value: 'value',
          label: 'label',
        },
        multiple: true,
        collapseTags: true,
        clearable: true,
      },
    },
  },
  // 开始新增项
  {
    field: 'outlineCPTypes',
    title: '线上权益',
    span: 24,
    itemRender: {
      name: 'VxeSelect',
      props: {
        placeholder: '请选择',
        options: computed(() => onlineCPList.value),
        optionProps: {
          value: 'value',
          label: 'label',
        },
        multiple: true,
        collapseTags: true,
        clearable: true,
      },
    },
  },
  //账户类型，单选，商户号还是个人号，默认选中商户号
  {
    field: 'wechatPaymentType',
    title: '账户类型',
    span: 24,
    itemRender: {
      name: 'VxeRadioGroup',
      props: {
        placeholder: '请选择',
        options: [
          { label: '商户号', value: '2' },
          { label: '个人号', value: '1' },
        ],
        modelValue: '2',
      },
    },
  },
  // 微信账户
  {
    field: 'wechatPaymentAccount',
    title: '微信账户',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入' } },
  },
  // 分账比例 0-100
  {
    field: 'profitSharing',
    title: '分账比例',
    span: 24,
    itemRender: { name: 'VxeInput', props: { placeholder: '请输入', type: 'number', min: 0, max: 100 } },
  },
  // 营业状态 单选，营业、休息、停业
  {
    field: 'businessStatus',
    title: '营业状态',
    span: 24,
    itemRender: { name: 'VxeRadioGroup', props: { placeholder: '请选择' }, options: [{ label: '营业', value: '1' }, { label: '休息', value: '2' }, { label: '停业', value: '3' }] },
  },

  { align: 'center', span: 24, slots: { default: 'active' } },
];

// 营业时间字段
const businessHoursField = {
  field: 'businessTime',
  title: '营业时间',
  span: 24,
  slots: {
    title: 'businessTimeTitle',
    default: 'businessHours',
  },
} as const;

// 更新表单项
function updateFormItems() {
  const items = [...baseFormItems];
  const shouldShow = showBusinessHours.value;
  // 查找分账比例和营业时间
  const profitSharingIndex = items.findIndex(item => item.field === 'profitSharing');
  const businessTimeIndex = items.findIndex(item => item.field === 'businessTime');

  if (shouldShow) {
    if (businessTimeIndex === -1 && profitSharingIndex !== -1) {
      items.splice(profitSharingIndex + 1, 0, businessHoursField as any);
    }
  } else {
    if (businessTimeIndex !== -1) {
      items.splice(businessTimeIndex, 1);
    }
  }

  formProps.items = items as any;
}

const formProps = reactive<VxeFormProps<FormModel>>({
  titleWidth: 100,
  titleAlign: 'right',
  titleColon: true,
  data: { ...props.data },
  items: baseFormItems as any,
  rules: {
    name: [{ required: true, message: '请输入供应商名称' }],
    detailAddress: [{ required: true, message: '请输入地址' }],
    kahuna: [{ required: true, message: '请输入负责人' }],
    phone: [{ required: true, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }],
    // 合作机构
    collaborateDepts: [
      {
        required: true,
        validator: () => {
          const depts = model.value.collaborateDepts;
          if (!depts || !Array.isArray(depts) || depts.length === 0) {
            notification.error({
              message: '请选择合作机构',
            });
            return;
          }
        },
      },
    ],
    wechatPaymentType: [{ required: true, message: '请选择账户类型' }],
    wechatPaymentAccount: [{ required: true, message: '请输入微信接收方账号' }],
    profitSharing: [{ required: true, message: '请输入分账比例' }],
    businessStatus: [{ required: true, message: '请选择营业状态' }],
    businessTime: [
      {
        validator: () => {
          if (!showBusinessHours.value) return;
          if (!model.value.businessHours) {
            notification.error({
              message: '请至少选择一天营业时间',
            });
            return;
          }
          // 检查至少选择了一天
          const hasSelectedDay = days.some(day => model.value.businessHours[day]?.enabled);
          if (!hasSelectedDay) {
            notification.error({
              message: '请至少选择一天营业时间',
            });
            return;
          }
          // 检查选中的天都有时间范围
          for (const day of days) {
            const dayData = model.value.businessHours[day];
            if (dayData?.enabled) {
              if (!dayData.start || !dayData.end) {
                throw new Error('请完善所有选中日期的营业时间');
              }
            }
          }
        },
      },
    ],
  },
});

// 判断是否显示营业时间（仅限"线下项目"有值时展示）
const showBusinessHours = computed<boolean>(() => {
  const offlineCPTypes: string[] | undefined = formProps.data?.offlineCPTypes;
  return !!(offlineCPTypes && Array.isArray(offlineCPTypes) && offlineCPTypes.length > 0);
});

const prevOfflineCPTypes = ref<string[] | undefined>(undefined);
let wasCleared = false;

// 重置营业时间为默认值
function resetBusinessHours() {
  const defaultTime = { start: '08:00', end: '20:00' };
  const businessHoursData: Record<string, { enabled: boolean; start: string; end: string }> = {};
  days.forEach((day) => {
    businessHoursData[day] = {
      enabled: true,
      start: defaultTime.start,
      end: defaultTime.end,
    };
  });
  model.value.businessHours = businessHoursData;

  // 重置时间范围值
  days.forEach(day => {
    timeRangeValues.value[day] = [dayjs('08:00', 'HH:mm'), dayjs('20:00', 'HH:mm')];
  });
}

// 监听线下项目变化，更新表单项，并在清除后再次选择时重置营业时间
watch(() => formProps.data?.offlineCPTypes, (newVal) => {
  const newHasValue = !!(newVal && Array.isArray(newVal) && newVal.length > 0);
  const oldHasValue = !!(prevOfflineCPTypes.value && Array.isArray(prevOfflineCPTypes.value) && prevOfflineCPTypes.value.length > 0);


  if (oldHasValue && !newHasValue) {
    wasCleared = true;
  }


  if (wasCleared && !oldHasValue && newHasValue) {
    resetBusinessHours();
    wasCleared = false;
  }

  prevOfflineCPTypes.value = newVal ? [...newVal] : undefined;
  updateFormItems();
}, { deep: true });

const formEmits: VxeFormListeners<FormModel> = {
  submit({ data }) {
    // 验证至少选择一个项目类型
    const onlineCPTypes = data?.onlineCPTypes;
    const offlineCPTypes = data?.offlineCPTypes;
    const outlineCPTypes = data?.outlineCPTypes;
    const hasOnline = onlineCPTypes && Array.isArray(onlineCPTypes) && onlineCPTypes.length > 0;
    const hasOffline = offlineCPTypes && Array.isArray(offlineCPTypes) && offlineCPTypes.length > 0;
    const hasOutline = outlineCPTypes && Array.isArray(outlineCPTypes) && outlineCPTypes.length > 0;

    if (!hasOnline && !hasOffline && !hasOutline) {
      notification.error({
        message: '实体商品、线下服务、线上权益至少选择一项',
      });
      return;
    }

    data.collaborateDepts = model.value.collaborateDepts.map((item: any) => {
      return {
        deptId: item.value,
        deptName: item.label
      }
    })

    // 格式化营业时间数据为字符串格式
    if (showBusinessHours.value && model.value.businessHours) {
      (data as any).businessTime = formatBusinessTime(model.value.businessHours);
    }

    submit(data).then(() => {
      notification.success({
        message: '操作成功',
      });
      VxeUI.modal.close('supplier-modal');
    });
  },
};

function onDeptChange(
  newVal: Array<{ value: string | number; label: string }>,
  _labels: Array<string>,
  extra: any
) {
  const current = new Set(newVal?.map((n) => String(n.value)) ?? []);
  const prev = new Set(
    (model.value.collaborateDepts as Array<{ value: string | number }> | undefined)?.map((n) => String(n.value)) ?? []
  );

  const final = new Set(current);

  // 判定是否为新增（选中）
  const triggerValue = String(extra?.triggerValue ?? '');
  const isChecked = !!extra?.checked; // true: 勾选, false: 取消

  if (triggerValue && isChecked) {
    // 勾选
    const node = findNode(branch.value, triggerValue);
    if (node) {
      for (const cid of collectChildren(node)) final.add(cid);
    }
  } else if (!isChecked) {
    // 取消
  } else {
    // 回退
    const added = [...current].filter((v) => !prev.has(v));
    for (const v of added) {
      const node = findNode(branch.value, v);
      if (node) {
        for (const cid of collectChildren(node)) final.add(cid);
      }
    }
  }

  const finalIds = [...final];
  const nextList = finalIds.map((id) => ({ value: String(id), label: findLabel(branch.value, id) }));

  nextTick(() => {
    model.value.collaborateDepts = nextList;
  });
}
function cancel() {
  VxeUI.modal.close('supplier-modal');
}
// 获取线上权益
async function getOnlineCPList() {
  try {
    const res = await getDictionaryMethod('condition_type_outline');
    if (res?.length > 0) {
      onlineCPList.value = res;
    }
  } catch (error) {
    console.error('获取项目列表失败:', error);
  };
}
// 获取线下项目
async function getOfflineCPList() {
  try {
    const res = await getDictionaryMethod('condition_type');
    if (res?.length > 0) {
      projectList.value = res;
    }
  } catch (error) {
    console.error('获取项目列表失败:', error);
  };
}
onBeforeMount(async () => {
  if (props.data?.id) load(props.data);
  await getOnlineCPList();
  await getOfflineCPList();
  // 初始化线下服务
  prevOfflineCPTypes.value = formProps.data?.offlineCPTypes ? [...formProps.data.offlineCPTypes] : undefined;
  // 初始化表单
  updateFormItems();
});
</script>

<template>
  <div class="form-container">
    <vxe-form ref="formRef" v-bind="formProps" v-on="formEmits" :loading="submitting">
      <template #initiate>
        <a-tree-select style="width: 100%" :show-checked-strategy="SHOW_ALL" tree-check-strictly :tree-data="branch"
          tree-checkable allow-clear :labelInValue="true" v-model:value="model.collaborateDepts"
          v-model:treeExpandedKeys="expandedKeys" :getPopupContainer="getSafePopupContainer"
          :dropdownMatchSelectWidth="false" :dropdownStyle="{ zIndex: 4000 }" placeholder="请选择" @change="onDeptChange"
          @dropdownVisibleChange="onVisibleChange" />
      </template>
      <template #businessTimeTitle>
        <span style="color: #ff4d4f">*</span>营业时间
      </template>
      <template #businessHours>
        <div class="business-hours-container">
          <div class="business-hours-header">
            <Checkbox v-model:checked="selectAllBusinessHours">全选</Checkbox>
          </div>
          <div class="business-hours-list">
            <div v-for="(day, index) in days" :key="day" class="business-hours-item">
              <Checkbox :checked="model.businessHours?.[day]?.enabled || false" @change="() => handleDayToggle(day)">
                {{ model.dayLabels?.[index] || dayLabels[index] }}
              </Checkbox>
              <div class="time-range-wrapper">
                <a-time-range-picker :value="timeRangeValues[day]" format="HH:mm"
                  :disabled="!model.businessHours?.[day]?.enabled"
                  @change="(timeRange: any) => handleTimeRangeChange(day, timeRange)" style="width: 200px" />
              </div>
            </div>
          </div>
        </div>
      </template>
      <template #active>
        <vxe-button type="reset" content="取消" :disabled="submitting" @click="cancel"></vxe-button>
        <vxe-button type="submit" status="primary" content="确定" :loading="submitting"></vxe-button>
      </template>
    </vxe-form>

  </div>
</template>

<style scoped lang="scss">
.form-container {
  padding: 20px;
}

.business-hours-container {
  width: 100%;
}

.business-hours-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;

  .business-hours-label {
    font-weight: 500;
  }
}

.business-hours-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.business-hours-item {
  display: flex;
  align-items: center;
  gap: 16px;

  .time-range-wrapper {
    display: flex;
    align-items: center;
  }
}
</style>
