<script setup lang="ts">
import IconArrowDown from "@/components/atoms/button/IconArrowDown.vue";
import IconArrowUp from "@/components/atoms/button/IconArrowUp.vue";
import IconDeleteBtn from "@/components/atoms/button/IconDeleteBtn.vue";
import IconModifyBtn from "@/components/atoms/button/IconModifyBtn.vue";
import { computed, onBeforeUnmount, onMounted, watch, ref } from "vue";
import { WorkflowService } from "@/components/service/management/workflowService";
import { storage } from "@/utils/storage";
import type { Workflow } from "@/components/models/management/Workflow";
import { storeToRefs } from "pinia";
import { useAutoflowStore } from "@/stores/autoflowStore";
import { kubeflowService } from "@/components/service/management/kubeflowService";
import {
  toKubeflowForm,
  type KubeflowUploadDto,
} from "@/components/models/management/Kubeflow";

const { projectId } = storeToRefs(useAutoflowStore());

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

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

const isEdit = computed(() => props.mode === "edit");

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

// ====== KFP 이름 제한 & 한글 제한 유틸 ======
const KFP_NAME_REGEX = /^[a-z0-9]([-a-z0-9\.]*[a-z0-9])?$/; // 소문자/숫자/.-, 시작/끝 영숫자
const KOREAN_RX = /[ㄱ-ㅎㅏ-ㅣ가-힣]/g;

const sanitizeKfpName = (s: string) => {
  let x = (s ?? "").toLowerCase();
  x = x.replace(/[\s_]+/g, "-"); // 공백/언더스코어 -> 하이픈
  x = x.replace(/[^a-z0-9.-]/g, ""); // 허용 외 문자 제거(한글 포함)
  x = x.replace(/-+/g, "-"); // 하이픈 중복 축소
  x = x.replace(/^[^a-z0-9]+/, ""); // 앞쪽 비허용 제거
  x = x.replace(/[^a-z0-9]+$/, ""); // 뒤쪽 비허용 제거
  return x;
};
const stripKorean = (s: string) => (s ?? "").replace(KOREAN_RX, "");

// 힌트/에러 메시지
const nameHint = ref(
  "허용 문자: 소문자 a–z, 숫자 0–9, '-', '.' (시작/끝은 영숫자). 한글/공백/대문자/언더스코어 불가",
);
const descHint = ref("한글은 사용할 수 없습니다.");
const nameInvalid = computed(
  () => !!form.value.name && !KFP_NAME_REGEX.test(form.value.name),
);
const nameErrorMsg = computed(() =>
  nameInvalid.value
    ? "형식이 올바르지 않습니다. (소문자/숫자, '-', '.', 시작/끝은 영숫자)"
    : "",
);

// 입력 시 자동 정제
function onNameInput(v: string) {
  const cleaned = sanitizeKfpName(v || "");
  if (cleaned !== v) {
    nameHint.value = "허용되지 않는 문자는 자동으로 제거됩니다.";
  } else {
    nameHint.value =
      "허용 문자: 소문자 a–z, 숫자 0–9, '-', '.' (시작/끝은 영숫자)";
  }
  form.value.name = cleaned;
}
function onDescInput(v: string) {
  const cleaned = stripKorean(v || "");
  form.value.description = cleaned;
}

function extractApiErrorMessage(err: any): string {
  const status = err?.response?.status;
  const data = err?.response?.data;
  const raw =
    (typeof data === "string"
      ? data
      : data?.message || data?.error || data?.detail) ||
    err?.message ||
    "";

  const text = String(raw);

  if (
    status === 409 ||
    /already\s*exists|duplicate|이미 존재|중복/i.test(text)
  ) {
    return "같은 이름의 파이프라인이 이미 존재합니다. 다른 이름으로 등록해주세요.";
  }
  if (status === 400 && /name|display[_ ]?name|invalid/i.test(text)) {
    return "이름(name)이 유효하지 않습니다. 공백/특수문자 여부를 확인해주세요.";
  }
  if (status === 401 || status === 403) {
    return "권한이 없거나 로그인 정보가 만료되었습니다. 다시 로그인 후 시도하세요.";
  }
  if (status === 413 || /file too large|payload too large|size/i.test(text)) {
    return "업로드 파일 용량이 너무 큽니다.";
  }
  if (status === 500 && /InvalidUrl|Bad authority|host/i.test(text)) {
    return "서버 설정 오류로 업로드에 실패했습니다. (관리자에게 KFP URL 설정 점검을 요청하세요)";
  }
  return text || `요청에 실패했습니다. (HTTP ${status ?? "Error"})`;
}

const steps = ref([
  { order: 1, stepName: "Data Load", type: "DataPrep", status: "Configured" },
  {
    order: 2,
    stepName: "Preprocessing",
    type: "Preprocess",
    status: "Not Configured",
  },
  {
    order: 3,
    stepName: "Train Model",
    type: "Train",
    status: "Not Configured",
  },
]);

/** form state */
const form = ref({
  name: "",
  description: "",
  file: null as File | null,
});

/** props.editData -> form 바인딩 */
function hydrateFormFromEdit(data: any) {
  if (!data) return;
  // 표시값은 원본을 보여주되, 저장 시 최종 검증/정제
  form.value.name = data.workflowName ?? data.name ?? "";
  form.value.description = data.workflowDescription ?? data.description ?? "";
}
onMounted(() => {
  if (isEdit.value) hydrateFormFromEdit(props.editData);
});
watch(
  () => props.editData,
  (v) => {
    if (isEdit.value) hydrateFormFromEdit(v);
  },
);

