<script setup lang="ts">
// 회원가입 — 가입 폼 → 인증 메일 발송 안내. 인증 메일의 링크를 눌러야 가입이 완료된다.
import { computed, ref } from 'vue'
import { RouterLink, useRoute } from 'vue-router'
import RelayMark from '@/components/RelayMark.vue'
import { useAuthStore } from '@/stores/auth.store'
import { useDialog } from '@/composables/useDialog'

const authStore = useAuthStore()
const dialog = useDialog()

// 폼 상태
const name = ref('')
const email = ref('')
const password = ref('')
const passwordConfirm = ref('')
const showPassword = ref(false)
const showPasswordConfirm = ref(false)
const agreeTerms = ref(true)
const submitting = ref(false)

// 화면 단계: 'form'(가입 폼) → 'verify'(인증 메일 전송됨)
const step = ref<'form' | 'verify'>('form')
// 인증 메일이 실제 발송된 주소(폼 입력과 분리 — 재발송/표시에 사용)
const sentEmail = ref('')
const resending = ref(false)
const resendDone = ref(false)
const displayEmail = computed(() => sentEmail.value || email.value.trim() || 'name@acme.co')

// 로그인 화면에서 미인증으로 넘어온 경우(?sent=이메일) — 메일은 이미 발송됐으므로 바로 '발송 완료' 화면 표시
const route = useRoute()
const sentParam = route.query.sent
if (typeof sentParam === 'string' && sentParam.trim()) {
  sentEmail.value = sentParam.trim()
  step.value = 'verify'
}

// 가입 처리 — 검증 후 API 호출, 성공 시 인증 메일 안내 화면으로 전환
async function submit() {
  if (submitting.value) return

  // 클라이언트 1차 검증 (서버 DTO 가 최종 검증)
  if (!name.value.trim() || !email.value.trim() || !password.value) {
    void dialog.alert('이름, 이메일, 비밀번호를 모두 입력해 주세요.', { variant: 'warning' })
    return
  }
  if (password.value.length < 8) {
    void dialog.alert('비밀번호는 최소 8자 이상이어야 합니다.', { variant: 'warning' })
    return
  }
  if (password.value !== passwordConfirm.value) {
    void dialog.alert('비밀번호가 일치하지 않습니다.', { variant: 'warning' })
    return
  }
  if (!agreeTerms.value) {
    void dialog.alert('이용약관 및 개인정보 처리방침에 동의해 주세요.', { variant: 'warning' })
    return
  }

  submitting.value = true
  try {
    const result = await authStore.signup({
      name: name.value.trim(),
      email: email.value.trim(),
      password: password.value,
    })
    sentEmail.value = result.email
    resendDone.value = false
    step.value = 'verify'
  } catch {
    // 에러 메시지는 API 인터셉터에서 전역 처리됨
  } finally {
    submitting.value = false
  }
}

// 인증 메일 재발송 — 존재 여부는 서버가 노출하지 않으므로 항상 완료 안내
async function resend() {
  if (resending.value || !sentEmail.value) return
  resending.value = true
  try {
    await authStore.resendVerification(sentEmail.value)
    resendDone.value = true
  } catch {
    // 에러 메시지는 API 인터셉터에서 전역 처리됨
  } finally {
    resending.value = false
  }
}

function backToForm() {
  step.value = 'form'
}

const points = [
  '이메일로 1분이면 가입 완료',
  '이메일 인증으로 안전한 가입',
  '가입 후 바로 업무 흐름에 참여',
]
</script>

