import dayjs from "dayjs";
import { message } from "@/utils/message";
import { addDialog } from "@/components/ReDialog";
import { usePublicHooks } from "@/views/system/hooks";
import QRCode from "qrcode";
import { deviceDetection } from "@pureadmin/utils";
import type { PaginationProps } from "@pureadmin/table";
import { getReplenisherList,
  createReplenisher,
  updateReplenisher,
  updateReplenisherStatus,
  deleteReplenisher,
  getBoundDevices,
  bindDevices,
  unbindDevice,
  generateBindingCode
} from "@/api/replenisher";
import { getEnabledShops, getShopDevices } from "@/api/shop";
import {
  type Ref,
  h,
  ref,
  computed,
  toRaw,
  reactive,
  onMounted
} from "vue";
import {
  ElForm,
  ElInput,
  ElFormItem,
  ElSelect,
  ElOption,
  ElRadioGroup,
  ElRadioButton,
  ElButton,
  ElTag,
  ElMessageBox,
  ElPopconfirm
} from "element-plus";
import type { ReplenisherFormItem, ReplenisherSearchForm, ShopWithDevices } from "./types";

export function useReplenisher(tableRef: Ref) {
  const form = reactive<ReplenisherSearchForm>({
    keyword: "",
    status: ""
  });
  const dialogForm = reactive<any>({
    id: undefined,
    name: "",
    phone: "",
    employeeId: "",
    status: 1
  });
  const formRef = ref();
  const ruleFormRef = ref();
  const dataList = ref([]);
  const loading = ref(true);
  const switchLoadMap = ref({});
  const { switchStyle } = usePublicHooks();
  const pagination = reactive<PaginationProps>({
    total: 0,
    pageSize: 10,
    currentPage: 1,
    background: true
  });

  const columns: TableColumnList = [
    {
      label: "补货员ID",
      prop: "id",
      width: 90
    },
    {
      label: "姓名",
      prop: "name",
      minWidth: 100
    },
    {
      label: "手机号",
      prop: "phone",
      minWidth: 130
    },
    {
      label: "工号",
      prop: "employeeId",
      minWidth: 100
    },
    {
      label: "绑定设备数",
      prop: "boundDeviceCount",
      width: 110
    },
    {
      label: "状态",
      prop: "status",
      minWidth: 100,
      cellRenderer: scope => (
        <el-switch
          size={scope.props.size === "small" ? "small" : "default"}
          loading={switchLoadMap.value[scope.index]?.loading}
          v-model={scope.row.status}
          active-value={1}
          inactive-value={0}
          active-text="正常"
          inactive-text="禁用"
          inline-prompt
          style={switchStyle.value}
          onChange={() => onChange(scope as any)}
        />
      )
    },
    {
      label: "累计任务",
      prop: "totalTasks",
      width: 100
    },
    {
      label: "最后任务时间",
      prop: "lastTaskTime",
      minWidth: 160,
      formatter: ({ lastTaskTime }) =>
        lastTaskTime ? dayjs(lastTaskTime).format("YYYY-MM-DD HH:mm:ss") : "-"
    },
    {
      label: "创建时间",
      prop: "createTime",
      minWidth: 160,
      formatter: ({ createTime }) =>
        createTime ? dayjs(createTime).format("YYYY-MM-DD HH:mm:ss") : "-"
    },
    {
      label: "操作",
      fixed: "right",
      width: 220,
      slot: "operation"
    }
  ];

  // 状态切换
  function onChange({ row, index }) {
    ElMessageBox.confirm(
      `确认要<strong>${row.status === 0 ? "禁用" : "启用"}</strong>补货员<strong style='color:var(--el-color-primary)'>${row.name}</strong>吗?`,
      "系统提示",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        dangerouslyUseHTMLString: true,
        draggable: true
      }
    )
      .then(async () => {
        switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
          loading: true
        });
        try {
          const res = await updateReplenisherStatus(row.id, { status: row.status });
          if (res.code === 200) {
            message(`已${row.status === 0 ? "禁用" : "启用"}补货员 ${row.name}`, {
              type: "success"
            });
          } else {
            row.status = row.status === 0 ? 1 : 0;
            message(res.message || "操作失败", { type: "error" });
          }
        } catch {
          row.status = row.status === 0 ? 1 : 0;
          message("操作失败", { type: "error" });
        } finally {
          setTimeout(() => {
            switchLoadMap.value[index] = Object.assign({}, switchLoadMap.value[index], {
              loading: false
            });
          }, 300);
        }
      })
      .catch(() => {
        row.status = row.status === 0 ? 1 : 0;
      });
  }

  // 删除
  async function handleDelete(row: ReplenisherFormItem) {
    try {
      const res = await deleteReplenisher(row.id);
      if (res.code === 200) {
        message(`已成功删除补货员 ${row.name}`, { type: "success" });
        onSearch();
      } else {
        message(res.message || "删除失败", { type: "error" });
      }
    } catch (error) {
      message("删除失败", { type: "error" });
    }
  }

  // 设备绑定管理（门店设备树）
  const bindDialogVisible = ref(false);
  const currentReplenisher = ref<ReplenisherFormItem>(null);
  const deviceLoading = ref(false);
  const shopDeviceTree = ref<ShopWithDevices[]>([]);
  const loadingShopTree = ref(false);
  const selectedDeviceIds = ref<Set<string>>(new Set());
  const origBoundDeviceIds = ref<Set<string>>(new Set());
  const shopSearchKeyword = ref("");

  // 按搜索词过滤门店
  const filteredShopTree = computed(() => {
    const kw = shopSearchKeyword.value.trim().toLowerCase();
    if (!kw) return shopDeviceTree.value;
    return shopDeviceTree.value.filter(
      s => s.name.toLowerCase().includes(kw) || s.address.toLowerCase().includes(kw)
    );
  });

  // 全部设备是否已选中
  const allDevicesCount = computed(() =>
    shopDeviceTree.value.reduce((sum, s) => sum + s.devices.length, 0)
  );
  const isAllSelected = computed(() =>
    allDevicesCount.value > 0 && selectedDeviceIds.value.size === allDevicesCount.value
  );

  function toggleSelectAll() {
    if (isAllSelected.value) {
      selectedDeviceIds.value = new Set();
    } else {
      const all = new Set<string>();
      shopDeviceTree.value.forEach(s => s.devices.forEach(d => all.add(d.deviceId)));
      selectedDeviceIds.value = all;
    }
  }

  function resetShopSearch() {
    shopSearchKeyword.value = "";
  }

  async function openBindDialog(row: ReplenisherFormItem) {
    currentReplenisher.value = row;
    bindDialogVisible.value = true;
    loadingShopTree.value = true;

    try {
      // 并行获取所有启用的门店 + 已绑定的设备
      const [shopsRes, boundRes] = await Promise.all([
        getEnabledShops(),
        getBoundDevices(row.id)
      ]);

      const shops: any[] = shopsRes.data || [];
      const boundDevices: string[] = boundRes.data || [];
      selectedDeviceIds.value = new Set(boundDevices);
      origBoundDeviceIds.value = new Set(boundDevices);

      // 并行获取每个门店的设备
      const shopPromises = shops.map(async (shop: any) => {
        try {
          const devRes = await getShopDevices(shop.id);
          const devices: any[] = devRes.data || [];
          return {
            id: shop.id,
            name: shop.name,
            address: shop.address || "",
            devices: devices.map((d: any) => ({
              deviceId: d.deviceId,
              name: d.name
            })),
            expanded: false,
            loading: false
          } as ShopWithDevices;
        } catch {
          return {
            id: shop.id,
            name: shop.name,
            address: shop.address || "",
            devices: [],
            expanded: false,
            loading: false
          } as ShopWithDevices;
        }
      });

      shopDeviceTree.value = await Promise.all(shopPromises);
    } catch (error) {
      console.error("加载门店设备数据失败:", error);
      message("加载数据失败", { type: "error" });
    } finally {
      loadingShopTree.value = false;
    }
  }

  function toggleDeviceSelect(deviceId: string) {
    const newSet = new Set(selectedDeviceIds.value);
    if (newSet.has(deviceId)) {
      newSet.delete(deviceId);
    } else {
      newSet.add(deviceId);
    }
    selectedDeviceIds.value = newSet;
  }

  function toggleShopSelectAll(shop: ShopWithDevices) {
    const newSet = new Set(selectedDeviceIds.value);
    const allSelected = shop.devices.every(d => newSet.has(d.deviceId));
    if (allSelected) {
      shop.devices.forEach(d => newSet.delete(d.deviceId));
    } else {
      shop.devices.forEach(d => newSet.add(d.deviceId));
    }
    selectedDeviceIds.value = newSet;
  }

  function getShopSelectState(shop: ShopWithDevices): "all" | "partial" | "none" {
    if (shop.devices.length === 0) return "none";
    const selected = shop.devices.filter(d => selectedDeviceIds.value.has(d.deviceId)).length;
    if (selected === shop.devices.length) return "all";
    if (selected > 0) return "partial";
    return "none";
  }

  async function handleConfirmBind() {
    if (!currentReplenisher.value) return;

    const origSet = origBoundDeviceIds.value;
    const newSet = selectedDeviceIds.value;

    const toBind = [...newSet].filter(id => !origSet.has(id));
    const toUnbind = [...origSet].filter(id => !newSet.has(id));

    if (toBind.length === 0 && toUnbind.length === 0) {
      message("未做任何变更", { type: "info" });
      return;
    }

    deviceLoading.value = true;
    try {
      if (toBind.length > 0) {
        const res = await bindDevices(currentReplenisher.value.id, { deviceIds: toBind });
        if (res.code !== 200) {
          message("绑定设备失败: " + (res.message || ""), { type: "error" });
          return;
        }
      }

      if (toUnbind.length > 0) {
        await Promise.all(toUnbind.map(deviceId =>
          unbindDevice(currentReplenisher.value.id, deviceId)
        ));
      }

      message(`设备绑定更新完成（绑定${toBind.length}台，解绑${toUnbind.length}台）`, { type: "success" });
      bindDialogVisible.value = false;
      onSearch();
    } catch (error) {
      message("操作失败", { type: "error" });
    } finally {
      deviceLoading.value = false;
    }
  }

  // 绑定码生成弹窗
  const bindingDialogVisible = ref(false);
  const bindingCodeData = reactive<{
    replenisherName: string;
    bindingCode: string;
    qrCodeDataUrl: string;
  }>({
    replenisherName: "",
    bindingCode: "",
    qrCodeDataUrl: ""
  });
  const generatingCode = ref(false);

  function openBindingCodeDialog(row: ReplenisherFormItem) {
    // 已绑定微信的补货员无需生成绑定码，只提示不弹窗
    if (row.wechatOpenid) {
      message("该补货员已绑定微信，无需重新生成绑定码", { type: "info" });
      return;
    }
    currentReplenisher.value = row;
    bindingCodeData.replenisherName = row.name;
    bindingCodeData.bindingCode = "";
    bindingCodeData.qrCodeDataUrl = "";
    bindingDialogVisible.value = true;
    handleGenerateAndShowBindingCode(row);
  }

  async function handleGenerateAndShowBindingCode(row: ReplenisherFormItem) {
    if (!row || !row.id) {
      message("补货员信息不完整", { type: "error" });
      return;
    }
    generatingCode.value = true;
    try {
      // 检查是否已绑定微信
      if (row.wechatOpenid) {
        message("该补货员已绑定微信，无需重新生成绑定码", { type: "warning" });
        return;
      }

      const res = await generateBindingCode(row.id);
      if (res.code === 200 && res.data?.bindingCode) {
        const code = res.data.bindingCode;
        bindingCodeData.bindingCode = code;

        // 生成二维码（将绑定码编码为二维码，补货员可在小程序登录页扫码识别）
        try {
          bindingCodeData.qrCodeDataUrl = await QRCode.toDataURL(code, {
            width: 280,
            margin: 2,
            color: {
              dark: "#1e293b",
              light: "#ffffff"
            }
          });
        } catch (qrErr) {
          console.error("生成二维码失败:", qrErr);
          bindingCodeData.qrCodeDataUrl = "";
        }

        // 刷新列表更新 wechatOpenid 状态
        onSearch();
      } else {
        message(res.message || "生成绑定码失败", { type: "error" });
      }
    } catch (error) {
      console.error("生成绑定码失败:", error);
      message("生成绑定码失败", { type: "error" });
    } finally {
      generatingCode.value = false;
    }
  }

  // 分割绑定码，每4位一组加空格显示
  function formatBindingCode(code: string): string {
    if (!code) return "";
    return code.replace(/(.{4})/g, "$1 ").trim();
  }

  // 复制绑定码
  function copyBindingCode() {
    const code = bindingCodeData.bindingCode;
    if (!code) return;
    navigator.clipboard.writeText(code).then(() => {
      message("绑定码已复制", { type: "success" });
    }).catch(() => {
      // 备用方式
      const textarea = document.createElement("textarea");
      textarea.value = code;
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand("copy");
      document.body.removeChild(textarea);
      message("绑定码已复制", { type: "success" });
    });
  }

  // 分页
  function handleSizeChange(val: number) {
    pagination.pageSize = val;
    onSearch();
  }

  function handleCurrentChange(val: number) {
    pagination.currentPage = val;
    onSearch();
  }

  // 搜索
  async function onSearch() {
    loading.value = true;
    try {
      const searchParams: any = {
        page: pagination.currentPage,
        pageSize: pagination.pageSize
      };
      if (form.keyword) searchParams.keyword = form.keyword;
      if (form.status) searchParams.status = form.status;

      const { data } = await getReplenisherList(searchParams);
      if (data) {
        dataList.value = data.list || [];
        pagination.total = Number(data.total) || 0;
      }
    } catch (error) {
      console.error("获取补货员列表失败:", error);
    } finally {
      setTimeout(() => {
        loading.value = false;
      }, 300);
    }
  }

  // 重置表单
  const resetForm = formEl => {
    if (!formEl) return;
    formEl.resetFields();
    pagination.currentPage = 1;
    onSearch();
  };

  // 打开弹窗
  function openDialog(title = "新增", row?: ReplenisherFormItem) {
    // 初始化对话框表单数据
    dialogForm.id = row?.id;
    dialogForm.name = row?.name ?? "";
    dialogForm.phone = row?.phone ?? "";
    dialogForm.employeeId = row?.employeeId ?? "";
    dialogForm.status = row?.status ?? 1;
    addDialog({
      title: `${title}补货员`,
      props: {
        formInline: {
          id: row?.id,
          name: row?.name ?? "",
          phone: row?.phone ?? "",
          employeeId: row?.employeeId ?? "",
          status: row?.status ?? 1
        }
      },
      width: "40%",
      draggable: true,
      fullscreen: deviceDetection(),
      fullscreenIcon: true,
      closeOnClickModal: false,
      contentRenderer: () => (
        <ElForm ref={ruleFormRef} model={dialogForm} label-width="100px">
          <ElFormItem
            label="姓名"
            prop="name"
            rules={[{ required: true, message: "请输入补货员姓名", trigger: "blur" }]}
          >
            <ElInput
              v-model={dialogForm.name}
              placeholder="请输入补货员姓名"
              clearable
            />
          </ElFormItem>
          <ElFormItem
            label="手机号"
            prop="phone"
          >
            <ElInput v-model={dialogForm.phone} placeholder="请输入手机号" clearable />
          </ElFormItem>
          <ElFormItem
            label="工号"
            prop="employeeId"
          >
            <ElInput v-model={dialogForm.employeeId} placeholder="请输入工号" clearable />
          </ElFormItem>
          <ElFormItem label="状态" prop="status">
            <ElRadioGroup v-model={dialogForm.status}>
              <ElRadioButton value={1}>正常</ElRadioButton>
              <ElRadioButton value={0}>禁用</ElRadioButton>
            </ElRadioGroup>
          </ElFormItem>
        </ElForm>
      ),
      beforeSure: async (done) => {
        const valid = await ruleFormRef.value.validate().catch(() => false);
        if (!valid) return;

        try {
          if (title === "新增") {
            const res = await createReplenisher({
              name: dialogForm.name,
              phone: dialogForm.phone || undefined,
              employeeId: dialogForm.employeeId || undefined
            });
            if (res.code === 200) {
              message(`新增补货员 ${dialogForm.name} 成功`, { type: "success" });
              done();
              onSearch();
            } else {
              message(res.message || "新增失败", { type: "error" });
            }
          } else {
            const res = await updateReplenisher(row.id, {
              name: dialogForm.name,
              phone: dialogForm.phone || undefined,
              employeeId: dialogForm.employeeId || undefined,
              status: dialogForm.status
            });
            if (res.code === 200) {
              message(`修改补货员 ${dialogForm.name} 成功`, { type: "success" });
              done();
              onSearch();
            } else {
              message(res.message || "修改失败", { type: "error" });
            }
          }
        } catch (error) {
          message("操作失败", { type: "error" });
        }
      }
    });
  }

  onMounted(() => {
    onSearch();
  });

  return {
    form,
    loading,
    columns,
    dataList,
    pagination,
    onSearch,
    resetForm,
    openDialog,
    handleDelete,
    openBindDialog,
    openBindingCodeDialog,
    bindingDialogVisible,
    bindingCodeData,
    generatingCode,
    formatBindingCode,
    copyBindingCode,
    bindDialogVisible,
    currentReplenisher,
    deviceLoading,
    shopDeviceTree,
    loadingShopTree,
    selectedDeviceIds,
    toggleDeviceSelect,
    toggleShopSelectAll,
    getShopSelectState,
    handleConfirmBind,
    shopSearchKeyword,
    filteredShopTree,
    allDevicesCount,
    isAllSelected,
    toggleSelectAll,
    resetShopSearch,
    handleSizeChange,
    handleCurrentChange
  };
}
