import { Response } from "express";
import { AuthenticatedRequest } from "../types/auth";
import { getPool } from "../database/db";
import { logger } from "../utils/logger";

const pool = getPool();

/**
 * 연쇄 관계 목록 조회
 */
export const getCascadingRelations = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const companyCode = req.user?.companyCode || "*";
    const { isActive } = req.query;

    let query = `
      SELECT 
        relation_id,
        relation_code,
        relation_name,
        description,
        parent_table,
        parent_value_column,
        parent_label_column,
        child_table,
        child_filter_column,
        child_value_column,
        child_label_column,
        child_order_column,
        child_order_direction,
        empty_parent_message,
        no_options_message,
        loading_message,
        clear_on_parent_change,
        company_code,
        is_active,
        created_by,
        created_date,
        updated_by,
        updated_date
      FROM cascading_relation
      WHERE 1=1
    `;

    const params: any[] = [];
    let paramIndex = 1;

    // 멀티테넌시 필터링
    // - 최고 관리자(company_code = "*"): 모든 데이터 조회 가능
    // - 일반 회사: 자기 회사 데이터만 조회 (공통 데이터는 조회 불가)
    if (companyCode !== "*") {
      query += ` AND company_code = $${paramIndex}`;
      params.push(companyCode);
      paramIndex++;
    }

    // 활성 상태 필터링
    if (isActive !== undefined) {
      query += ` AND is_active = $${paramIndex}`;
      params.push(isActive);
      paramIndex++;
    }

    query += ` ORDER BY relation_name ASC`;

    const result = await pool.query(query, params);

    logger.info("연쇄 관계 목록 조회", {
      companyCode,
      count: result.rowCount,
    });

    return res.json({
      success: true,
      data: result.rows,
    });
  } catch (error: any) {
    logger.error("연쇄 관계 목록 조회 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 목록 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계 상세 조회
 */
export const getCascadingRelationById = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { id } = req.params;
    const companyCode = req.user?.companyCode || "*";

    let query = `
      SELECT 
        relation_id,
        relation_code,
        relation_name,
        description,
        parent_table,
        parent_value_column,
        parent_label_column,
        child_table,
        child_filter_column,
        child_value_column,
        child_label_column,
        child_order_column,
        child_order_direction,
        empty_parent_message,
        no_options_message,
        loading_message,
        clear_on_parent_change,
        company_code,
        is_active,
        created_by,
        created_date,
        updated_by,
        updated_date
      FROM cascading_relation
      WHERE relation_id = $1
    `;

    const params: any[] = [id];

    // 멀티테넌시 필터링 (company_code = "*"는 최고 관리자 전용)
    if (companyCode !== "*") {
      query += ` AND company_code = $2`;
      params.push(companyCode);
    }

    const result = await pool.query(query, params);

    if (result.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    return res.json({
      success: true,
      data: result.rows[0],
    });
  } catch (error: any) {
    logger.error("연쇄 관계 상세 조회 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계 코드로 조회
 */
export const getCascadingRelationByCode = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { code } = req.params;
    const companyCode = req.user?.companyCode || "*";

    let query = `
      SELECT 
        relation_id,
        relation_code,
        relation_name,
        description,
        parent_table,
        parent_value_column,
        parent_label_column,
        child_table,
        child_filter_column,
        child_value_column,
        child_label_column,
        child_order_column,
        child_order_direction,
        empty_parent_message,
        no_options_message,
        loading_message,
        clear_on_parent_change,
        company_code,
        is_active
      FROM cascading_relation
      WHERE relation_code = $1
        AND is_active = 'Y'
    `;

    const params: any[] = [code];

    // 멀티테넌시 필터링 (company_code = "*"는 최고 관리자 전용)
    if (companyCode !== "*") {
      query += ` AND company_code = $2`;
      params.push(companyCode);
    }
    query += ` LIMIT 1`;

    const result = await pool.query(query, params);

    if (result.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    return res.json({
      success: true,
      data: result.rows[0],
    });
  } catch (error: any) {
    logger.error("연쇄 관계 코드 조회 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계 생성
 */
export const createCascadingRelation = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";

    const {
      relationCode,
      relationName,
      description,
      parentTable,
      parentValueColumn,
      parentLabelColumn,
      childTable,
      childFilterColumn,
      childValueColumn,
      childLabelColumn,
      childOrderColumn,
      childOrderDirection,
      emptyParentMessage,
      noOptionsMessage,
      loadingMessage,
      clearOnParentChange,
    } = req.body;

    // 필수 필드 검증
    if (
      !relationCode ||
      !relationName ||
      !parentTable ||
      !parentValueColumn ||
      !childTable ||
      !childFilterColumn ||
      !childValueColumn ||
      !childLabelColumn
    ) {
      return res.status(400).json({
        success: false,
        message: "필수 필드가 누락되었습니다.",
      });
    }

    // 중복 코드 체크
    const duplicateCheck = await pool.query(
      `SELECT relation_id FROM cascading_relation 
       WHERE relation_code = $1 AND company_code = $2`,
      [relationCode, companyCode]
    );

    if (duplicateCheck.rowCount && duplicateCheck.rowCount > 0) {
      return res.status(400).json({
        success: false,
        message: "이미 존재하는 관계 코드입니다.",
      });
    }

    const query = `
      INSERT INTO cascading_relation (
        relation_code,
        relation_name,
        description,
        parent_table,
        parent_value_column,
        parent_label_column,
        child_table,
        child_filter_column,
        child_value_column,
        child_label_column,
        child_order_column,
        child_order_direction,
        empty_parent_message,
        no_options_message,
        loading_message,
        clear_on_parent_change,
        company_code,
        is_active,
        created_by,
        created_date
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, 'Y', $18, CURRENT_TIMESTAMP)
      RETURNING *
    `;

    const result = await pool.query(query, [
      relationCode,
      relationName,
      description || null,
      parentTable,
      parentValueColumn,
      parentLabelColumn || null,
      childTable,
      childFilterColumn,
      childValueColumn,
      childLabelColumn,
      childOrderColumn || null,
      childOrderDirection || "ASC",
      emptyParentMessage || "상위 항목을 먼저 선택하세요",
      noOptionsMessage || "선택 가능한 항목이 없습니다",
      loadingMessage || "로딩 중...",
      clearOnParentChange !== false ? "Y" : "N",
      companyCode,
      userId,
    ]);

    logger.info("연쇄 관계 생성", {
      relationId: result.rows[0].relation_id,
      relationCode,
      companyCode,
      userId,
    });

    return res.status(201).json({
      success: true,
      data: result.rows[0],
      message: "연쇄 관계가 생성되었습니다.",
    });
  } catch (error: any) {
    logger.error("연쇄 관계 생성 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 생성에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계 수정
 */
export const updateCascadingRelation = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { id } = req.params;
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";

    const {
      relationName,
      description,
      parentTable,
      parentValueColumn,
      parentLabelColumn,
      childTable,
      childFilterColumn,
      childValueColumn,
      childLabelColumn,
      childOrderColumn,
      childOrderDirection,
      emptyParentMessage,
      noOptionsMessage,
      loadingMessage,
      clearOnParentChange,
      isActive,
    } = req.body;

    // 권한 체크
    const existingCheck = await pool.query(
      `SELECT relation_id, company_code FROM cascading_relation WHERE relation_id = $1`,
      [id]
    );

    if (existingCheck.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    // 다른 회사의 데이터는 수정 불가 (최고 관리자 제외)
    const existingCompanyCode = existingCheck.rows[0].company_code;
    if (
      companyCode !== "*" &&
      existingCompanyCode !== companyCode &&
      existingCompanyCode !== "*"
    ) {
      return res.status(403).json({
        success: false,
        message: "수정 권한이 없습니다.",
      });
    }

    const query = `
      UPDATE cascading_relation SET
        relation_name = COALESCE($1, relation_name),
        description = COALESCE($2, description),
        parent_table = COALESCE($3, parent_table),
        parent_value_column = COALESCE($4, parent_value_column),
        parent_label_column = COALESCE($5, parent_label_column),
        child_table = COALESCE($6, child_table),
        child_filter_column = COALESCE($7, child_filter_column),
        child_value_column = COALESCE($8, child_value_column),
        child_label_column = COALESCE($9, child_label_column),
        child_order_column = COALESCE($10, child_order_column),
        child_order_direction = COALESCE($11, child_order_direction),
        empty_parent_message = COALESCE($12, empty_parent_message),
        no_options_message = COALESCE($13, no_options_message),
        loading_message = COALESCE($14, loading_message),
        clear_on_parent_change = COALESCE($15, clear_on_parent_change),
        is_active = COALESCE($16, is_active),
        updated_by = $17,
        updated_date = CURRENT_TIMESTAMP
      WHERE relation_id = $18
      RETURNING *
    `;

    const result = await pool.query(query, [
      relationName,
      description,
      parentTable,
      parentValueColumn,
      parentLabelColumn,
      childTable,
      childFilterColumn,
      childValueColumn,
      childLabelColumn,
      childOrderColumn,
      childOrderDirection,
      emptyParentMessage,
      noOptionsMessage,
      loadingMessage,
      clearOnParentChange !== undefined
        ? clearOnParentChange
          ? "Y"
          : "N"
        : null,
      isActive !== undefined ? (isActive ? "Y" : "N") : null,
      userId,
      id,
    ]);

    logger.info("연쇄 관계 수정", {
      relationId: id,
      companyCode,
      userId,
    });

    return res.json({
      success: true,
      data: result.rows[0],
      message: "연쇄 관계가 수정되었습니다.",
    });
  } catch (error: any) {
    logger.error("연쇄 관계 수정 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 수정에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계 삭제
 */
export const deleteCascadingRelation = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { id } = req.params;
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";

    // 권한 체크
    const existingCheck = await pool.query(
      `SELECT relation_id, company_code FROM cascading_relation WHERE relation_id = $1`,
      [id]
    );

    if (existingCheck.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    // 다른 회사의 데이터는 삭제 불가 (최고 관리자 제외)
    const existingCompanyCode = existingCheck.rows[0].company_code;
    if (
      companyCode !== "*" &&
      existingCompanyCode !== companyCode &&
      existingCompanyCode !== "*"
    ) {
      return res.status(403).json({
        success: false,
        message: "삭제 권한이 없습니다.",
      });
    }

    // 소프트 삭제 (is_active = 'N')
    await pool.query(
      `UPDATE cascading_relation SET is_active = 'N', updated_by = $1, updated_date = CURRENT_TIMESTAMP WHERE relation_id = $2`,
      [userId, id]
    );

    logger.info("연쇄 관계 삭제", {
      relationId: id,
      companyCode,
      userId,
    });

    return res.json({
      success: true,
      message: "연쇄 관계가 삭제되었습니다.",
    });
  } catch (error: any) {
    logger.error("연쇄 관계 삭제 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 관계 삭제에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 🆕 연쇄 관계로 부모 옵션 조회 (상위 선택 역할용)
 * parent_table에서 전체 옵션을 조회합니다.
 */
export const getParentOptions = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { code } = req.params;
    const companyCode = req.user?.companyCode || "*";

    // 관계 정보 조회
    let relationQuery = `
      SELECT 
        parent_table,
        parent_value_column,
        parent_label_column
      FROM cascading_relation
      WHERE relation_code = $1
        AND is_active = 'Y'
    `;

    const relationParams: any[] = [code];

    // 멀티테넌시 필터링 (company_code = "*"는 최고 관리자 전용)
    if (companyCode !== "*") {
      relationQuery += ` AND company_code = $2`;
      relationParams.push(companyCode);
    }
    relationQuery += ` LIMIT 1`;

    const relationResult = await pool.query(relationQuery, relationParams);

    if (relationResult.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    const relation = relationResult.rows[0];

    // 라벨 컬럼이 없으면 값 컬럼 사용
    const labelColumn =
      relation.parent_label_column || relation.parent_value_column;

    // 부모 옵션 조회
    let optionsQuery = `
      SELECT 
        ${relation.parent_value_column} as value,
        ${labelColumn} as label
      FROM ${relation.parent_table}
      WHERE 1=1
    `;

    // 멀티테넌시 적용 (테이블에 company_code가 있는 경우)
    const tableInfoResult = await pool.query(
      `SELECT column_name FROM information_schema.columns 
       WHERE table_name = $1 AND column_name = 'company_code'`,
      [relation.parent_table]
    );

    const optionsParams: any[] = [];

    // company_code = "*"는 최고 관리자 전용이므로 일반 회사는 자기 회사 데이터만
    if (
      tableInfoResult.rowCount &&
      tableInfoResult.rowCount > 0 &&
      companyCode !== "*"
    ) {
      optionsQuery += ` AND company_code = $1`;
      optionsParams.push(companyCode);
    }

    // status 컬럼이 있으면 활성 상태만 조회
    const statusInfoResult = await pool.query(
      `SELECT column_name FROM information_schema.columns 
       WHERE table_name = $1 AND column_name = 'status'`,
      [relation.parent_table]
    );

    if (statusInfoResult.rowCount && statusInfoResult.rowCount > 0) {
      optionsQuery += ` AND (status IS NULL OR status != 'N')`;
    }

    // 정렬
    optionsQuery += ` ORDER BY ${labelColumn} ASC`;

    const optionsResult = await pool.query(optionsQuery, optionsParams);

    logger.info("부모 옵션 조회", {
      relationCode: code,
      parentTable: relation.parent_table,
      optionsCount: optionsResult.rowCount,
    });

    return res.json({
      success: true,
      data: optionsResult.rows,
    });
  } catch (error: any) {
    logger.error("부모 옵션 조회 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "부모 옵션 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 연쇄 관계로 자식 옵션 조회
 * 실제 연쇄 드롭다운에서 사용하는 API
 * 
 * 다중 부모값 지원:
 * - parentValue: 단일 값 (예: "공정검사")
 * - parentValues: 다중 값 (예: "공정검사,출하검사" 또는 배열)
 */
export const getCascadingOptions = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { code } = req.params;
    const { parentValue, parentValues } = req.query;
    const companyCode = req.user?.companyCode || "*";

    // 다중 부모값 파싱
    let parentValueArray: string[] = [];
    
    if (parentValues) {
      // parentValues가 있으면 우선 사용 (다중 선택)
      if (Array.isArray(parentValues)) {
        parentValueArray = parentValues.map(v => String(v));
      } else {
        // 콤마로 구분된 문자열
        parentValueArray = String(parentValues).split(',').map(v => v.trim()).filter(v => v);
      }
    } else if (parentValue) {
      // 기존 단일 값 호환
      parentValueArray = [String(parentValue)];
    }

    if (parentValueArray.length === 0) {
      return res.json({
        success: true,
        data: [],
        message: "부모 값이 없습니다.",
      });
    }

    // 관계 정보 조회
    let relationQuery = `
      SELECT 
        child_table,
        child_filter_column,
        child_value_column,
        child_label_column,
        child_order_column,
        child_order_direction
      FROM cascading_relation
      WHERE relation_code = $1
        AND is_active = 'Y'
    `;

    const relationParams: any[] = [code];

    // 멀티테넌시 필터링 (company_code = "*"는 최고 관리자 전용)
    if (companyCode !== "*") {
      relationQuery += ` AND company_code = $2`;
      relationParams.push(companyCode);
    }
    relationQuery += ` LIMIT 1`;

    const relationResult = await pool.query(relationQuery, relationParams);

    if (relationResult.rowCount === 0) {
      return res.status(404).json({
        success: false,
        message: "연쇄 관계를 찾을 수 없습니다.",
      });
    }

    const relation = relationResult.rows[0];

    // 자식 옵션 조회 - 다중 부모값에 대해 IN 절 사용
    // SQL Injection 방지를 위해 파라미터화된 쿼리 사용
    const placeholders = parentValueArray.map((_, idx) => `$${idx + 1}`).join(', ');
    
    let optionsQuery = `
      SELECT DISTINCT
        ${relation.child_value_column} as value,
        ${relation.child_label_column} as label,
        ${relation.child_filter_column} as parent_value
      FROM ${relation.child_table}
      WHERE ${relation.child_filter_column} IN (${placeholders})
    `;

    // 멀티테넌시 적용 (테이블에 company_code가 있는 경우)
    const tableInfoResult = await pool.query(
      `SELECT column_name FROM information_schema.columns 
       WHERE table_name = $1 AND column_name = 'company_code'`,
      [relation.child_table]
    );

    const optionsParams: any[] = [...parentValueArray];
    let paramIndex = parentValueArray.length + 1;

    // company_code = "*"는 최고 관리자 전용이므로 일반 회사는 자기 회사 데이터만
    if (
      tableInfoResult.rowCount &&
      tableInfoResult.rowCount > 0 &&
      companyCode !== "*"
    ) {
      optionsQuery += ` AND company_code = $${paramIndex}`;
      optionsParams.push(companyCode);
      paramIndex++;
    }

    // 정렬
    if (relation.child_order_column) {
      optionsQuery += ` ORDER BY ${relation.child_order_column} ${relation.child_order_direction || "ASC"}`;
    } else {
      optionsQuery += ` ORDER BY ${relation.child_label_column} ASC`;
    }

    const optionsResult = await pool.query(optionsQuery, optionsParams);

    logger.info("연쇄 옵션 조회 (다중 부모값 지원)", {
      relationCode: code,
      parentValues: parentValueArray,
      optionsCount: optionsResult.rowCount,
    });

    return res.json({
      success: true,
      data: optionsResult.rows,
    });
  } catch (error: any) {
    logger.error("연쇄 옵션 조회 실패", { error: error.message });
    return res.status(500).json({
      success: false,
      message: "연쇄 옵션 조회에 실패했습니다.",
      error: error.message,
    });
  }
};
