<script setup lang="ts">
import { ref, computed, onMounted, watch } from "vue";
import { AttachmentsService } from "@/components/service/management/attachmentsService";
import { ProjectService } from "@/components/service/project/projectService";
// ✅ 부모에서 넘겨준 id 수신 + 닫기 이벤트
const props = defineProps<{ id: number | string }>();
const emit = defineEmits<{ (e: "close"): void }>();

// -------- state --------
const loading = ref(false);
const detailRaw = ref<any | null>(null);

const experimentInfo = ref({
  datasetTitle: "-",
  projectName: "-",
  version: "-",
  createdDate: "-",
  createdId: "-",
  modifiedDate: "-",
  modifiedId: "-",
  description: "-",
  fileName: "-",
  fileSize: "-",
});

const downloadObjectName = computed(() => detailRaw.value?.storagePath || "");
const canDownload = computed(() => !!downloadObjectName.value);

async function handleDownload() {
  const key = downloadObjectName.value.trim();
  if (!key) return;

  const res = await AttachmentsService.downloadFile(key);

  const ct = String(res.headers["content-type"] || "").toLowerCase();
  if (ct.includes("application/json")) {
    const text = await (res.data as Blob).text();
    try {
      const json = JSON.parse(text);
      throw new Error(json.message || text);
    } catch {
      throw new Error(text);
    }
  }

  const cd = res.headers["content-disposition"] || "";
  let filename: string | undefined;
  const mUtf8 = cd.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
  const mStd = cd.match(/filename\s*=\s*(?:"([^"]+)"|([^;]+))/i);
  if (mUtf8?.[1]) {
    try {
      filename = decodeURIComponent(mUtf8[1].trim());
    } catch {
      filename = mUtf8[1].trim();
    }
  } else if (mStd) {
    filename = (mStd[1] || mStd[2])?.trim();
  }

  // 2) 헤더가 없거나 못 읽으면: objectName의 basename으로 강제(fallback)
  if (!filename) {
    // key 예: "11fc4121-...-mlflow_pipeline.yaml" 또는 "dir/subdir/11fc...yaml"
    const parts = key.split(/[\\/]/);
    filename = parts[parts.length - 1] || "download.bin";
  }

  const blob = new Blob([res.data]);
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.setAttribute("download", filename);
  document.body.appendChild(a);
  a.click();
  a.remove();
  URL.revokeObjectURL(url);
}

// -------- utils --------
const formatIso = (s?: string) =>
  s ? String(s).replace("T", " ").slice(0, 19) : "-";

const formatBytes = (b?: number) => {
  const n = Number(b);
  if (!Number.isFinite(n) || n < 0) return "-";
  if (n < 1024) return `${n} B`;
  const u = ["KB", "MB", "GB", "TB"];
  let i = -1,
    v = n;
  do {
    v /= 1024;
    i++;
  } while (v >= 1024 && i < u.length - 1);
  return `${v.toFixed(1)} ${u[i]}`;
};

// 백엔드 응답 → 화면 모델
const mapToViewModel = (raw: any) => {
  const projectName =
    raw?.projectName ?? raw?.project?.name ?? raw?.prjNm ?? "-";

  const size = raw?.fileSize ?? raw?.size ?? raw?.length ?? undefined;

  return {
    datasetTitle: raw?.title ?? "-",
    projectName,
    version: raw?.version ?? "-",
    createdDate: formatIso(raw?.regDt),
    createdId: raw?.regUserId ?? "-",
    modifiedDate: formatIso(raw?.modDt),
    modifiedId: raw?.modUserId ?? "-",
    description: raw?.description ?? "-",
    fileName: raw?.originalName ?? "-",
    fileSize: formatBytes(size),
  };
};

async function fetchProjectName(projectId?: number) {
  if (!projectId && projectId !== 0) return;
  try {
    const res = await ProjectService.fetchProjectById(projectId as number);
    const prj = res?.data ?? res;
    experimentInfo.value.projectName = prj?.prjNm ?? prj?.name ?? "-";
  } catch (e) {
    console.warn("[Experiment/View] project fetch fail:", e);
  }
}

const info = computed(() => mapToViewModel(detailRaw.value || {}));

