/**
 * 자동 입력 (Auto-Fill) 컨트롤러
 * 마스터 선택 시 여러 필드 자동 입력 기능
 */

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

// =====================================================
// 자동 입력 그룹 CRUD
// =====================================================

/**
 * 자동 입력 그룹 목록 조회
 */
export const getAutoFillGroups = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const companyCode = req.user?.companyCode || "*";
    const { isActive } = req.query;

    let sql = `
      SELECT 
        g.*,
        COUNT(m.mapping_id) as mapping_count
      FROM cascading_auto_fill_group g
      LEFT JOIN cascading_auto_fill_mapping m 
        ON g.group_code = m.group_code AND g.company_code = m.company_code
      WHERE 1=1
    `;
    const params: any[] = [];
    let paramIndex = 1;

    // 회사 필터
    if (companyCode !== "*") {
      sql += ` AND g.company_code = $${paramIndex++}`;
      params.push(companyCode);
    }

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

    sql += ` GROUP BY g.group_id ORDER BY g.group_name`;

    const result = await query(sql, params);

    logger.info("자동 입력 그룹 목록 조회", {
      count: result.length,
      companyCode,
    });

    res.json({
      success: true,
      data: result,
    });
  } catch (error: any) {
    logger.error("자동 입력 그룹 목록 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 그룹 목록 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 자동 입력 그룹 상세 조회 (매핑 포함)
 */
export const getAutoFillGroupDetail = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { groupCode } = req.params;
    const companyCode = req.user?.companyCode || "*";

    // 그룹 정보 조회
    let groupSql = `
      SELECT * FROM cascading_auto_fill_group
      WHERE group_code = $1
    `;
    const groupParams: any[] = [groupCode];

    if (companyCode !== "*") {
      groupSql += ` AND company_code = $2`;
      groupParams.push(companyCode);
    }

    const groupResult = await queryOne(groupSql, groupParams);

    if (!groupResult) {
      return res.status(404).json({
        success: false,
        message: "자동 입력 그룹을 찾을 수 없습니다.",
      });
    }

    // 매핑 정보 조회
    const mappingSql = `
      SELECT * FROM cascading_auto_fill_mapping
      WHERE group_code = $1 AND company_code = $2
      ORDER BY sort_order, mapping_id
    `;
    const mappingResult = await query(mappingSql, [
      groupCode,
      groupResult.company_code,
    ]);

    logger.info("자동 입력 그룹 상세 조회", { groupCode, companyCode });

    res.json({
      success: true,
      data: {
        ...groupResult,
        mappings: mappingResult,
      },
    });
  } catch (error: any) {
    logger.error("자동 입력 그룹 상세 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 그룹 상세 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 그룹 코드 자동 생성 함수
 */
const generateAutoFillGroupCode = async (
  companyCode: string
): Promise<string> => {
  const prefix = "AF";
  const result = await queryOne(
    `SELECT COUNT(*) as cnt FROM cascading_auto_fill_group WHERE company_code = $1`,
    [companyCode]
  );
  const count = parseInt(result?.cnt || "0", 10) + 1;
  const timestamp = Date.now().toString(36).toUpperCase().slice(-4);
  return `${prefix}_${timestamp}_${count.toString().padStart(3, "0")}`;
};

/**
 * 자동 입력 그룹 생성
 */
export const createAutoFillGroup = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";
    const {
      groupName,
      description,
      masterTable,
      masterValueColumn,
      masterLabelColumn,
      mappings = [],
    } = req.body;

    // 필수 필드 검증
    if (!groupName || !masterTable || !masterValueColumn) {
      return res.status(400).json({
        success: false,
        message:
          "필수 필드가 누락되었습니다. (groupName, masterTable, masterValueColumn)",
      });
    }

    // 그룹 코드 자동 생성
    const groupCode = await generateAutoFillGroupCode(companyCode);

    // 그룹 생성
    const insertGroupSql = `
      INSERT INTO cascading_auto_fill_group (
        group_code, group_name, description,
        master_table, master_value_column, master_label_column,
        company_code, is_active, created_date
      ) VALUES ($1, $2, $3, $4, $5, $6, $7, 'Y', CURRENT_TIMESTAMP)
      RETURNING *
    `;

    const groupResult = await queryOne(insertGroupSql, [
      groupCode,
      groupName,
      description || null,
      masterTable,
      masterValueColumn,
      masterLabelColumn || null,
      companyCode,
    ]);

    // 매핑 생성
    if (mappings.length > 0) {
      for (let i = 0; i < mappings.length; i++) {
        const m = mappings[i];
        await query(
          `INSERT INTO cascading_auto_fill_mapping (
            group_code, company_code, source_column, target_field, target_label,
            is_editable, is_required, default_value, sort_order
          ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
          [
            groupCode,
            companyCode,
            m.sourceColumn,
            m.targetField,
            m.targetLabel || null,
            m.isEditable || "Y",
            m.isRequired || "N",
            m.defaultValue || null,
            m.sortOrder || i + 1,
          ]
        );
      }
    }

    logger.info("자동 입력 그룹 생성", { groupCode, companyCode, userId });

    res.status(201).json({
      success: true,
      message: "자동 입력 그룹이 생성되었습니다.",
      data: groupResult,
    });
  } catch (error: any) {
    logger.error("자동 입력 그룹 생성 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 그룹 생성에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 자동 입력 그룹 수정
 */
export const updateAutoFillGroup = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { groupCode } = req.params;
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";
    const {
      groupName,
      description,
      masterTable,
      masterValueColumn,
      masterLabelColumn,
      isActive,
      mappings,
    } = req.body;

    // 기존 그룹 확인
    let checkSql = `SELECT * FROM cascading_auto_fill_group WHERE group_code = $1`;
    const checkParams: any[] = [groupCode];

    if (companyCode !== "*") {
      checkSql += ` AND company_code = $2`;
      checkParams.push(companyCode);
    }

    const existing = await queryOne(checkSql, checkParams);

    if (!existing) {
      return res.status(404).json({
        success: false,
        message: "자동 입력 그룹을 찾을 수 없습니다.",
      });
    }

    // 그룹 업데이트
    const updateSql = `
      UPDATE cascading_auto_fill_group SET
        group_name = COALESCE($1, group_name),
        description = COALESCE($2, description),
        master_table = COALESCE($3, master_table),
        master_value_column = COALESCE($4, master_value_column),
        master_label_column = COALESCE($5, master_label_column),
        is_active = COALESCE($6, is_active),
        updated_date = CURRENT_TIMESTAMP
      WHERE group_code = $7 AND company_code = $8
      RETURNING *
    `;

    const updateResult = await queryOne(updateSql, [
      groupName,
      description,
      masterTable,
      masterValueColumn,
      masterLabelColumn,
      isActive,
      groupCode,
      existing.company_code,
    ]);

    // 매핑 업데이트 (전체 교체 방식)
    if (mappings !== undefined) {
      // 기존 매핑 삭제
      await query(
        `DELETE FROM cascading_auto_fill_mapping WHERE group_code = $1 AND company_code = $2`,
        [groupCode, existing.company_code]
      );

      // 새 매핑 추가
      for (let i = 0; i < mappings.length; i++) {
        const m = mappings[i];
        await query(
          `INSERT INTO cascading_auto_fill_mapping (
            group_code, company_code, source_column, target_field, target_label,
            is_editable, is_required, default_value, sort_order
          ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
          [
            groupCode,
            existing.company_code,
            m.sourceColumn,
            m.targetField,
            m.targetLabel || null,
            m.isEditable || "Y",
            m.isRequired || "N",
            m.defaultValue || null,
            m.sortOrder || i + 1,
          ]
        );
      }
    }

    logger.info("자동 입력 그룹 수정", { groupCode, companyCode, userId });

    res.json({
      success: true,
      message: "자동 입력 그룹이 수정되었습니다.",
      data: updateResult,
    });
  } catch (error: any) {
    logger.error("자동 입력 그룹 수정 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 그룹 수정에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 자동 입력 그룹 삭제
 */
export const deleteAutoFillGroup = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { groupCode } = req.params;
    const companyCode = req.user?.companyCode || "*";
    const userId = req.user?.userId || "system";

    let deleteSql = `DELETE FROM cascading_auto_fill_group WHERE group_code = $1`;
    const deleteParams: any[] = [groupCode];

    if (companyCode !== "*") {
      deleteSql += ` AND company_code = $2`;
      deleteParams.push(companyCode);
    }

    deleteSql += ` RETURNING group_code`;

    const result = await queryOne(deleteSql, deleteParams);

    if (!result) {
      return res.status(404).json({
        success: false,
        message: "자동 입력 그룹을 찾을 수 없습니다.",
      });
    }

    logger.info("자동 입력 그룹 삭제", { groupCode, companyCode, userId });

    res.json({
      success: true,
      message: "자동 입력 그룹이 삭제되었습니다.",
    });
  } catch (error: any) {
    logger.error("자동 입력 그룹 삭제 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 그룹 삭제에 실패했습니다.",
      error: error.message,
    });
  }
};

// =====================================================
// 자동 입력 데이터 조회 (실제 사용)
// =====================================================

/**
 * 마스터 옵션 목록 조회
 * 자동 입력 그룹의 마스터 테이블에서 선택 가능한 옵션 목록
 */
export const getAutoFillMasterOptions = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { groupCode } = req.params;
    const companyCode = req.user?.companyCode || "*";

    // 그룹 정보 조회
    let groupSql = `SELECT * FROM cascading_auto_fill_group WHERE group_code = $1 AND is_active = 'Y'`;
    const groupParams: any[] = [groupCode];

    if (companyCode !== "*") {
      groupSql += ` AND company_code = $2`;
      groupParams.push(companyCode);
    }

    const group = await queryOne(groupSql, groupParams);

    if (!group) {
      return res.status(404).json({
        success: false,
        message: "자동 입력 그룹을 찾을 수 없습니다.",
      });
    }

    // 마스터 테이블에서 옵션 조회
    const labelColumn = group.master_label_column || group.master_value_column;
    let optionsSql = `
      SELECT 
        ${group.master_value_column} as value,
        ${labelColumn} as label
      FROM ${group.master_table}
      WHERE 1=1
    `;
    const optionsParams: any[] = [];
    let paramIndex = 1;

    // 멀티테넌시 필터 (테이블에 company_code가 있는 경우)
    if (companyCode !== "*") {
      // company_code 컬럼 존재 여부 확인
      const columnCheck = await queryOne(
        `SELECT column_name FROM information_schema.columns 
         WHERE table_name = $1 AND column_name = 'company_code'`,
        [group.master_table]
      );

      if (columnCheck) {
        optionsSql += ` AND company_code = $${paramIndex++}`;
        optionsParams.push(companyCode);
      }
    }

    optionsSql += ` ORDER BY ${labelColumn}`;

    const optionsResult = await query(optionsSql, optionsParams);

    logger.info("자동 입력 마스터 옵션 조회", {
      groupCode,
      count: optionsResult.length,
    });

    res.json({
      success: true,
      data: optionsResult,
    });
  } catch (error: any) {
    logger.error("자동 입력 마스터 옵션 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 마스터 옵션 조회에 실패했습니다.",
      error: error.message,
    });
  }
};

