<script setup lang="ts">
// 프로젝트 설정 — 일반 설정 + 위험 구역 (관리자 전용)
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter, RouterLink } from 'vue-router'
import AppShell from '@/layouts/AppShell.vue'
import ProjectHeader from '@/components/ProjectHeader.vue'
import ProjectTabs from '@/components/ProjectTabs.vue'
import { useProjectStore } from '@/stores/project.store'
import { useDialog } from '@/composables/useDialog'
import { type Project } from '@/mock/relay.mock'

const route = useRoute()
const router = useRouter()
const projectId = computed(() => String(route.params.projectId))
const projectStore = useProjectStore()
const dialog = useDialog()

const repo = ref<Project | null>(null)

// 현재 사용자 권한 — 단건 응답에 포함된 값(백엔드와 동일 정책: 설정=admin, 삭제=소유자)
const canManage = computed(() => repo.value?.canManage === true)
const isOwner = computed(() => repo.value?.isOwner === true)
const headerMembers = computed(() => repo.value?.members ?? [])
const memberCount = computed(() =>
  repo.value ? repo.value.members.length + repo.value.moreCount : 0,
)

// 폼 상태(초기값은 프로젝트 데이터)
const displayTitle = ref('')
const description = ref('')
const saving = ref(false)

// 프로젝트 로드 + 폼 초기화
async function loadProject() {
  try {
    repo.value = await projectStore.fetchOne(projectId.value)
  } catch {
    repo.value = null
    return
  }
  if (!repo.value) return
  // 비관리자는 설정 화면에 진입할 수 없음 — 프로젝트 상세로 되돌린다(탭도 숨겨져 있어 정상 경로로는 도달 불가)
  if (!repo.value.canManage) {
    void router.replace(`/projects/${projectId.value}`)
    return
  }
  displayTitle.value = repo.value.name
  description.value = repo.value.desc
}
watch(projectId, loadProject, { immediate: true })

// 변경 저장 (admin 전용)
async function save() {
  if (saving.value || !repo.value || !canManage.value) return
  saving.value = true
  try {
    repo.value = await projectStore.update(projectId.value, {
      name: displayTitle.value.trim(),
      description: description.value.trim(),
    })
    void dialog.alert('변경 사항을 저장했습니다.', { variant: 'success' })
  } catch {
    // 인터셉터 전역 처리
  } finally {
    saving.value = false
  }
}

// 프로젝트 삭제 (소유자 전용)
async function removeProject() {
  if (!repo.value || !isOwner.value) return
  const ok = await dialog.confirm(
    '프로젝트와 그 안의 모든 업무·활동 기록이 영구 삭제됩니다. 이 작업은 되돌릴 수 없습니다.',
    {
      title: '프로젝트를 삭제할까요?',
      variant: 'danger',
      confirmText: '삭제',
    },
  )
  if (!ok) return
  try {
    await projectStore.remove(projectId.value)
    await router.push('/projects')
  } catch {
    // 인터셉터 전역 처리
  }
}
</script>

<template>
  <AppShell>
    <div
      v-if="repo && repo.canManage"
      class="page"
    >
      <div class="crumb">
        <RouterLink
          to="/projects"
          class="lnk"
        >
          프로젝트
        </RouterLink>
        <span class="sep">/</span>
        <RouterLink
          :to="`/projects/${repo.id}`"
          class="lnk"
        >
          {{ repo.name }}
        </RouterLink>
        <span class="sep">/</span>
        <b>설정</b>
      </div>

      <ProjectHeader
        :repo="repo"
        :meta-text="`멤버 ${memberCount}명`"
        :members="headerMembers"
        :more-count="repo.moreCount"
      />
      <ProjectTabs
        :project-id="repo.id"
        active="settings"
        :task-count="repo.totalCount"
        :member-count="memberCount"
        :can-manage="repo.canManage"
      />

      <div class="settings">
        <div class="admin-note">
          <svg
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <rect
              x="3"
              y="11"
              width="18"
              height="11"
              rx="2"
            /><path d="M7 11V7a5 5 0 0 1 10 0v4" />
          </svg>
          프로젝트 설정은 <b>관리자</b>만 변경할 수 있습니다.
        </div>

        <!-- 일반 -->
        <h2 class="sec-title">
          일반
        </h2>
        <div class="card">
          <div class="fblock">
            <div class="flabel">
              표시 제목
            </div>
            <div class="fhint">
              Relay 목록과 화면에 표시되는 이름입니다. (한글 가능)
            </div>
            <input
              v-model="displayTitle"
              class="tinput"
              type="text"
              maxlength="40"
            >
          </div>

          <div class="fblock">
            <div class="flabel">
              프로젝트 설명
            </div>
            <textarea
              v-model="description"
              class="tinput tarea"
            />
          </div>

          <div class="card-foot">
            <button
              class="btn primary"
              type="button"
              :disabled="saving"
              @click="save"
            >
              {{ saving ? '저장 중…' : '변경 저장' }}
            </button>
          </div>
        </div>

        <!-- 위험 구역 -->
        <h2 class="sec-title danger">
          위험 구역
        </h2>
        <div class="danger-card">
          <div class="danger-row">
            <div class="dr-main">
              <div class="dr-title">
                프로젝트 삭제
              </div>
              <div class="dr-desc">
                프로젝트와 그 안의 모든 업무·활동 기록이 영구 삭제됩니다. 되돌릴 수 없습니다.
                <span
                  v-if="!isOwner"
                  class="owner-only"
                >소유자만 삭제할 수 있습니다.</span>
              </div>
            </div>
            <button
              class="btn-danger solid"
              type="button"
              :disabled="!isOwner"
              @click="removeProject"
            >
              프로젝트 삭제
            </button>
          </div>
        </div>
      </div>
    </div>
  </AppShell>
