/**
 * 카테고리 트리 컨트롤러 (테스트용)
 */

import { Router, Request, Response } from "express";
import { categoryTreeService, CreateCategoryValueInput, UpdateCategoryValueInput } from "../services/categoryTreeService";
import { logger } from "../utils/logger";
import { authenticateToken } from "../middleware/authMiddleware";
import { auditLogService, getClientIp } from "../services/auditLogService";

const router = Router();

// 모든 라우트에 인증 미들웨어 적용
router.use(authenticateToken);

// 인증된 사용자 타입
interface AuthenticatedRequest extends Request {
  user?: {
    userId: string;
    userName: string;
    companyCode: string;
  };
}

/**
 * 전체 카테고리 키 목록 조회 (모든 테이블.컬럼 조합)
 * GET /api/category-tree/test/all-category-keys
 * 주의: 이 라우트는 /test/:tableName/:columnName 보다 먼저 정의되어야 함
 */
router.get("/test/all-category-keys", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const companyCode = req.user?.companyCode || "*";

    const keys = await categoryTreeService.getAllCategoryKeys(companyCode);

    res.json({
      success: true,
      data: keys,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("전체 카테고리 키 목록 조회 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 트리 조회
 * GET /api/category-tree/test/:tableName/:columnName
 */
router.get("/test/:tableName/:columnName", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { tableName, columnName } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const tree = await categoryTreeService.getCategoryTree(companyCode, tableName, columnName);

    res.json({
      success: true,
      data: tree,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 트리 조회 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 목록 조회 (플랫 리스트)
 * GET /api/category-tree/test/:tableName/:columnName/flat
 */
router.get("/test/:tableName/:columnName/flat", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { tableName, columnName } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const list = await categoryTreeService.getCategoryList(companyCode, tableName, columnName);

    res.json({
      success: true,
      data: list,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 목록 조회 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 값 단일 조회
 * GET /api/category-tree/test/value/:valueId
 */
router.get("/test/value/:valueId", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { valueId } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const value = await categoryTreeService.getCategoryValue(companyCode, Number(valueId));

    if (!value) {
      return res.status(404).json({
        success: false,
        error: "카테고리 값을 찾을 수 없습니다",
      });
    }

    res.json({
      success: true,
      data: value,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 값 조회 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 값 생성
 * POST /api/category-tree/test/value
 */
router.post("/test/value", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const input: CreateCategoryValueInput = req.body;
    const userCompanyCode = req.user?.companyCode || "*";
    const createdBy = req.user?.userId;

    // 🔧 최고 관리자가 특정 회사를 선택한 경우, targetCompanyCode 우선 사용
    // 단, 최고 관리자(companyCode = '*')만 다른 회사 코드 사용 가능
    let companyCode = userCompanyCode;
    if (input.targetCompanyCode && userCompanyCode === "*") {
      companyCode = input.targetCompanyCode;
      logger.info("🔓 최고 관리자 회사 코드 오버라이드 (카테고리 값 생성)", {
        originalCompanyCode: userCompanyCode,
        targetCompanyCode: input.targetCompanyCode,
      });
    }

    if (!input.tableName || !input.columnName || !input.valueCode || !input.valueLabel) {
      return res.status(400).json({
        success: false,
        error: "tableName, columnName, valueCode, valueLabel은 필수입니다",
      });
    }

    const value = await categoryTreeService.createCategoryValue(companyCode, input, createdBy);

    auditLogService.log({
      companyCode,
      userId: req.user?.userId || "",
      userName: req.user?.userName,
      action: "CREATE",
      resourceType: "CODE_CATEGORY",
      resourceId: String(value.valueId),
      resourceName: input.valueLabel,
      tableName: "category_values",
      summary: `카테고리 값 "${input.valueLabel}" 생성 (${input.tableName}.${input.columnName})`,
      changes: { after: { tableName: input.tableName, columnName: input.columnName, valueCode: input.valueCode, valueLabel: input.valueLabel } },
      ipAddress: getClientIp(req),
      requestPath: req.originalUrl,
    });

    res.json({
      success: true,
      data: value,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 값 생성 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 값 수정
 * PUT /api/category-tree/test/value/:valueId
 */
router.put("/test/value/:valueId", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { valueId } = req.params;
    const input: UpdateCategoryValueInput = req.body;
    const companyCode = req.user?.companyCode || "*";
    const updatedBy = req.user?.userId;

    const beforeValue = await categoryTreeService.getCategoryValue(companyCode, Number(valueId));
    const value = await categoryTreeService.updateCategoryValue(companyCode, Number(valueId), input, updatedBy);

    if (!value) {
      return res.status(404).json({
        success: false,
        error: "카테고리 값을 찾을 수 없습니다",
      });
    }

    auditLogService.log({
      companyCode,
      userId: req.user?.userId || "",
      userName: req.user?.userName,
      action: "UPDATE",
      resourceType: "CODE_CATEGORY",
      resourceId: valueId,
      resourceName: value.valueLabel,
      tableName: "category_values",
      summary: `카테고리 값 "${value.valueLabel}" 수정 (${value.tableName}.${value.columnName})`,
      changes: {
        before: beforeValue ? { valueLabel: beforeValue.valueLabel, valueCode: beforeValue.valueCode } : undefined,
        after: input,
      },
      ipAddress: getClientIp(req),
      requestPath: req.originalUrl,
    });

    res.json({
      success: true,
      data: value,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 값 수정 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 값 삭제 가능 여부 사전 확인
 * GET /api/category-tree/test/value/:valueId/can-delete
 */
router.get("/test/value/:valueId/can-delete", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { valueId } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const result = await categoryTreeService.checkCanDelete(companyCode, Number(valueId));

    res.json({
      success: true,
      data: result,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 삭제 가능 여부 확인 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 카테고리 값 삭제
 * DELETE /api/category-tree/test/value/:valueId
 */
router.delete("/test/value/:valueId", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { valueId } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const beforeValue = await categoryTreeService.getCategoryValue(companyCode, Number(valueId));
    const success = await categoryTreeService.deleteCategoryValue(companyCode, Number(valueId));

    if (!success) {
      return res.status(404).json({
        success: false,
        error: "카테고리 값을 찾을 수 없습니다",
      });
    }

    auditLogService.log({
      companyCode,
      userId: req.user?.userId || "",
      userName: req.user?.userName,
      action: "DELETE",
      resourceType: "CODE_CATEGORY",
      resourceId: valueId,
      resourceName: beforeValue?.valueLabel || valueId,
      tableName: "category_values",
      summary: `카테고리 값 "${beforeValue?.valueLabel || valueId}" 삭제 (${beforeValue?.tableName || ""}.${beforeValue?.columnName || ""})`,
      changes: beforeValue ? { before: { valueLabel: beforeValue.valueLabel, valueCode: beforeValue.valueCode, tableName: beforeValue.tableName, columnName: beforeValue.columnName } } : undefined,
      ipAddress: getClientIp(req),
      requestPath: req.originalUrl,
    });

    res.json({
      success: true,
      message: "삭제되었습니다",
    });
  } catch (error: unknown) {
    const err = error as Error;

    if (err.message.startsWith("VALIDATION:")) {
      const validationMessage = err.message.replace("VALIDATION:", "");
      logger.warn("카테고리 값 삭제 검증 실패", { valueId: req.params.valueId, reason: validationMessage });
      return res.status(400).json({
        success: false,
        error: validationMessage,
      });
    }

    logger.error("카테고리 값 삭제 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

/**
 * 테이블의 카테고리 컬럼 목록 조회
 * GET /api/category-tree/test/columns/:tableName
 */
router.get("/test/columns/:tableName", async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { tableName } = req.params;
    const companyCode = req.user?.companyCode || "*";

    const columns = await categoryTreeService.getCategoryColumns(companyCode, tableName);

    res.json({
      success: true,
      data: columns,
    });
  } catch (error: unknown) {
    const err = error as Error;
    logger.error("카테고리 컬럼 목록 조회 API 오류", { error: err.message });
    res.status(500).json({
      success: false,
      error: err.message,
    });
  }
});

export default router;