async function fetchDetail(id: number | string) {
  const idNum = typeof id === "string" ? Number(id) : id;
  if (!Number.isFinite(idNum as number)) {
    console.warn("[Datasets/View] invalid id:", id);
    return;
  }

  loading.value = true;
  try {
    const res = await AttachmentsService.view(idNum as number);
    detailRaw.value = res?.data ?? res;

    experimentInfo.value = mapToViewModel(detailRaw.value);
    await fetchProjectName(detailRaw.value?.projectId);
  } catch (e) {
    console.error("[Datasets/View] fetch detail error:", e);
  } finally {
    loading.value = false;
  }
}

// -------- lifecycle --------
onMounted(() => {
  fetchDetail(props.id);
});

watch(
  () => props.id,
  (nv) => {
    if (nv !== undefined && nv !== null && nv !== "") fetchDetail(nv);
  },
);
</script>

<template>
  <v-container fluid class="h-100 pa-5 d-flex flex-column align-center">
    <v-card
      flat
      class="bg-shades-transparent d-flex flex-column justify-center w-100"
    >
      <v-card flat class="bg-shades-transparent w-100">
        <v-card-item class="text-h5 font-weight-bold pt-0 pa-5 pl-0">
          <div class="d-flex flex-row justify-start align-center">
            <div class="text-primary">View Details</div>
          </div>
        </v-card-item>
      </v-card>

      <v-card flat class="bordered-box mb-6 w-100 rounded-lg pa-8">
        <v-card-text class="px-6 pb-6 pt-4">
          <v-row align="center" class="py-2">
            <v-col cols="3" class="text-h6 font-weight-bold"
              >Dataset Title
            </v-col>
            <v-col cols="3" class="pa-2">{{
              experimentInfo.datasetTitle
            }}</v-col>
            <v-col cols="3" class="text-h6 font-weight-bold">Version </v-col>
            <v-col cols="3" class="pa-2">{{ experimentInfo.version }}</v-col>
          </v-row>
          <VDivider class="my-2" />
          <!-- Experiment Name -->
          <v-row align="center" class="py-2">
            <v-col cols="3" class="text-h6 font-weight-bold"
              >Project Name
            </v-col>
            <v-col cols="9" class="pa-2">{{
              experimentInfo.projectName
            }}</v-col>
          </v-row>
          <VDivider class="my-2" />
          <v-row align="center" class="py-2">
            <v-col cols="3" class="text-h6 font-weight-bold"
              >Created Date
            </v-col>
            <v-col cols="3" class="pa-2">{{
              experimentInfo.createdDate
            }}</v-col>
            <v-col cols="3" class="text-h6 font-weight-bold">Created ID </v-col>
            <v-col cols="3" class="pa-2">{{ experimentInfo.createdId }}</v-col>
          </v-row>

          <VDivider class="my-2" />

          <!-- Description -->
          <v-row align="center" class="py-2">
            <v-col cols="3" class="text-h6 font-weight-bold">Description</v-col>
            <v-col cols="9" class="pa-2">{{
              experimentInfo.description
            }}</v-col>
          </v-row>
          <VDivider class="my-2" />
          <v-row align="center" class="py-2">
            <v-col cols="3" class="text-h6 font-weight-bold">File</v-col>
            <v-col cols="9" class="pa-2 d-flex align-center">
              <span class="text-truncate">{{ experimentInfo.fileName }}</span>
              <v-btn
                icon
                variant="text"
                size="small"
                class="ml-2"
                :disabled="!canDownload"
                @click="handleDownload"
                aria-label="download"
              >
                <v-icon>mdi-download</v-icon>
              </v-btn>
            </v-col>
          </v-row>
        </v-card-text>
        <v-sheet class="d-flex justify-end mb-2">
          <v-btn color="primary" @click="emit('close')"> Back to List </v-btn>
        </v-sheet>
      </v-card>
    </v-card>
  </v-container>
</template>

<style scoped>
.v-card-text {
  width: 100% !important;
  border-collapse: collapse;
  /* 전체 테이블 1px 테두리 */
}

.v-card-text th {
  font-size: 20px;
  min-width: 400px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background-color: rgba(255, 255, 255, 0.05);
  font-weight: 600;
  text-align: center;
  white-space: nowrap;
}
.v-card-text td {
  font-size: 16px;
  min-width: 600px;
  padding: 12px 16px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.v-card-text tr:nth-child(odd) {
  background-color: rgba(255, 255, 255, 0.02);
}
</style>