</template>

<style scoped>
.crumb {
  padding: 1.125rem 0 0.75rem;
}

.settings {
  max-width: 45rem;
}
.admin-note {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.781rem;
  color: var(--text-3);
  margin-bottom: 1.125rem;
}
.admin-note svg {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}
.admin-note b {
  color: var(--text-2);
  font-weight: 600;
  white-space: nowrap;
}

.sec-title {
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: -0.0125rem;
  margin: 0 0 0.75rem;
}
.sec-title.danger {
  color: var(--red);
}
.card {
  margin-bottom: 1.875rem;
}
.fblock {
  padding: 1.25rem 1.375rem;
  border-top: 1px solid var(--border);
}
.fblock:first-child {
  border-top: none;
}
.flabel {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.3125rem;
  display: flex;
  align-items: center;
  gap: 0.4375rem;
}
.fhint {
  font-size: 0.781rem;
  color: var(--text-3);
  margin-bottom: 0.6875rem;
  line-height: 1.5;
}
.fixed-pill {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--text-2);
  background: #e9ebef;
  border: 1px solid var(--border-strong);
  padding: 0.0625rem 0.4375rem;
  border-radius: 20px;
  line-height: 1.5;
  white-space: nowrap;
}

.tinput {
  width: 100%;
  height: 2.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0 0.75rem;
  font-family: inherit;
  font-size: 0.875rem;
  color: var(--text);
  background: #fff;
}
.tinput:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}
.btn-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.btn-danger:disabled:hover {
  background: var(--red);
}
.owner-only {
  color: var(--red);
  font-weight: 600;
}
textarea.tarea {
  min-height: 5.25rem;
  padding: 0.625rem 0.75rem;
  line-height: 1.6;
  resize: vertical;
  height: auto;
}

.readonly {
  display: flex;
  align-items: center;
  gap: 0.5625rem;
  height: 2.5rem;
  padding: 0 0.8125rem;
  background: #f5f6f8;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-2);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: not-allowed;
}
.readonly .slash {
  color: var(--text-3);
}
.readonly .mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text);
  font-weight: 600;
}
.readonly .lock {
  margin-left: auto;
  color: var(--text-3);
  display: grid;
  place-items: center;
}
.readonly .lock svg {
  width: 0.875rem;
  height: 0.875rem;
}

.input-ico {
  display: flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: #fff;
  padding: 0 0.75rem;
  gap: 0.5625rem;
  max-width: 18.75rem;
}
.input-ico:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}
.input-ico .ico {
  color: var(--text-3);
  display: grid;
  place-items: center;
}
.input-ico .ico svg {
  width: 1rem;
  height: 1rem;
}
.input-ico input {
  flex: 1;
  border: none;
  outline: none;
  height: 2.5rem;
  font-family: inherit;
  font-size: 0.875rem;
  background: transparent;
  color: var(--text);
}

.card-foot {
  display: flex;
  justify-content: flex-end;
  padding: 0.875rem 1.375rem;
  border-top: 1px solid var(--border);
  background: #fafbfc;
  border-radius: 0 0 0.625rem 0.625rem;
}

/* 위험 구역 */
.danger-card {
  background: #fff;
  border: 1px solid var(--red-border);
  border-radius: 0.625rem;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.danger-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-top: 1px solid #f6dde2;
}
.danger-row:first-child {
  border-top: none;
}
.dr-main {
  flex: 1;
  min-width: 0;
}
.dr-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}
.dr-desc {
  font-size: 0.781rem;
  color: var(--text-2);
  margin-top: 0.1875rem;
  line-height: 1.5;
}
.btn-danger {
  height: 2.125rem;
  padding: 0 0.875rem;
  border-radius: var(--radius);
  font-size: 0.8125rem;
  font-weight: 600;
  border: 1px solid var(--red-border);
  background: #fff;
  color: var(--red);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  font-family: inherit;
}
.btn-danger.solid {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}
.btn-danger.solid:hover {
  background: #c23a51;
}
</style>
