// routes/auth.js
const express = require("express")
const router = express.Router()

const requireAuth = require("../middleware/requireAuth.js")
const { validate } = require("../middleware/validate.middleware")
const authService = require("../services/auth.service")
const { endpoints } = require("@shared/contracts")

const { mapLoginRequestToLoginInput, mapLoginResultToResponse } = require("../adapters/responses/login.adapter")
const { mapRegisterRequestToRegisterInput, mapRegisterResultToResponse } = require("../adapters/responses/register.adapter")
const { mapMeRequestToUserId, mapMeResultToResponse } = require("../adapters/responses/me.adapter")

const { auth } = endpoints

// NOT: app.js’de cookie-parser olmalı:
// const cookieParser = require("cookie-parser")
// app.use(cookieParser())

function getCookieOptions() {
  const isProd = process.env.NODE_ENV === "production"

  // DEV: http localhost -> secure false, sameSite lax
  if (!isProd) {
    return {
      httpOnly: true,
      secure: false,
      sameSite: "lax",
      path: "/",
    }
  }

  // PROD: cross-site kullanacaksan (frontend ayrı domain)
  return {
    httpOnly: true,
    secure: true,
    sameSite: "none",
    path: "/",
  }
}


function setRefreshCookie(res, refreshToken) {
  const opts = getCookieOptions()
  const maxAgeMs = Number(process.env.REFRESH_COOKIE_MAX_AGE_MS || 1000 * 60 * 60 * 24 * 30)
  res.cookie("rt", refreshToken, { ...opts, maxAge: maxAgeMs })
}

function clearRefreshCookie(res) {
  const opts = getCookieOptions()
  res.clearCookie("rt", { ...opts })
}

router.post(
  "/register",
  validate(auth.registerRequestSchema, "body", "validatedRegisterInput"),
  async (req, res) => {
    try {
      const input = mapRegisterRequestToRegisterInput(req.validatedRegisterInput)

      const result = await authService.register({
        ...input,
        meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
      })

      // refresh cookie set
      if (result.refreshToken) setRefreshCookie(res, result.refreshToken)

      // response body: access + user (adapter refresh'i koymamalı)
      const response = auth.authResponseSchema.parse(mapRegisterResultToResponse(result))
      res.json(response)
    } catch (err) {
      const status = err.statusCode || 500
      res.status(status).json({ message: err.message || "Kayit islemi basarisiz." })
    }
  }
)

router.post(
  "/login",
  validate(auth.loginRequestSchema, "body", "validatedLoginInput"),
  async (req, res) => {
    try {
      const input = mapLoginRequestToLoginInput(req.validatedLoginInput)

      const result = await authService.login({
        ...input,
        meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
      })

      // refresh cookie set
      setRefreshCookie(res, result.refreshToken)

      const response = auth.authResponseSchema.parse(mapLoginResultToResponse(result))
      res.json(response)
    } catch (err) {
  console.error("LOGIN ERROR:", err)           // <-- ekle
  console.error("LOGIN ERROR MSG:", err?.message)
  console.error("LOGIN ERROR STACK:", err?.stack)

  const status = err.statusCode || 500
  res.status(status).json({
    message: err.statusCode ? err.message : "Giris islemi basarisiz.",
  })
}
  }
)

router.post("/refresh", async (req, res) => {
  try {
    const refreshToken = req.cookies?.rt
    if (!refreshToken) return res.status(401).json({ message: "Refresh token yok" })

    const result = await authService.refresh({
      refreshToken,
      meta: { ip: req.ip, userAgent: req.headers["user-agent"] || null },
    })

    // rotate -> yeni refresh cookie
    setRefreshCookie(res, result.refreshToken)

    // body: access + user (adapter refresh'i koymamalı)
    const response = auth.authResponseSchema.parse(mapLoginResultToResponse(result))
    res.json(response)
  } catch (err) {
    clearRefreshCookie(res)
    const status = err.statusCode || 401
    res.status(status).json({ message: err.message || "Refresh basarisiz" })
  }
})

router.post("/logout", async (req, res) => {
  try {
    const refreshToken = req.cookies?.rt

    // logout idempotent olsun
    if (refreshToken) {
      await authService.logout({ refreshToken })
    }

    clearRefreshCookie(res)
    res.status(204).send()
  } catch (err) {
    clearRefreshCookie(res)
    const status = err.statusCode || 500
    res.status(status).json({ message: err.message || "Cikis basarisiz" })
  }
})

router.get("/me", requireAuth, async (req, res) => {
  try {
    const userId = mapMeRequestToUserId(req) // req.auth.userId okumalı
    const user = await authService.getMe(userId)
    const response = auth.meResponseSchema.parse(mapMeResultToResponse(user))
    res.json(response)
  } catch (err) {
    const status = err.statusCode || 500
    res.status(status).json({ message: err.message || "Sunucu hatasi" })
  }
})

module.exports = router
