<template>
  <dialog class="modal" :class="{ 'modal-open': visible }">
    <div class="modal-box w-96 max-w-md">
      <h3 class="text-lg font-bold mb-4">新增实验板</h3>

      <!-- 步骤1: 输入板卡名称 -->
      <div v-if="currentStep === 'input'" class="space-y-4">
        <form @submit.prevent="handleSubmit">
          <!-- 实验板名称 -->
          <div class="form-control">
            <label class="label">
              <span class="label-text"
                >实验板名称 <span class="text-error">*</span></span
              >
            </label>
            <input
              v-model="form.name"
              type="text"
              placeholder="请输入实验板名称"
              class="input input-bordered"
              :class="{ 'input-error': errors.name }"
              required
            />
            <label v-if="errors.name" class="label">
              <span class="label-text-alt text-error">{{ errors.name }}</span>
            </label>
          </div>

          <!-- 操作按钮 -->
          <div class="modal-action">
            <button
              type="button"
              class="btn btn-ghost"
              @click="handleCancel"
              :disabled="isSubmitting"
            >
              取消
            </button>
            <button
              type="submit"
              class="btn btn-primary"
              :class="{ loading: isSubmitting }"
              :disabled="isSubmitting"
            >
              {{ isSubmitting ? "添加中..." : "确认添加" }}
            </button>
          </div>
        </form>
      </div>

      <!-- 步骤2: 等待配对 -->
      <div v-else-if="currentStep === 'pairing'" class="space-y-4">
        <div class="text-center">
          <div class="alert alert-info">
            <div class="flex items-center">
              <svg
                class="w-5 h-5 mr-2"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
                />
              </svg>
              <span>请打开实验板配对模式</span>
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="modal-action">
          <button
            type="button"
            class="btn btn-ghost"
            @click="handleCancelPairing"
            :disabled="isConfiguring"
          >
            取消
          </button>
          <button
            type="button"
            class="btn btn-primary"
            @click="handlePairingConfirm"
            :disabled="isConfiguring"
          >
            已开启
          </button>
        </div>
      </div>

      <!-- 步骤3: 配置网络 -->
      <div v-else-if="currentStep === 'configuring'" class="space-y-4">
        <div class="text-center">
          <div class="alert alert-warning">
            <div class="flex items-center">
              <div class="loading loading-spinner loading-sm mr-2"></div>
              <span>正在分配网络...</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 步骤4: 显示配置结果 -->
      <div v-else-if="currentStep === 'result'" class="space-y-4">
        <div class="text-center">
          <div class="alert alert-success">
            <div class="flex items-center">
              <svg
                class="w-5 h-5 mr-2"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  stroke-linecap="round"
                  stroke-linejoin="round"
                  stroke-width="2"
                  d="M5 13l4 4L19 7"
                />
              </svg>
              <span>实验板配置成功</span>
            </div>
          </div>
        </div>

        <!-- 网络配置信息 -->
        <div v-if="networkConfig" class="space-y-2">
          <h4 class="font-semibold">网络配置信息：</h4>
          <div class="bg-base-200 p-3 rounded">
            <div class="text-sm space-y-1">
              <div>
                <span class="font-medium">主机IP:</span>
                {{ networkConfig.hostIP }}
              </div>
              <div>
                <span class="font-medium">板卡IP:</span>
                {{ networkConfig.boardIP }}
              </div>
              <div>
                <span class="font-medium">主机MAC:</span>
                {{ networkConfig.hostMAC }}
              </div>
              <div>
                <span class="font-medium">板卡MAC:</span>
                {{ networkConfig.boardMAC }}
              </div>
            </div>
          </div>
        </div>

        <!-- 操作按钮 -->
        <div class="modal-action">
          <button type="button" class="btn btn-primary" @click="handleSuccess">
            确认
          </button>
        </div>
      </div>
    </div>

    <!-- 点击背景关闭 -->
    <form method="dialog" class="modal-backdrop">
      <button type="button" @click="handleCancel">close</button>
    </form>
  </dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, watch } from "vue";
import { AuthManager } from "../../utils/AuthManager";
import { useAlertStore } from "../../components/Alert";
import {
  BoardStatus,
  DataClient,
  NetConfigClient,
  type NetworkConfigDto,
} from "../../APIClient";
import { useRequiredInjection } from "@/utils/Common";
import { useBoardManager } from "@/utils/BoardManager";

// Props 和 Emits
interface Props {
  visible: boolean;
}

interface Emits {
  (e: "update:visible", value: boolean): void;
  (e: "success"): void;
}

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

// 使用 Alert
const alertStore = useAlertStore();

const boardManager = useRequiredInjection(useBoardManager);

// 当前步骤
const currentStep = ref<"input" | "pairing" | "configuring" | "result">(
  "input",
);

// 表单数据
const form = reactive({
  name: "Board1",
});

// 表单错误
const errors = reactive({
  name: "",
});

// 状态
const isSubmitting = ref(false);
const isConfiguring = ref(false);

// 添加的板卡信息
const addedBoardId = ref<string>("");
const networkConfig = ref<NetworkConfigDto | null>(null);

