/**
 * 공정 작업기준 컨트롤러
 * 품목별 라우팅/공정에 대한 작업 항목 및 상세 관리
 */

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

// ============================================================
// 품목/라우팅/공정 조회 (좌측 트리 데이터)
// ============================================================

/**
 * 라우팅이 있는 품목 목록 조회
 * 요청 쿼리: tableName(품목테이블), nameColumn, codeColumn
 */
export async function getItemsWithRouting(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const {
      tableName = "item_info",
      nameColumn = "item_name",
      codeColumn = "item_number",
      routingTable = "item_routing_version",
      routingFkColumn = "item_code",
      search = "",
      extraColumns = "",
      filterConditions = "",
    } = req.query as Record<string, string>;

    const params: any[] = [companyCode];
    let paramIndex = 2;

    // 검색 조건
    let searchCondition = "";
    if (search) {
      searchCondition = `AND (i.${nameColumn} ILIKE $${paramIndex} OR i.${codeColumn} ILIKE $${paramIndex})`;
      params.push(`%${search}%`);
      paramIndex++;
    }

    // 추가 컬럼 SELECT
    const extraColumnNames: string[] = extraColumns
      ? extraColumns.split(",").map((c: string) => c.trim()).filter(Boolean)
      : [];
    const extraSelect = extraColumnNames.map((col) => `i.${col}`).join(", ");
    const extraGroupBy = extraColumnNames.map((col) => `i.${col}`).join(", ");

    // 사전 필터 조건
    let filterWhere = "";
    if (filterConditions) {
      try {
        const filters = JSON.parse(filterConditions) as Array<{
          column: string;
          operator: string;
          value: string;
        }>;
        for (const f of filters) {
          if (!f.column || !f.value) continue;
          if (f.operator === "equals") {
            filterWhere += ` AND i.${f.column} = $${paramIndex}`;
            params.push(f.value);
          } else if (f.operator === "contains") {
            filterWhere += ` AND i.${f.column} ILIKE $${paramIndex}`;
            params.push(`%${f.value}%`);
          } else if (f.operator === "not_equals") {
            filterWhere += ` AND i.${f.column} != $${paramIndex}`;
            params.push(f.value);
          }
          paramIndex++;
        }
      } catch { /* 파싱 실패 시 무시 */ }
    }

    const query = `
      SELECT
        i.id,
        i.${nameColumn} AS item_name,
        i.${codeColumn} AS item_code
        ${extraSelect ? ", " + extraSelect : ""},
        COUNT(rv.id) AS routing_count
      FROM ${tableName} i
      LEFT JOIN ${routingTable} rv ON rv.${routingFkColumn} = i.${codeColumn}
        AND rv.company_code = i.company_code
      WHERE i.company_code = $1
        ${searchCondition}
        ${filterWhere}
      GROUP BY i.id, i.${nameColumn}, i.${codeColumn}${extraGroupBy ? ", " + extraGroupBy : ""}, i.created_date
      ORDER BY i.created_date DESC NULLS LAST
    `;

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

    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.message });
  }
}

/**
 * 품목별 라우팅 버전 + 공정 목록 조회 (트리 하위 데이터)
 */
