/**
 * 품목검사정보 컨트롤러
 * - item_code 단위로 GROUP BY 한 후 페이징하여 좌측 품목 패널 데이터 제공
 */

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

interface InspectionRow {
  id: string;
  item_code: string;
  item_name: string;
  inspection_type: string | null;
  inspection_standard: string | null;
  inspection_standard_id: string | null;
  inspection_item_name: string | null;
  inspection_method: string | null;
  apply_process: string | null;
  classification: string | null;
  pass_criteria: string | null;
  is_required: string | null;
  is_active: string | null;
  manager_id: string | null;
  memo: string | null;
  sort_order: string | null;
  change_record: string | null;
  created_date: string | null;
  updated_date: string | null;
}

export async function getGroupedList(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const search = (req.query.search as string | undefined)?.trim() || "";
    const page = Math.max(1, parseInt(String(req.query.page ?? "1"), 10) || 1);
    const size = Math.max(1, Math.min(200, parseInt(String(req.query.size ?? "20"), 10) || 20));

    const pool = getPool();
    const searchPattern = search ? `%${search}%` : null;

    // 1) total: DISTINCT item_code 수
    const countQuery = `
      SELECT COUNT(*)::int AS total FROM (
        SELECT item_code
        FROM item_inspection_info
        WHERE company_code = $1
          AND ($2::text IS NULL OR item_code ILIKE $2 OR item_name ILIKE $2)
        GROUP BY item_code
      ) g;
    `;
    const countRes = await pool.query(countQuery, [companyCode, searchPattern]);
    const total: number = countRes.rows[0]?.total ?? 0;

    if (total === 0) {
      return res.json({
        success: true,
        groups: [],
        total: 0,
        page,
        size,
        totalPages: 1,
      });
    }

    // 2) 현재 페이지의 item_code 목록 (그룹 메타 포함)
    const offset = (page - 1) * size;
    const groupQuery = `
      SELECT
        item_code,
        MIN(item_name) AS item_name,
        MIN(is_active) AS is_active
      FROM item_inspection_info
      WHERE company_code = $1
        AND ($2::text IS NULL OR item_code ILIKE $2 OR item_name ILIKE $2)
      GROUP BY item_code
      ORDER BY MIN(item_name) ASC NULLS LAST, item_code ASC
      LIMIT $3 OFFSET $4;
    `;
    const groupRes = await pool.query(groupQuery, [companyCode, searchPattern, size, offset]);
    const pageItems: { item_code: string; item_name: string | null; is_active: string | null }[] = groupRes.rows;
    const itemCodes = pageItems.map((r) => r.item_code).filter(Boolean);

    if (itemCodes.length === 0) {
      return res.json({
        success: true,
        groups: [],
        total,
        page,
        size,
        totalPages: Math.max(1, Math.ceil(total / size)),
      });
    }

    // 3) 페이지 item_code들의 모든 검사항목 row
    const detailQuery = `
      SELECT
        id, item_code, item_name, inspection_type, inspection_standard, inspection_standard_id,
        inspection_item_name, inspection_method, apply_process, classification,
        pass_criteria, is_required, is_active, manager_id, memo,
        sort_order, change_record, created_date, updated_date
      FROM item_inspection_info
      WHERE company_code = $1
        AND item_code = ANY($2::text[])
      ORDER BY item_code, sort_order, created_date;
    `;
    const detailRes = await pool.query(detailQuery, [companyCode, itemCodes]);
    const rowsByItem: Record<string, InspectionRow[]> = {};
    for (const row of detailRes.rows as InspectionRow[]) {
      const key = row.item_code || "";
      if (!rowsByItem[key]) rowsByItem[key] = [];
      rowsByItem[key].push(row);
    }

    const groups = pageItems.map((g) => ({
      item_code: g.item_code,
      item_name: g.item_name || "",
      is_active: g.is_active || "",
      rows: rowsByItem[g.item_code] || [],
    }));

    logger.info("품목검사정보 그룹 페이징 조회", {
      companyCode,
      page,
      size,
      total,
      groupCount: groups.length,
    });

    return res.json({
      success: true,
      groups,
      total,
      page,
      size,
      totalPages: Math.max(1, Math.ceil(total / size)),
    });
  } catch (error: any) {
    logger.error("품목검사정보 그룹 페이징 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}