/**
 * 자동 입력 데이터 조회
 * 마스터 값 선택 시 자동으로 입력할 데이터 조회
 */
export const getAutoFillData = async (
  req: AuthenticatedRequest,
  res: Response
) => {
  try {
    const { groupCode } = req.params;
    const { masterValue } = req.query;
    const companyCode = req.user?.companyCode || "*";

    if (!masterValue) {
      return res.status(400).json({
        success: false,
        message: "masterValue 파라미터가 필요합니다.",
      });
    }

    // 그룹 정보 조회
    let groupSql = `SELECT * FROM cascading_auto_fill_group WHERE group_code = $1 AND is_active = 'Y'`;
    const groupParams: any[] = [groupCode];

    if (companyCode !== "*") {
      groupSql += ` AND company_code = $2`;
      groupParams.push(companyCode);
    }

    const group = await queryOne(groupSql, groupParams);

    if (!group) {
      return res.status(404).json({
        success: false,
        message: "자동 입력 그룹을 찾을 수 없습니다.",
      });
    }

    // 매핑 정보 조회
    const mappingSql = `
      SELECT * FROM cascading_auto_fill_mapping
      WHERE group_code = $1 AND company_code = $2
      ORDER BY sort_order
    `;
    const mappings = await query(mappingSql, [groupCode, group.company_code]);

    if (mappings.length === 0) {
      return res.json({
        success: true,
        data: {},
        mappings: [],
      });
    }

    // 마스터 테이블에서 데이터 조회
    const sourceColumns = mappings.map((m: any) => m.source_column).join(", ");
    let dataSql = `
      SELECT ${sourceColumns}
      FROM ${group.master_table}
      WHERE ${group.master_value_column} = $1
    `;
    const dataParams: any[] = [masterValue];
    let paramIndex = 2;

    // 멀티테넌시 필터
    if (companyCode !== "*") {
      const columnCheck = await queryOne(
        `SELECT column_name FROM information_schema.columns 
         WHERE table_name = $1 AND column_name = 'company_code'`,
        [group.master_table]
      );

      if (columnCheck) {
        dataSql += ` AND company_code = $${paramIndex++}`;
        dataParams.push(companyCode);
      }
    }

    const dataResult = await queryOne(dataSql, dataParams);

    // 결과를 target_field 기준으로 변환
    const autoFillData: Record<string, any> = {};
    const mappingInfo: any[] = [];

    for (const mapping of mappings) {
      const sourceValue = dataResult?.[mapping.source_column];
      const finalValue =
        sourceValue !== null && sourceValue !== undefined
          ? sourceValue
          : mapping.default_value;

      autoFillData[mapping.target_field] = finalValue;
      mappingInfo.push({
        targetField: mapping.target_field,
        targetLabel: mapping.target_label,
        value: finalValue,
        isEditable: mapping.is_editable === "Y",
        isRequired: mapping.is_required === "Y",
      });
    }

    logger.info("자동 입력 데이터 조회", {
      groupCode,
      masterValue,
      fieldCount: mappingInfo.length,
    });

    res.json({
      success: true,
      data: autoFillData,
      mappings: mappingInfo,
    });
  } catch (error: any) {
    logger.error("자동 입력 데이터 조회 실패", { error: error.message });
    res.status(500).json({
      success: false,
      message: "자동 입력 데이터 조회에 실패했습니다.",
      error: error.message,
    });
  }
};