export async function getRoutingsWithProcesses(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { itemCode } = req.params;
    const {
      routingVersionTable = "item_routing_version",
      routingDetailTable = "item_routing_detail",
      routingFkColumn = "item_code",
      processTable = "process_mng",
      processNameColumn = "process_name",
      processCodeColumn = "process_code",
    } = req.query as Record<string, string>;

    // 라우팅 버전 목록
    const versionsQuery = `
      SELECT id, version_name, description, created_date, COALESCE(is_default, false) AS is_default
      FROM ${routingVersionTable}
      WHERE ${routingFkColumn} = $1 AND company_code = $2
      ORDER BY is_default DESC, created_date DESC
    `;
    const versionsResult = await getPool().query(versionsQuery, [
      itemCode,
      companyCode,
    ]);

    // 각 버전별 공정 목록
    const routings = [];
    for (const version of versionsResult.rows) {
      const detailsQuery = `
        SELECT
          rd.id AS routing_detail_id,
          rd.seq_no,
          rd.process_code,
          rd.is_required,
          rd.work_type,
          p.${processNameColumn} AS process_name
        FROM ${routingDetailTable} rd
        LEFT JOIN ${processTable} p ON p.${processCodeColumn} = rd.process_code
          AND p.company_code = rd.company_code
        WHERE rd.routing_version_id = $1 AND rd.company_code = $2
        ORDER BY rd.seq_no::integer
      `;
      const detailsResult = await getPool().query(detailsQuery, [
        version.id,
        companyCode,
      ]);

      routings.push({
        ...version,
        processes: detailsResult.rows,
      });
    }

    return res.json({ success: true, data: routings });
  } catch (error: any) {
    logger.error("라우팅/공정 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================================
// 기본 버전 설정
// ============================================================

/**
 * 라우팅 버전을 기본 버전으로 설정
 * 같은 품목의 다른 버전은 기본 해제
 */
export async function setDefaultVersion(req: AuthenticatedRequest, res: Response) {
  const pool = getPool();
  const client = await pool.connect();
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { versionId } = req.params;
    const {
      routingVersionTable = "item_routing_version",
      routingFkColumn = "item_code",
    } = req.body;

    await client.query("BEGIN");

    const versionResult = await client.query(
      `SELECT ${routingFkColumn} AS item_code FROM ${routingVersionTable} WHERE id = $1 AND company_code = $2`,
      [versionId, companyCode]
    );

    if (versionResult.rowCount === 0) {
      await client.query("ROLLBACK");
      return res.status(404).json({ success: false, message: "버전을 찾을 수 없습니다" });
    }

    const itemCode = versionResult.rows[0].item_code;

    await client.query(
      `UPDATE ${routingVersionTable} SET is_default = false WHERE ${routingFkColumn} = $1 AND company_code = $2`,
      [itemCode, companyCode]
    );

    await client.query(
      `UPDATE ${routingVersionTable} SET is_default = true WHERE id = $1 AND company_code = $2`,
      [versionId, companyCode]
    );

    await client.query("COMMIT");

    logger.info("기본 버전 설정", { companyCode, versionId, itemCode });
    return res.json({ success: true, message: "기본 버전이 설정되었습니다" });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("기본 버전 설정 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

/**
 * 기본 버전 해제
 */
export async function unsetDefaultVersion(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { versionId } = req.params;
    const { routingVersionTable = "item_routing_version" } = req.body;

    await getPool().query(
      `UPDATE ${routingVersionTable} SET is_default = false WHERE id = $1 AND company_code = $2`,
      [versionId, companyCode]
    );

    logger.info("기본 버전 해제", { companyCode, versionId });
    return res.json({ success: true, message: "기본 버전이 해제되었습니다" });
  } catch (error: any) {
    logger.error("기본 버전 해제 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================================
// 작업 항목 CRUD
// ============================================================

/**
 * 공정별 작업 항목 목록 조회 (phase별 그룹)
 */
export async function getWorkItems(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { routingDetailId } = req.params;

    const query = `
      SELECT
        wi.id,
        wi.routing_detail_id,
        wi.work_phase,
        wi.title,
        wi.is_required,
        wi.sort_order,
        wi.description,
        wi.created_date,
        (SELECT COUNT(*) FROM process_work_item_detail d
         WHERE d.work_item_id = wi.id AND d.company_code = wi.company_code
        )::integer AS detail_count
      FROM process_work_item wi
      WHERE wi.routing_detail_id = $1 AND wi.company_code = $2
      ORDER BY wi.work_phase, wi.sort_order, wi.created_date
    `;

    const result = await getPool().query(query, [routingDetailId, companyCode]);

    // phase별 그룹핑
    const grouped: Record<string, any[]> = {};
    for (const row of result.rows) {
      const phase = row.work_phase;
      if (!grouped[phase]) grouped[phase] = [];
      grouped[phase].push(row);
    }

    return res.json({ success: true, data: grouped, items: result.rows });
  } catch (error: any) {
    logger.error("작업 항목 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

/**
 * 작업 항목 추가
 */
export async function createWorkItem(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    const writer = req.user?.userId;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { routing_detail_id, work_phase, title, is_required, sort_order, description } = req.body;

    if (!routing_detail_id || !work_phase || !title) {
      return res.status(400).json({
        success: false,
        message: "routing_detail_id, work_phase, title은 필수입니다",
      });
    }

    const query = `
      INSERT INTO process_work_item
        (company_code, routing_detail_id, work_phase, title, is_required, sort_order, description, writer)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
      RETURNING *
    `;

    const result = await getPool().query(query, [
      companyCode,
      routing_detail_id,
      work_phase,
      title,
      is_required || "N",
      sort_order || 0,
      description || null,
      writer,
    ]);

    logger.info("작업 항목 생성", { companyCode, id: result.rows[0].id });
    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.message });
  }
}

/**
 * 작업 항목 수정
 */
export async function updateWorkItem(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { id } = req.params;
    const { title, is_required, sort_order, description } = req.body;

    const query = `
      UPDATE process_work_item
      SET title = COALESCE($1, title),
          is_required = COALESCE($2, is_required),
          sort_order = COALESCE($3, sort_order),
          description = COALESCE($4, description),
          updated_date = NOW()
      WHERE id = $5 AND company_code = $6
      RETURNING *
    `;

    const result = await getPool().query(query, [
      title,
      is_required,
      sort_order,
      description,
      id,
      companyCode,
    ]);

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

    logger.info("작업 항목 수정", { companyCode, id });
    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.message });
  }
}

/**
 * 작업 항목 삭제 (상세도 함께 삭제)
 */
export async function deleteWorkItem(req: AuthenticatedRequest, res: Response) {
  const client = await getPool().connect();
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { id } = req.params;

    await client.query("BEGIN");

    // 상세 먼저 삭제
    await client.query(
      "DELETE FROM process_work_item_detail WHERE work_item_id = $1 AND company_code = $2",
      [id, companyCode]
    );

    // 항목 삭제
    const result = await client.query(
      "DELETE FROM process_work_item WHERE id = $1 AND company_code = $2 RETURNING id",
      [id, companyCode]
    );

    if (result.rowCount === 0) {
      await client.query("ROLLBACK");
      return res.status(404).json({ success: false, message: "항목을 찾을 수 없습니다" });
    }

    await client.query("COMMIT");
    logger.info("작업 항목 삭제", { companyCode, id });
    return res.json({ success: true });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("작업 항목 삭제 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

// ============================================================
// 작업 항목 상세 CRUD
// ============================================================

/**
 * 작업 항목 상세 목록 조회
 */
export async function getWorkItemDetails(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { workItemId } = req.params;

    const query = `
      SELECT id, work_item_id, detail_type, content, is_required, sort_order, remark,
             inspection_code, inspection_method, unit, lower_limit, upper_limit,
             duration_minutes, input_type, lookup_target, display_fields,
             created_date
      FROM process_work_item_detail
      WHERE work_item_id = $1 AND company_code = $2
      ORDER BY sort_order, created_date
    `;

    const result = await getPool().query(query, [workItemId, companyCode]);
    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.message });
  }
}

/**
 * 작업 항목 상세 추가
 */
export async function createWorkItemDetail(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    const writer = req.user?.userId;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const {
      work_item_id, detail_type, content, is_required, sort_order, remark,
      inspection_code, inspection_method, unit, lower_limit, upper_limit,
      duration_minutes, input_type, lookup_target, display_fields,
    } = req.body;

    if (!work_item_id || !content) {
      return res.status(400).json({
        success: false,
        message: "work_item_id, content는 필수입니다",
      });
    }

    // work_item이 같은 company_code인지 검증
    const ownerCheck = await getPool().query(
      "SELECT id FROM process_work_item WHERE id = $1 AND company_code = $2",
      [work_item_id, companyCode]
    );
    if (ownerCheck.rowCount === 0) {
      return res.status(403).json({ success: false, message: "권한이 없습니다" });
    }

    const query = `
      INSERT INTO process_work_item_detail
        (company_code, work_item_id, detail_type, content, is_required, sort_order, remark, writer,
         inspection_code, inspection_method, unit, lower_limit, upper_limit,
         duration_minutes, input_type, lookup_target, display_fields)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
      RETURNING *
    `;

    const result = await getPool().query(query, [
      companyCode,
      work_item_id,
      detail_type || null,
      content,
      is_required || "N",
      sort_order || 0,
      remark || null,
      writer,
      inspection_code || null,
      inspection_method || null,
      unit || null,
      lower_limit || null,
      upper_limit || null,
      duration_minutes || null,
      input_type || null,
      lookup_target || null,
      display_fields || null,
    ]);

    logger.info("작업 항목 상세 생성", { companyCode, id: result.rows[0].id });
    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.message });
  }
}

