const express = require('express');
const router = express.Router();
const { query } = require('../mods/dbconnection');
const config = require("../conf/config.json");
const passport = require('passport');
const { createAuthToken, createRefreshToken } = require('../mods/passport');
const { secret: tokenSecret } = require('../conf/config.json').secure.jwt;
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const moment = require('moment');
const { email, clientURL } = require('../conf/config.json');
const cookie = require('cookie');

router.get(
  '/',
  passport.authenticate('jwt', { session: false }),
  async (req, res) => {
    res.status(200).json({
      user: {
        userId: req.user.user_id,
        userName: req.user.user_name,
        accountId: req.user.account_id,
        deptId: req.user.dept_id,
        deptName: req.user.dept_name,
        isAdmin: req.user.is_admin,
        isActive: req.user.is_active,
        isWorker: req.user.is_worker
      },
    });
  }
);

router.post('/login', async (req, res) => {
  var userId = req.body.userId;
  var userPw = req.body.userPw;

  if (!userId) return res.status(412).json({ msg: '아이디를 입력해주세요.' });

  try {
    // 계정 상태 확인
    const active = await query(
      `SELECT is_active FROM \`${config.dbName.boas_se}\`.tb_user WHERE user_id = ?`,
      [userId]
    );

    if (active.length !== 1) {
      return res.status(401).json({
          msg: '아이디/비밀번호를 확인해주세요.',
      });
    }

    if (active[0].is_active === 'N') {
      return res.status(401).json({
          msg: '해당 계정은 비활성 상태입니다.',
      });
    }

    // 로그인 시도
    const user = await query(
      `SELECT u.user_id, u.user_name, u.user_pw, u.account_id, u.dept_id, d.dept_name, u.is_admin, u.is_active , u.is_worker
      FROM \`${config.dbName.boas_se}\`.tb_user u
      LEFT JOIN \`${config.dbName.boas_se}\`.tb_dept d on d.dept_id = u.dept_id
      WHERE u.user_id = ? AND u.user_pw = ?;`,
      [userId, userPw]
    );

    if (user.length !== 1) {
      return res.status(401).json({
        msg: `아이디/비밀번호를 확인해주세요.`,
      });
    }

    // 로그인 성공 시

    const tokenPayload = {
      user_id: user[0].user_id,
      account_id : user[0].account_id,
      is_admin: user[0].is_admin
    };
    
    const accessToken = createAuthToken(tokenPayload);
    const refreshToken = createRefreshToken(tokenPayload);

    // 쿠키 설정
    res.setHeader('Set-Cookie', [
      cookie.serialize('auth_token', accessToken, {
        httpOnly: true,
        secure: false,
        sameSite: 'lax',
        maxAge: 24 * 60 * 60, // 24시간
        path: '/',
      }),
      cookie.serialize('refresh_token', refreshToken, {
        httpOnly: false,
        secure: false,
        sameSite: 'lax',
        maxAge: 7 * 24 * 60 * 60, // 7일
        path: '/',
      }),
    ]);

    // 사용자 정보만 반환 (토큰은 쿠키로 전송됨)
    res.status(200).json({
      user: {
        userId: user[0].user_id,
        userName: user[0].user_name,
        accountId: user[0].account_id,
        deptId: user[0].dept_id,
        deptName : user[0].dept_name,
        isAdmin: user[0].is_admin,
        isActive: user[0].is_active,
        isWorker: user[0].is_worker
      },
    });
  } catch (error) {
    console.error('Login error:', error);
    res.status(500).json({ msg: '서버 오류가 발생했습니다.' });
  }
});

router.post('/logout', (req, res) => {
  try {
    const cookieOptions = {
      httpOnly: false,
      secure: false,
      sameSite: 'lax',
      path: '/',
    };

    res.clearCookie('auth_token', cookieOptions);
    res.clearCookie('refresh_token', cookieOptions);

    return res.status(200).json({
      msg: '로그아웃 완료',
    });
  } catch (error) {
    console.error(error);

    return res.status(500).json({
      msg: '로그아웃 처리 중 오류가 발생했습니다.',
    });
  }
});