<template>
  <div class="auth">
    <!-- 브랜드 패널 -->
    <aside class="brand-panel">
      <div class="blob b1" />
      <div class="blob b2" />
      <div class="ring" />
      <div class="bp-logo">
        <span class="logo"><RelayMark white /></span> Relay
      </div>
      <div class="bp-body">
        <div class="bp-head">
          팀에 합류하고<br>업무 지시를 시작하세요
        </div>
        <div class="bp-sub">
          계정을 만들면 프로젝트에 초대되어, 받은 업무를 확인하고 직접 업무를 지시할 수 있습니다.
        </div>
        <div class="bp-points">
          <div
            v-for="point in points"
            :key="point"
            class="bp-point"
          >
            <span class="ic">
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="3"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <path d="M20 6 9 17l-5-5" />
              </svg>
            </span>
            {{ point }}
          </div>
        </div>
      </div>
      <div class="bp-foot">
        © 2026 Relay · 사내 업무 지시 플랫폼
      </div>
    </aside>

    <!-- 폼 패널 -->
    <main class="form-panel">
      <div class="auth-card">
        <div class="ac-logo">
          <span class="logo"><RelayMark white /></span> Relay
        </div>

        <!-- 상태 1: 가입 폼 -->
        <form
          v-if="step === 'form'"
          class="signup-form"
          @submit.prevent="submit"
        >
          <h1 class="ac-title">
            이메일로 회원가입
          </h1>
          <p class="ac-sub">
            구글·카카오 계정은 <RouterLink
              class="inline-link"
              to="/login"
            >
              로그인 화면
            </RouterLink>에서 바로 시작할 수 있어요.
          </p>

          <div class="field first">
            <label
              class="flabel"
              for="su-name"
            >이름</label>
            <input
              id="su-name"
              v-model="name"
              class="tinput"
              type="text"
              placeholder="홍길동"
              autocomplete="name"
            >
          </div>

          <div class="field">
            <label
              class="flabel"
              for="su-email"
            >이메일</label>
            <input
              id="su-email"
              v-model="email"
              class="tinput"
              type="email"
              placeholder="name@acme.co"
              autocomplete="email"
            >
            <div class="field-hint">
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <rect
                  x="2"
                  y="4"
                  width="20"
                  height="16"
                  rx="2"
                /><path d="m22 6-10 7L2 6" />
              </svg>
              가입 후 이 주소로 인증 메일이 발송됩니다.
            </div>
          </div>

          <div class="field">
            <label
              class="flabel"
              for="su-pw"
            >비밀번호</label>
            <div class="pw-wrap">
              <input
                id="su-pw"
                v-model="password"
                class="tinput"
                :type="showPassword ? 'text' : 'password'"
                placeholder="비밀번호 입력"
                autocomplete="new-password"
              >
              <button
                class="pw-toggle"
                type="button"
                :aria-label="showPassword ? '비밀번호 숨기기' : '비밀번호 표시'"
                @click="showPassword = !showPassword"
              >
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  stroke-linecap="round"
                  stroke-linejoin="round"
                >
                  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" /><circle
                    cx="12"
                    cy="12"
                    r="3"
                  />
                </svg>
              </button>
            </div>
            <div class="field-hint">
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <circle
                  cx="12"
                  cy="12"
                  r="10"
                /><path d="M12 16v-4M12 8h.01" />
              </svg>
              8자 이상, 영문과 숫자를 포함해주세요.
            </div>
          </div>

          <div class="field">
            <label
              class="flabel"
              for="su-pw2"
            >비밀번호 확인</label>
            <div class="pw-wrap">
              <input
                id="su-pw2"
                v-model="passwordConfirm"
                class="tinput"
                :type="showPasswordConfirm ? 'text' : 'password'"
                placeholder="비밀번호 다시 입력"
                autocomplete="new-password"
              >
              <button
                class="pw-toggle"
                type="button"
                :aria-label="showPasswordConfirm ? '비밀번호 숨기기' : '비밀번호 표시'"
                @click="showPasswordConfirm = !showPasswordConfirm"
              >
                <svg
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  stroke-width="2"
                  stroke-linecap="round"
                  stroke-linejoin="round"
                >
                  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" /><circle
                    cx="12"
                    cy="12"
                    r="3"
                  />
                </svg>
              </button>
            </div>
          </div>

          <button
            class="terms"
            type="button"
            @click="agreeTerms = !agreeTerms"
          >
            <span
              class="box"
              :class="{ on: agreeTerms }"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="3.5"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <path d="M20 6 9 17l-5-5" />
              </svg>
            </span>
            <span><a href="#">이용약관</a> 및 <a href="#">개인정보 처리방침</a>에 동의합니다. (필수)</span>
          </button>

          <button
            class="submit"
            type="submit"
            :disabled="submitting"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2.2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <rect
                x="2"
                y="4"
                width="20"
                height="16"
                rx="2"
              /><path d="m22 6-10 7L2 6" />
            </svg>
            {{ submitting ? '가입 중…' : '가입하고 시작하기' }}
          </button>

          <div class="alt">
            이미 계정이 있으신가요? <RouterLink to="/login">
              로그인
            </RouterLink>
          </div>
        </form>

        <!-- 상태 2: 인증 메일 전송됨 -->
        <div
          v-else
          class="verify"
        >
          <div class="vicon">
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="1.8"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <rect
                x="2"
                y="4"
                width="20"
                height="16"
                rx="2"
              /><path d="m22 6-10 7L2 6" />
            </svg>
          </div>
          <h1>이메일을 확인해주세요</h1>
          <div class="vtext">
            아래 주소로 인증 메일을 보냈습니다.<br>메일 속 링크를 클릭하면 가입이 완료됩니다.
          </div>
          <div class="vmail">
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <rect
                x="2"
                y="4"
                width="20"
                height="16"
                rx="2"
              /><path d="m22 6-10 7L2 6" />
            </svg>
            <span>{{ displayEmail }}</span>
          </div>
          <div class="vspam">
            메일이 보이지 않나요? 스팸함을 확인하거나 잠시 후 다시 시도해주세요.
          </div>
          <div
            v-if="resendDone"
            class="vresent"
          >
            <svg
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="3"
              stroke-linecap="round"
              stroke-linejoin="round"
            >
              <path d="M20 6 9 17l-5-5" />
            </svg>
            인증 메일을 다시 보냈습니다.
          </div>
          <div class="vactions">
            <RouterLink
              class="btn-login"
              to="/login"
            >
              인증을 완료했어요 · 로그인하러 가기
            </RouterLink>
            <button
              class="btn-ghost"
              type="button"
              :disabled="resending"
              @click="resend"
            >
              <svg
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
              >
                <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" /><path d="M21 3v5h-5" />
              </svg>
              {{ resending ? '보내는 중…' : '인증 메일 다시 보내기' }}
            </button>
            <button
              class="vchange"
              type="button"
              @click="backToForm"
            >
              다른 이메일로 가입하기
            </button>
          </div>
        </div>
      </div>
    </main>
  </div>