/**
 * 작업 항목 상세 수정
 */
export async function updateWorkItemDetail(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { id } = req.params;
    const {
      detail_type, content, is_required, sort_order, remark,
      inspection_code, inspection_method, unit, lower_limit, upper_limit,
      duration_minutes, input_type, lookup_target, display_fields,
    } = req.body;

    const query = `
      UPDATE process_work_item_detail
      SET detail_type = COALESCE($1, detail_type),
          content = COALESCE($2, content),
          is_required = COALESCE($3, is_required),
          sort_order = COALESCE($4, sort_order),
          remark = COALESCE($5, remark),
          inspection_code = $8,
          inspection_method = $9,
          unit = $10,
          lower_limit = $11,
          upper_limit = $12,
          duration_minutes = $13,
          input_type = $14,
          lookup_target = $15,
          display_fields = $16,
          updated_date = NOW()
      WHERE id = $6 AND company_code = $7
      RETURNING *
    `;

    const result = await getPool().query(query, [
      detail_type,
      content,
      is_required,
      sort_order,
      remark,
      id,
      companyCode,
      inspection_code || null,
      inspection_method || null,
      unit || null,
      lower_limit || null,
      upper_limit || null,
      duration_minutes || null,
      input_type || null,
      lookup_target || null,
      display_fields || null,
    ]);

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

    logger.info("작업 항목 상세 수정", { companyCode, id });
    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.message });
  }
}

