<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import { ExperimentService } from "@/components/service/management/ExperimentService";
import { ExperimentCreateDto } from "@/components/models/management/Experiments";
import type { AxiosError } from "axios"; // ✅ 추가

type SelectedData = {
  name?: string;
  description?: string;
  username?: string;
  projectId?: number | null;
};

const props = defineProps<{
  editData: SelectedData | null;
  mode: "create" | "edit";
}>();

const emit = defineEmits<{
  (e: "close-modal"): void;
  (e: "saved", v: any): void;
}>();

const saving = ref(false);
const errorMsg = ref("");

const form = ref({
  name: "",
  description: "",
  regUserId: "",
  projectId: null as number | null,
});

// 부모가 준 값으로 즉시 초기화
watch(
  () => props.editData,
  (v) => {
    form.value.name = v?.name ?? "";
    form.value.description = v?.description ?? "";
    form.value.regUserId = v?.username ?? "";
    form.value.projectId = v?.projectId ?? null;
  },
  { immediate: true },
);

const nowIso = () => new Date().toISOString();

/** ✅ 에러를 사용자 친화적으로 변환 */
function parseApiError(err: unknown): string {
  const ax = err as AxiosError<any>;

  // 네트워크/타임아웃
  if (!ax?.response) {
    if ((ax as any)?.code === "ECONNABORTED")
      return "요청 시간이 초과되었습니다. 잠시 후 다시 시도해 주세요.";
    return "네트워크 오류가 발생했습니다. 연결 상태를 확인해 주세요.";
  }

  const { status, data } = ax.response;
  const serverMsg = (
    data?.message ||
    data?.error ||
    data?.detail ||
    data?.msg ||
    ""
  ).toString();

  // 중복 이름(409 또는 메시지 키워드)
  if (status === 409 || /duplicate|exists|이미.*존재|중복/i.test(serverMsg)) {
    return "동일한 이름의 Experiment가 이미 존재합니다. 다른 이름을 사용해 주세요.";
  }

  // 유효성 오류(400/422) - 필드 에러 배열 처리
  if (status === 400 || status === 422) {
    const fieldErrors =
      data?.errors || data?.fieldErrors || data?.validationErrors;
    if (Array.isArray(fieldErrors) && fieldErrors.length) {
      const f = fieldErrors[0];
      if (typeof f === "string") return f;
      if (f?.defaultMessage) return f.defaultMessage;
      if (f?.message) return f.message;
      if (f?.field && f?.error) return `${f.field}: ${f.error}`;
    }
    if (serverMsg) return serverMsg;
    return "입력값이 올바르지 않습니다. 필수 항목을 확인해 주세요.";
  }

  // 인증/권한
  if (status === 401) return "로그인이 필요합니다.";
  if (status === 403) return "이 작업에 대한 권한이 없습니다.";

  // 리소스 없음
  if (status === 404) return "대상을 찾을 수 없습니다.";

  // 용량/요청 크기
  if (status === 413) return "요청 용량 제한을 초과했습니다.";

  // 그 외 서버 에러
  if (status >= 500)
    return (
      serverMsg || "서버 내부 오류가 발생했습니다. 관리자에게 문의해 주세요."
    );
  return serverMsg || "요청 처리 중 오류가 발생했습니다.";
}

async function submit() {
  errorMsg.value = "";

  const name = (form.value.name || "").trim();
  const description = (form.value.description || "").trim();
  const regUserId = (form.value.regUserId || "").trim();
  const projectId = Number(form.value.projectId);

  if (!name) {
    errorMsg.value = "Experiment Name은 필수입니다.";
    return;
  }
  if (!regUserId) {
    errorMsg.value = "로그인 사용자(regUserId) 정보를 찾을 수 없습니다.";
    return;
  }
  if (!Number.isFinite(projectId) || projectId <= 0) {
    errorMsg.value = "프로젝트가 선택되지 않았습니다.";
    return;
  }

  const now = nowIso();

  const payload: ExperimentCreateDto = {
    kubeFlowId: null,
    mlFlowId: null,
    name,
    displayName: name,
    description,
    artifactLocation: null,
    lifecycleStage: "active",
    storageState: "available",
    kubeflowCreatedAt: null,
    mlflowCreatedAt: null,
    lastUpdateTime: null,
    lastRunCreatedAt: null,
    regUserId,
    projectId,
  };

  try {
    saving.value = true;
    const res = await ExperimentService.add(payload);
    emit("saved", res?.data ?? { ok: true });
    emit("close-modal");
  } catch (e) {
    console.error("[Experiment] 저장 실패:", e);
    errorMsg.value = parseApiError(e); // ✅ 바뀐 부분
  } finally {
    saving.value = false;
  }
}

function onEsc(e: KeyboardEvent) {
  if (e.key === "Escape") emit("close-modal");
}
onMounted(() => window.addEventListener("keydown", onEsc));
onBeforeUnmount(() => window.removeEventListener("keydown", onEsc));
</script>

<template>
  <v-card class="rounded-lg overflow-hidden">
    <v-card-title
      class="text-white font-weight-bold text-h6"
      style="background-color: #1976d2"
    >
      Create Experiment
    </v-card-title>

    <v-card-text class="pa-6">
      <v-form @submit.prevent="submit">
        <div class="mb-5">
          <label class="text-subtitle-2 font-weight-medium mb-1 d-block"
            >Experiment Name</label
          >
          <v-text-field
            v-model="form.name"
            variant="outlined"
            :disabled="saving"
            dense
            hide-details
            required
          />
        </div>

        <div class="mb-5">
          <label class="text-subtitle-2 font-weight-medium mb-1 d-block"
            >Description</label
          >
          <v-textarea
            v-model="form.description"
            variant="outlined"
            rows="3"
            :disabled="saving"
            dense
            hide-details
          />
        </div>

        <div v-if="errorMsg" class="mt-3 text-error">{{ errorMsg }}</div>
      </v-form>
    </v-card-text>

    <v-card-actions class="justify-end" style="padding: 16px 24px">
      <v-btn
        color="success"
        :loading="saving"
        :disabled="saving"
        @click="submit"
        >Save</v-btn
      >
      <v-btn
        text
        class="white--text"
        :disabled="saving"
        @click="$emit('close-modal')"
        >Close</v-btn
      >
    </v-card-actions>
  </v-card>
</template>