router.post('/workerLogin', async (req, res) => {
  var userId = req.body.userId;
  var eqptId = req.body.eqptId;

  if (!userId) return res.status(412).json({ msg: '작업자를 선택해주세요.' });
  if (!eqptId) return res.status(412).json({ msg: '장비를 선택해주세요.' });

  try{
    const user = await query(
      `SELECT user_id, is_active
        FROM \`${config.dbName.boas_se}\`.tb_user
        WHERE user_id = ?`,
      [userId]
    );

    if (user.length !== 1) {
      return res.status(401).json({ msg: '존재하지 않는 작업자입니다.' });
    }

    if (user[0].is_active === 'N') {
      return res.status(401).json({ msg: '해당 계정은 비활성 상태입니다.' });
    }

    const eqpt = await query(
      `SELECT eqpt_id
        FROM \`${config.dbName.boas_se}\`.tb_eqpt
        WHERE eqpt_id = ?`,
      [eqptId]
    );

    if (eqpt.length !== 1) {
      return res.status(401).json({ msg: '존재하지 않는 장비입니다.' });
    }

    const sessionId = crypto.randomUUID();

    const lastUserLog = await query(
        `SELECT user_id, eqpt_id, session_id, op_type
        FROM \`${config.dbName.boas_se}\`.tb_user_eqpt
        WHERE user_id = ?
        ORDER BY reg_dt DESC
        LIMIT 1`,
        [userId]
    );

    const lastEqptLog = await query(
        `SELECT user_id, eqpt_id, session_id, op_type
        FROM \`${config.dbName.boas_se}\`.tb_user_eqpt
        WHERE eqpt_id = ?
        ORDER BY reg_dt DESC
        LIMIT 1`,
        [eqptId]
    );

    const logoutTargets = [];

    if (lastUserLog.length > 0 && lastUserLog[0].op_type === 'LOGIN') {
        logoutTargets.push(lastUserLog[0]);
    }

    if (lastEqptLog.length > 0 && lastEqptLog[0].op_type === 'LOGIN') {
        const exists = logoutTargets.some(
            (log) => log.session_id === lastEqptLog[0].session_id
        );

        if (!exists) {
            logoutTargets.push(lastEqptLog[0]);
        }
    }

    for (const target of logoutTargets) {
        await query(
            `INSERT INTO \`${config.dbName.boas_se}\`.tb_user_eqpt
            (user_id, eqpt_id, session_id, reg_dt, op_type)
            VALUES (?, ?, ?, NOW(3), 'LOGOUT')`,
            [
                target.user_id,
                target.eqpt_id,
                target.session_id,
            ]
        );
    }

    await query(
        `INSERT INTO \`${config.dbName.boas_se}\`.tb_user_eqpt
        (user_id, eqpt_id, session_id, reg_dt, op_type)
        VALUES (?, ?, ?, NOW(3), 'LOGIN')`,
        [userId, eqptId, sessionId]
    );

    return res.json({
        ok: true,
        msg: '작업자 로그인이 완료되었습니다.',
        sessionId,
    });


  } catch (error) {
    console.error(error);

    return res.status(500).json({
      msg: '작업자 로그인 처리 중 오류가 발생했습니다.',
    });
  }
})

router.post('/workerLogout', async (req, res) => {
  const { userId, eqptId, sessionId } = req.body;

  if (!userId) {
      return res.status(412).json({
          msg: '작업자를 선택해주세요.',
      });
  }

  if (!eqptId) {
      return res.status(412).json({
          msg: '장비를 선택해주세요.',
      });
  }

  if (!sessionId) {
      return res.status(412).json({
          msg: '작업자 로그인 세션 정보가 없습니다.',
      });
  }

  try {
    const lastSessionLog = await query(
      `SELECT user_id, eqpt_id, session_id, op_type, reg_dt
        FROM \`${config.dbName.boas_se}\`.tb_user_eqpt
        WHERE session_id = ?
        ORDER BY reg_dt DESC
        LIMIT 1`,
      [sessionId]
    );

    if (lastSessionLog.length === 0) {
      return res.status(400).json({
        msg: '로그인 세션 이력이 존재하지 않습니다.',
      });
    }

    const log = lastSessionLog[0];

    if (log.op_type === 'LOGOUT') {
      return res.status(400).json({
        msg: '이미 로그아웃 상태입니다.',
      });
    }

    if (log.user_id !== userId) {
      return res.status(400).json({
        msg: '작업자 로그인 세션 정보가 일치하지 않습니다.',
      });
    }

    if (log.eqpt_id !== eqptId) {
      return res.status(400).json({
        msg: '장비 로그인 세션 정보가 일치하지 않습니다.',
      });
    }

    await query(
      `INSERT INTO \`${config.dbName.boas_se}\`.tb_user_eqpt
        (user_id, eqpt_id, session_id, reg_dt, op_type)
        VALUES (?, ?, ?, NOW(3), 'LOGOUT')`,
      [userId, eqptId, sessionId]
    );

    return res.json({
      ok: true,
      msg: '작업자 로그아웃이 완료되었습니다.',
    });

  } catch (error) {
    console.error(error);

    return res.status(500).json({
      msg: '작업자 로그아웃 처리 중 오류가 발생했습니다.',
    });
  }
});

router.get('/workerLoginCheck', async (req, res) => {
  const { userId, eqptId, sessionId } = req.query;

  if (!userId || !eqptId || !sessionId) {
    return res.status(400).json({
      ok: false,
      isLogin: false,
      msg: '작업자, 장비 또는 세션 정보가 없습니다.',
    });
  }

  try {
    const lastSessionLog = await query(
      `SELECT user_id, eqpt_id, session_id, op_type, reg_dt
        FROM \`${config.dbName.boas_se}\`.tb_user_eqpt
        WHERE session_id = ?
        ORDER BY reg_dt DESC
        LIMIT 1`,
      [sessionId]
    );

    if (lastSessionLog.length === 0) {
      return res.json({
        ok: true,
        isLogin: false,
        reason: 'NO_SESSION_LOG',
      });
    }

    const log = lastSessionLog[0];

    if (log.op_type !== 'LOGIN') {
      return res.json({
        ok: true,
        isLogin: false,
        reason: 'SESSION_LOGGED_OUT',
      });
    }

    if (log.user_id !== userId) {
      return res.json({
        ok: true,
        isLogin: false,
        reason: 'USER_MISMATCH',
      });
    }

    if (log.eqpt_id !== eqptId) {
      return res.json({
        ok: true,
        isLogin: false,
        reason: 'EQPT_MISMATCH',
        currentEqptId: log.eqpt_id,
      });
    }

    return res.json({
        ok: true,
        isLogin: true,
    });
  } catch (error) {
    console.error(error);

    return res.status(500).json({
      ok: false,
      isLogin: false,
      msg: '작업자 로그인 상태 확인 중 오류가 발생했습니다.',
    });
  }
});

module.exports = router;