/**
 * 작업 항목 상세 삭제
 */
export async function deleteWorkItemDetail(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { id } = req.params;

    const result = await getPool().query(
      "DELETE FROM process_work_item_detail WHERE id = $1 AND company_code = $2 RETURNING id",
      [id, companyCode]
    );

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

    logger.info("작업 항목 상세 삭제", { companyCode, id });
    return res.json({ success: true });
  } catch (error: any) {
    logger.error("작업 항목 상세 삭제 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================================
// 전체 저장 (일괄)
// ============================================================

/**
 * 전체 저장: 작업 항목 + 상세를 일괄 저장
 * 기존 데이터를 삭제하고 새로 삽입하는 replace 방식
 */
export async function saveAll(req: AuthenticatedRequest, res: Response) {
  const client = await getPool().connect();
  try {
    const companyCode = req.user?.companyCode;
    const writer = req.user?.userId;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { routing_detail_id, items } = req.body;

    if (!routing_detail_id || !Array.isArray(items)) {
      return res.status(400).json({
        success: false,
        message: "routing_detail_id와 items 배열이 필요합니다",
      });
    }

    await client.query("BEGIN");

    // 기존 상세 삭제
    await client.query(
      `DELETE FROM process_work_item_detail
       WHERE work_item_id IN (
         SELECT id FROM process_work_item
         WHERE routing_detail_id = $1 AND company_code = $2
       )`,
      [routing_detail_id, companyCode]
    );

    // 기존 항목 삭제
    await client.query(
      "DELETE FROM process_work_item WHERE routing_detail_id = $1 AND company_code = $2",
      [routing_detail_id, companyCode]
    );

    // 새 항목 + 상세 삽입
    for (const item of items) {
      const itemResult = await client.query(
        `INSERT INTO process_work_item
          (company_code, routing_detail_id, work_phase, title, is_required, sort_order, description, writer)
         VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
         RETURNING id`,
        [
          companyCode,
          routing_detail_id,
          item.work_phase,
          item.title,
          item.is_required || "N",
          item.sort_order || 0,
          item.description || null,
          writer,
        ]
      );

      const workItemId = itemResult.rows[0].id;

      if (Array.isArray(item.details)) {
        for (const detail of item.details) {
          await client.query(
            `INSERT INTO process_work_item_detail
              (company_code, work_item_id, detail_type, content, is_required, sort_order, remark, writer,
               inspection_code, inspection_method, unit, lower_limit, upper_limit,
               duration_minutes, input_type, lookup_target, display_fields)
             VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)`,
            [
              companyCode,
              workItemId,
              detail.detail_type || null,
              detail.content,
              detail.is_required || "N",
              detail.sort_order || 0,
              detail.remark || null,
              writer,
              detail.inspection_code || null,
              detail.inspection_method || null,
              detail.unit || null,
              detail.lower_limit || null,
              detail.upper_limit || null,
              detail.duration_minutes || null,
              detail.input_type || null,
              detail.lookup_target || null,
              detail.display_fields || null,
            ]
          );
        }
      }
    }

    await client.query("COMMIT");
    logger.info("작업기준 전체 저장", { companyCode, routing_detail_id, itemCount: items.length });
    return res.json({ success: true, message: "저장 완료" });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("작업기준 전체 저장 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

// ============================================================
// 등록 품목 관리 (item_routing_registered)
// ============================================================

/**
 * 화면별 등록된 품목 목록 조회
 */
export async function getRegisteredItems(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { screenCode } = req.params;
    const {
      tableName = "item_info",
      nameColumn = "item_name",
      codeColumn = "item_number",
      routingTable = "item_routing_version",
      routingFkColumn = "item_code",
      search = "",
      extraColumns = "",
    } = req.query as Record<string, string>;

    const params: any[] = [companyCode, screenCode];
    let paramIndex = 3;

    let searchCondition = "";
    if (search) {
      searchCondition = `AND (i.${nameColumn} ILIKE $${paramIndex} OR i.${codeColumn} ILIKE $${paramIndex})`;
      params.push(`%${search}%`);
      paramIndex++;
    }

    const extraColumnNames: string[] = extraColumns
      ? extraColumns.split(",").map((c: string) => c.trim()).filter(Boolean)
      : [];
    const extraSelect = extraColumnNames.map((col) => `i.${col}`).join(", ");
    const extraGroupBy = extraColumnNames.map((col) => `i.${col}`).join(", ");

    const query = `
      SELECT
        irr.id AS registered_id,
        irr.sort_order,
        i.id,
        i.${nameColumn} AS item_name,
        i.${codeColumn} AS item_code
        ${extraSelect ? ", " + extraSelect : ""},
        COUNT(rv.id) AS routing_count
      FROM item_routing_registered irr
      JOIN ${tableName} i ON irr.item_id = i.id
        AND i.company_code = irr.company_code
      LEFT JOIN ${routingTable} rv ON rv.${routingFkColumn} = i.${codeColumn}
        AND rv.company_code = i.company_code
      WHERE irr.company_code = $1
        AND irr.screen_code = $2
        ${searchCondition}
      GROUP BY irr.id, irr.sort_order, i.id, i.${nameColumn}, i.${codeColumn}${extraGroupBy ? ", " + extraGroupBy : ""}
      ORDER BY CAST(irr.sort_order AS int) ASC, irr.created_date ASC
    `;

    const result = await getPool().query(query, params);
    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.message });
  }
}

/**
 * 품목 등록 (화면에 품목 추가)
 */
export async function registerItem(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { screenCode, itemId, itemCode } = req.body;
    if (!screenCode || !itemId) {
      return res.status(400).json({ success: false, message: "screenCode, itemId 필수" });
    }

    const query = `
      INSERT INTO item_routing_registered (screen_code, item_id, item_code, company_code, writer)
      VALUES ($1, $2, $3, $4, $5)
      ON CONFLICT (screen_code, item_id, company_code) DO NOTHING
      RETURNING *
    `;
    const result = await getPool().query(query, [
      screenCode, itemId, itemCode || null, companyCode, req.user?.userId || null,
    ]);

    if (result.rowCount === 0) {
      return res.json({ success: true, message: "이미 등록된 품목입니다", data: null });
    }

    logger.info("품목 등록", { companyCode, screenCode, itemId });
    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.message });
  }
}