</template>

<style scoped>
/* 회원가입도 로그인과 동일한 auth 레이아웃(큰 모서리 반경) */
.auth {
  --radius: 8px;
  display: flex;
  min-height: 100vh;
}

/* ---- 브랜드 패널 ---- */
.brand-panel {
  flex: 0 0 46%;
  max-width: 38.75rem;
  position: relative;
  overflow: hidden;
  background: linear-gradient(155deg, #4f46e5 0%, #4338ca 52%, #2e2a8f 100%);
  color: #fff;
  padding: 2.75rem 3rem;
  display: flex;
  flex-direction: column;
}
.brand-panel .blob {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}
.brand-panel .b1 {
  width: 22.5rem;
  height: 22.5rem;
  right: -7.5rem;
  top: -5.625rem;
  background: rgba(255, 255, 255, 0.1);
}
.brand-panel .b2 {
  width: 16.25rem;
  height: 16.25rem;
  left: -5.625rem;
  bottom: -4.375rem;
  background: rgba(255, 255, 255, 0.07);
}
.brand-panel .ring {
  position: absolute;
  right: 3.75rem;
  bottom: 5rem;
  width: 11.25rem;
  height: 11.25rem;
  border: 1.5px solid rgba(255, 255, 255, 0.14);
  border-radius: 50%;
}
.brand-panel .ring::after {
  content: '';
  position: absolute;
  inset: 2.125rem;
  border: 1.5px solid rgba(255, 255, 255, 0.1);
  border-radius: 50%;
}
.bp-logo {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-weight: 700;
  font-size: 1.125rem;
  letter-spacing: -0.0125rem;
  position: relative;
  z-index: 1;
}
.bp-logo .logo {
  width: 2rem;
  height: 2rem;
  border-radius: 0.5625rem;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.22);
  display: grid;
  place-items: center;
  font-size: 1.0625rem;
  font-weight: 800;
}
.bp-body {
  margin-top: auto;
  position: relative;
  z-index: 1;
}
.bp-head {
  font-size: 2.125rem;
  font-weight: 700;
  line-height: 1.32;
  letter-spacing: -0.05rem;
  text-wrap: balance;
}
.bp-sub {
  margin-top: 1.125rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.82);
  max-width: 25rem;
}
.bp-points {
  margin-top: 1.875rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.bp-point {
  display: flex;
  align-items: center;
  gap: 0.6875rem;
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.92);
}
.bp-point .ic {
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.bp-point .ic svg {
  width: 0.8125rem;
  height: 0.8125rem;
}
.bp-foot {
  margin-top: 2.5rem;
  font-size: 0.781rem;
  color: rgba(255, 255, 255, 0.6);
  position: relative;
  z-index: 1;
}

/* ---- 폼 패널 ---- */
.form-panel {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 1.5rem;
}
.auth-card {
  width: 100%;
  max-width: 24rem;
}
.ac-logo {
  display: none;
}
.ac-title {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.03125rem;
}
.ac-sub {
  color: var(--text-2);
  font-size: 0.875rem;
  margin-top: 0.4375rem;
}
.inline-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.field {
  margin-bottom: 0.8125rem;
}
.field.first {
  margin-top: 1.625rem;
}
.flabel {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 0.4375rem;
  display: block;
}
.tinput {
  width: 100%;
  height: 2.75rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0 0.8125rem;
  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);
}
.tinput::placeholder {
  color: var(--text-3);
}
.pw-wrap {
  position: relative;
}
.pw-wrap .tinput {
  padding-right: 2.75rem;
}
.pw-toggle {
  position: absolute;
  right: 0.375rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.125rem;
  height: 2.125rem;
  border: none;
  background: transparent;
  color: var(--text-3);
  display: grid;
  place-items: center;
  cursor: pointer;
  border-radius: 0.375rem;
}
.pw-toggle:hover {
  background: #f1f2f4;
  color: var(--text-2);
}
.pw-toggle svg {
  width: 1.125rem;
  height: 1.125rem;
}
.field-hint {
  font-size: 0.75rem;
  color: var(--text-3);
  margin-top: 0.4375rem;
  display: flex;
  align-items: center;
  gap: 0.3125rem;
}
.field-hint svg {
  width: 0.8125rem;
  height: 0.8125rem;
  flex-shrink: 0;
}

