// backend/src/routes/auth.js
import { Router } from "express";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import { config } from "../config.js";
import { User } from "../db/sequelize.js";

import {
  signAccessToken,
  signRefreshToken,
  requireAuth,
} from "../middleware/auth.js";

const r = Router();

// cookie options — ทำในไฟล์นี้เลย (ไม่เพิ่ม utils ใหม่)
function cookieOpts(maxAgeMs) {
  const isProd = process.env.NODE_ENV === "production";
  const opts = {
    httpOnly: true,
    secure: true, // หลัง Nginx/HTTPS
    sameSite: "none", // ส่งข้าม subdomain ได้
    path: "/",
    maxAge: maxAgeMs,
  };
  if (config.COOKIE_DOMAIN) opts.domain = config.COOKIE_DOMAIN; // เช่น .np-dms.work
  if (!isProd && process.env.ALLOW_INSECURE_COOKIE === "1") {
    opts.secure = false;
    opts.sameSite = "lax";
  }
  return opts;
}

// helper TTL จาก config เดิม
const ACCESS_TTL_MS = (() => {
  // รับทั้งรูปแบบ "15m" (เช่น EXPIRES_IN) หรือ milliseconds
  // ถ้าเป็นเลขอยู่แล้ว (ms) ก็ใช้เลย
  if (/^\d+$/.test(String(config.JWT.EXPIRES_IN)))
    return Number(config.JWT.EXPIRES_IN);
  // แปลงรูปแบบเช่น "15m" เป็น ms แบบง่าย ๆ
  const s = String(config.JWT.EXPIRES_IN || "15m");
  const n = parseInt(s, 10);
  if (s.endsWith("h")) return n * 60 * 60 * 1000;
  if (s.endsWith("m")) return n * 60 * 1000;
  if (s.endsWith("s")) return n * 1000;
  return 15 * 60 * 1000;
})();
const REFRESH_TTL_MS = (() => {
  if (/^\d+$/.test(String(config.JWT.REFRESH_EXPIRES_IN)))
    return Number(config.JWT.REFRESH_EXPIRES_IN);
  const s = String(config.JWT.REFRESH_EXPIRES_IN || "7d");
  const n = parseInt(s, 10);
  if (s.endsWith("d")) return n * 24 * 60 * 60 * 1000;
  if (s.endsWith("h")) return n * 60 * 60 * 1000;
  if (s.endsWith("m")) return n * 60 * 1000;
  if (s.endsWith("s")) return n * 1000;
  return 7 * 24 * 60 * 60 * 1000;
})();

// == POST /api/auth/login ==
r.post("/login", async (req, res) => {
  const { username, password } = req.body || {};
  if (!username || !password)
    return res.status(400).json({ error: "USERNAME_PASSWORD_REQUIRED" });

  const user = await User.findOne({ where: { username }, raw: true });
  if (!user) return res.status(401).json({ error: "INVALID_CREDENTIALS" });

  const ok = await bcrypt.compare(password, user.password_hash || "");
  if (!ok) return res.status(401).json({ error: "INVALID_CREDENTIALS" });

  // NOTE: สิทธิ์จริง ๆ ให้ดึงจากตาราง role/permission ของคุณ
  const permissions = []; // ใส่เปล่าไว้ก่อน (คุณมี enrichRoles ที่อื่นอยู่แล้ว)
  const payload = {
    user_id: user.user_id,
    username: user.username,
    permissions,
  };

  const access = signAccessToken(payload);
  const refresh = signRefreshToken({ user_id: user.user_id });

  // ตั้งคุกกี้ (และยังส่ง token ใน body ได้ถ้าคุณใช้อยู่)
  res.cookie("access_token", access, cookieOpts(ACCESS_TTL_MS));
  res.cookie("refresh_token", refresh, cookieOpts(REFRESH_TTL_MS));

  return res.json({
    ok: true,
    token: access,
    refresh_token: refresh,
    user: { user_id: user.user_id, username: user.username, email: user.email },
  });
});

// == GET /api/auth/me ==
r.get("/me", requireAuth, async (req, res) => {
  // enrich เพิ่มจากฐานได้ตามต้องการ; ตอนนี้เอาเบื้องต้นจาก token
  return res.json({
    ok: true,
    user: {
      user_id: req.user.user_id,
      username: req.user.username,
      permissions: req.user.permissions || [],
    },
  });
});

// == POST /api/auth/refresh ==
r.post("/refresh", async (req, res) => {
  // รับจากคุกกี้ก่อน แล้วค่อย Authorization
  const bearer = req.headers.authorization?.startsWith("Bearer ")
    ? req.headers.authorization.slice(7)
    : null;
  const rt = req.cookies?.refresh_token || bearer;
  if (!rt) return res.status(401).json({ error: "Unauthenticated" });

  try {
    // verify refresh โดยตรงด้วย config.JWT.REFRESH_SECRET (คงสไตล์เดิม)
    const p = jwt.verify(rt, config.JWT.REFRESH_SECRET, { clockTolerance: 10 });
    // โหลดสิทธิ์ล่าสุดจากฐานได้ ถ้าต้องการ; ตอนนี้ใส่ [] ไว้ก่อน
    const permissions = [];
    const access = signAccessToken({ user_id: p.user_id, permissions });
    res.cookie("access_token", access, cookieOpts(ACCESS_TTL_MS));
    return res.json({ ok: true, token: access });
  } catch {
    return res.status(401).json({ error: "Unauthenticated" });
  }
});

// == POST /api/auth/logout ==
r.post("/logout", (_req, res) => {
  res.clearCookie("access_token", { path: "/" });
  res.clearCookie("refresh_token", { path: "/" });
  return res.json({ ok: true });
});

export default r;