/**
 * 여러 품목 일괄 등록
 */
export async function registerItemsBatch(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { screenCode, items } = req.body;
    if (!screenCode || !Array.isArray(items) || items.length === 0) {
      return res.status(400).json({ success: false, message: "screenCode, items[] 필수" });
    }

    const client = await getPool().connect();
    try {
      await client.query("BEGIN");
      const inserted: any[] = [];

      for (const item of items) {
        const result = await client.query(
          `INSERT INTO item_routing_registered (screen_code, item_id, item_code, company_code, writer)
           VALUES ($1, $2, $3, $4, $5)
           ON CONFLICT (screen_code, item_id, company_code) DO NOTHING
           RETURNING *`,
          [screenCode, item.itemId, item.itemCode || null, companyCode, req.user?.userId || null]
        );
        if (result.rows[0]) inserted.push(result.rows[0]);
      }

      await client.query("COMMIT");
      logger.info("품목 일괄 등록", { companyCode, screenCode, count: inserted.length });
      return res.json({ success: true, data: inserted });
    } catch (err) {
      await client.query("ROLLBACK");
      throw err;
    } finally {
      client.release();
    }
  } catch (error: any) {
    logger.error("품목 일괄 등록 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

/**
 * 등록 품목 제거
 */
export async function unregisterItem(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user?.companyCode;
    if (!companyCode) {
      return res.status(401).json({ success: false, message: "인증 필요" });
    }

    const { id } = req.params;
    const result = await getPool().query(
      `DELETE FROM item_routing_registered WHERE id = $1 AND company_code = $2 RETURNING id`,
      [id, companyCode]
    );

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

    logger.info("등록 품목 제거", { companyCode, id });
    return res.json({ success: true });
  } catch (error: any) {
    logger.error("등록 품목 제거 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}