.terms {
  display: flex;
  align-items: flex-start;
  gap: 0.5625rem;
  margin: 0.375rem 0 1.125rem;
  font-size: 0.8125rem;
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
  line-height: 1.5;
  background: none;
  border: none;
  font-family: inherit;
  text-align: left;
  padding: 0;
}
.terms .box {
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 0.3125rem;
  border: 1.5px solid var(--border-strong);
  display: grid;
  place-items: center;
  background: #fff;
  flex-shrink: 0;
  margin-top: 1px;
}
.terms .box.on {
  background: var(--accent);
  border-color: var(--accent);
}
.terms .box svg {
  width: 0.75rem;
  height: 0.75rem;
  color: #fff;
  opacity: 0;
}
.terms .box.on svg {
  opacity: 1;
}
.terms a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.terms a:hover {
  text-decoration: underline;
}

.submit {
  width: 100%;
  height: 2.875rem;
  border-radius: var(--radius);
  border: none;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(79, 70, 229, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4375rem;
}
.submit:hover {
  background: var(--accent-hover);
}
.submit svg {
  width: 1.0625rem;
  height: 1.0625rem;
}

.alt {
  margin-top: 1.375rem;
  text-align: center;
  font-size: 0.844rem;
  color: var(--text-2);
}
.alt a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.alt a:hover {
  text-decoration: underline;
}

/* 인증 메일 전송 상태 */
.verify {
  text-align: center;
}
.verify .vicon {
  width: 4.125rem;
  height: 4.125rem;
  border-radius: 50%;
  background: var(--accent-weak);
  color: var(--accent);
  display: grid;
  place-items: center;
  margin: 0 auto 1.375rem;
}
.verify .vicon svg {
  width: 1.875rem;
  height: 1.875rem;
}
.verify h1 {
  font-size: 1.4375rem;
  font-weight: 700;
  letter-spacing: -0.025rem;
}
.verify .vtext {
  color: var(--text-2);
  font-size: 0.875rem;
  line-height: 1.7;
  margin-top: 0.75rem;
}
.verify .vmail {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 1rem;
  padding: 0.5625rem 0.875rem;
  background: #f7f8fa;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text);
}
.verify .vmail svg {
  width: 0.9375rem;
  height: 0.9375rem;
  color: var(--text-3);
}
.verify .vspam {
  font-size: 0.781rem;
  color: var(--text-3);
  margin-top: 1.125rem;
  line-height: 1.6;
}
.verify .vresent {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 1rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--green);
}
.verify .vresent svg {
  width: 0.875rem;
  height: 0.875rem;
}
.verify .vactions {
  margin-top: 1.625rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.btn-login {
  height: 2.75rem;
  border-radius: var(--radius);
  border: none;
  background: var(--accent);
  color: #fff;
  font-family: inherit;
  font-size: 0.9375rem;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(79, 70, 229, 0.4);
}
.btn-login:hover {
  background: var(--accent-hover);
}
.btn-ghost {
  height: 2.75rem;
  border-radius: var(--radius);
  border: 1px solid var(--border-strong);
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4375rem;
}
.btn-ghost:hover {
  background: #f7f8fa;
}
.btn-ghost svg {
  width: 1rem;
  height: 1rem;
}
.vchange {
  background: none;
  border: none;
  font-family: inherit;
  font-size: 0.8125rem;
  color: var(--text-2);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.vchange:hover {
  color: var(--text);
}

/* 좁은 화면 — 브랜드 패널 숨기고 카드 로고 노출 */
@media (max-width: 55rem) {
  .brand-panel {
    display: none;
  }
  .ac-logo {
    display: flex;
    align-items: center;
    gap: 0.5625rem;
    font-weight: 700;
    font-size: 1.0625rem;
    margin-bottom: 1.5rem;
  }
  .ac-logo .logo {
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 0.5rem;
    background: linear-gradient(135deg, #5b54f0, #4338ca);
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 0.9375rem;
    font-weight: 800;
  }
}
</style>