/** 시간 포맷 */
const nowLocalIso = (): string => {
  const t = new Date(Date.now() - new Date().getTimezoneOffset() * 60000);
  return t.toISOString().slice(0, 23);
};

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

  // 제출 직전에 한 번 더 정제 & 검증
  form.value.name = sanitizeKfpName(form.value.name);
  form.value.description = stripKorean(form.value.description);

  const name = form.value.name.trim();
  if (!name || !KFP_NAME_REGEX.test(name)) {
    errorMsg.value =
      "Workflow Name 형식이 올바르지 않습니다. (소문자/숫자, '-', '.', 시작/끝은 영숫자)";
    return;
  }

  // 로그인 사용자
  const authObj =
    (typeof storage?.getAuth === "function" ? storage.getAuth() : null) ??
    JSON.parse(localStorage.getItem("autoflow-auth") || "{}");
  const regUserId =
    authObj?.userInfo?.username ??
    authObj?.userinfo?.username ??
    authObj?.username ??
    authObj?.userId ??
    "";

  if (!regUserId) {
    errorMsg.value = "로그인 사용자 정보를 찾을 수 없습니다.";
    return;
  }
  if (!projectId.value) {
    errorMsg.value = "프로젝트가 선택되지 않았습니다.";
    return;
  }

  const now = nowLocalIso();

  try {
    saving.value = true;

    if (isEdit.value) {
      // ===== 수정 =====
      const rawId = props.editData?.id ?? props.editData?.deviceKey;
      const id = Number(rawId);
      if (!id) {
        errorMsg.value = "수정할 ID가 없습니다.";
        return;
      }

      // ① 기존 값 조회
      const viewRes = await WorkflowService.view(id);
      const current = (viewRes?.data ?? viewRes) || {};

      // ② name/description만 변경, 그 외는 기존 값 유지해서 null 덮어쓰기 방지
      const updatePayload = cleanUndefined({
        id,
        name, // 변경
        description: form.value.description?.trim() || "", // 변경

        // ===== 기존 유지 필드 =====
        displayName: current.displayName,
        namespace: current.namespace,
        pipelineId: current.pipelineId,
        kubeflowStatus: current.kubeflowStatus,
        version: current.version,

        regUserId: current.regUserId ?? regUserId,
        projectId: current.projectId ?? projectId.value,
        regDt: current.regDt,
        modDt: now,
      });

      const { data } = await WorkflowService.update(id, updatePayload);
      emit("saved", data);
      emit("close-modal");
    } else {
      // ===== 생성 =====
      if (!form.value.file) {
        errorMsg.value = "업로드할 파일을 선택하세요.";
        return;
      }
      const dto: KubeflowUploadDto = {
        name,
        display_name: name,
        description: form.value.description?.trim() || "",
        namespace: "default",
        regUserId,
        projectId: projectId.value!,
        uploadfile: form.value.file,
      };
      const fd = toKubeflowForm(dto);
      const { data } = await kubeflowService.upload(fd);
      emit("saved", data);
      emit("close-modal");
    }
  } catch (e: any) {
    console.error("워크플로우 저장 실패:", e);
    errorMsg.value = extractApiErrorMessage(e);
  } finally {
    saving.value = false;
  }
}

/** undefined 필드는 제거해서 불필요한 키 전송 방지 */
function cleanUndefined<T extends Record<string, any>>(obj: T): T {
  return Object.fromEntries(
    Object.entries(obj).filter(([, v]) => v !== undefined),
  ) as T;
}

/** ESC로 닫기 */
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>
    <!-- 타이틀 -->
    <v-card-title
      class="text-white font-weight-bold text-h6"
      style="background-color: #1976d2"
    >
      {{ isEdit ? "Edit Workflow" : "Create Workflow" }}
    </v-card-title>

    <v-card-text class="pa-6">
      <div class="text-subtitle-1 font-weight-medium mb-4">
        Workflow Information
      </div>

      <v-form @submit.prevent="submit">
        <!-- Name -->
        <div class="mb-5">
          <label class="text-subtitle-2 font-weight-medium mb-1 d-block">
            Workflow Name
          </label>
          <v-text-field
            v-model="form.name"
            variant="outlined"
            :disabled="saving"
            dense
            hide-details="auto"
            persistent-hint
            :hint="nameHint"
            :error="nameInvalid"
            :error-messages="nameErrorMsg"
            @update:model-value="onNameInput"
            required
          />
        </div>

        <!-- Description -->
        <div class="mb-5">
          <label class="text-subtitle-2 font-weight-medium mb-1 d-block">
            Workflow Description
          </label>
          <v-textarea
            v-model="form.description"
            variant="outlined"
            :disabled="saving"
            rows="3"
            dense
            hide-details="auto"
            persistent-hint
            :hint="descHint"
            @update:model-value="onDescInput"
          />
        </div>

        <!-- Upload File -->
        <div class="mb-5">
          <label class="text-subtitle-2 font-weight-medium mb-1 d-block">
            Upload File
          </label>
          <v-file-input
            v-model="form.file"
            accept=".zip,.tar,.gz,.yaml,.yml"
            show-size
            variant="outlined"
            dense
            hide-details
            placeholder="파이프라인 파일 선택"
          />
        </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" @click="submit">
        {{ isEdit ? "Update" : "Save" }}
      </v-btn>
      <v-btn
        text
        class="white--text"
        :disabled="saving"
        @click="$emit('close-modal')"
      >
        Close
      </v-btn>
    </v-card-actions>
  </v-card>
</template>