// 验证表单
function validateForm(): boolean {
  // 清空之前的错误
  errors.name = "";

  let isValid = true;

  // 验证名称
  if (!form.name.trim()) {
    errors.name = "请输入实验板名称";
    isValid = false;
  } else if (form.name.trim().length < 2) {
    errors.name = "实验板名称至少需要2个字符";
    isValid = false;
  } else if (form.name.trim().length > 50) {
    errors.name = "实验板名称不能超过50个字符";
    isValid = false;
  }

  return isValid;
}

// 重置表单
function resetForm() {
  form.name = "Board1";
  errors.name = "";
  currentStep.value = "input";
  addedBoardId.value = "";
  networkConfig.value = null;
}

// 处理取消
function handleCancel() {
  if (!isSubmitting.value && !isConfiguring.value) {
    emit("update:visible", false);
    resetForm();
  }
}

// 处理提交
async function handleSubmit() {
  if (!validateForm()) {
    return;
  }

  isSubmitting.value = true;

  try {
    const dataClient = AuthManager.createClient(DataClient);

    // 添加板卡到数据库
    const boardId = await dataClient.addBoard(form.name.trim());

    if (boardId) {
      addedBoardId.value = boardId;
      currentStep.value = "pairing";
      alertStore?.success("板卡添加成功，请开启配对模式");
    } else {
      alertStore?.error("板卡添加失败");
    }
  } catch (error) {
    console.error("添加实验板失败:", error);
    alertStore?.error("添加实验板失败");
  } finally {
    isSubmitting.value = false;
  }
}

// 处理取消配对
async function handleCancelPairing() {
  if (!addedBoardId.value) return;

  try {
    const dataClient = AuthManager.createClient(DataClient);

    // 删除添加的板卡
    await dataClient.deleteBoard(addedBoardId.value);

    alertStore?.info("已取消添加实验板");
    emit("update:visible", false);
    resetForm();
  } catch (error) {
    console.error("删除板卡失败:", error);
    alertStore?.error("删除板卡失败");
  }
}

// 处理配对确认
async function handlePairingConfirm() {
  if (!addedBoardId.value) return;

  isConfiguring.value = true;
  currentStep.value = "configuring";

  try {
    // 通过 AuthManager 获取认证的客户端
    const dataClient = AuthManager.createClient(DataClient);
    const netConfigClient = AuthManager.createClient(NetConfigClient);

    // 获取数据库中对应分配的板卡信息
    const boardInfo = await dataClient.getBoardByID(addedBoardId.value);

    if (!boardInfo) {
      throw new Error("无法获取板卡信息");
    }

    // 更新主机IP和主机MAC
    await netConfigClient.updateHostIP();
    await netConfigClient.updateHostMAC();

    // 设置板卡IP和MAC
    await netConfigClient.setBoardIP(boardInfo.ipAddr);
    await netConfigClient.setBoardMAC(boardInfo.macAddr);

    // 更新板卡状态为可用
    if (
      (await dataClient.updateBoardStatus(
        boardInfo.id,
        BoardStatus.Available,
      )) != 1
    ) {
      throw new Error("无法更新板卡状态");
    }

    if (!(await boardManager.getAllBoards()).success) {
      alertStore?.error("无法获取板卡列表");
    }

    // 获取实验板网络信息
    const networkInfo = await netConfigClient.getNetworkConfig();

    if (networkInfo) {
      networkConfig.value = networkInfo;
      currentStep.value = "result";
      alertStore?.success("实验板配置成功");
    } else {
      throw new Error("无法获取网络配置信息");
    }
  } catch (error) {
    console.error("配置实验板失败:", error);
    alertStore?.error("配置实验板失败");

    // 配置失败，删除数据库中的板卡信息
    try {
      const dataClient = AuthManager.createClient(DataClient);
      await dataClient.deleteBoard(addedBoardId.value);
    } catch (deleteError) {
      console.error("删除板卡失败:", deleteError);
    }

    // 返回输入步骤
    currentStep.value = "input";
  } finally {
    isConfiguring.value = false;
  }
}

// 处理成功
function handleSuccess() {
  emit("success");
  emit("update:visible", false);
  resetForm();
}

// 监听对话框显示状态，重置表单
watch(
  () => props.visible,
  (newVisible) => {
    if (newVisible) {
      resetForm();
    }
  },
);
</script>

<style scoped lang="postcss">
@import "@/assets/main.css";

.form-control {
  @apply w-full;
}

.label-text {
  @apply font-medium;
}

.input-error {
  @apply border-error;
}

.text-error {
  @apply text-red-500;
}

.loading {
  @apply opacity-50 cursor-not-allowed;
}

.alert {
  @apply rounded-lg p-4;
}

.alert-info {
  @apply bg-blue-50 text-blue-800 border border-blue-200;
}

.alert-warning {
  @apply bg-yellow-50 text-yellow-800 border border-yellow-200;
}

.alert-success {
  @apply bg-green-50 text-green-800 border border-green-200;
}
</style>
