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

// 회사코드 필터 조건 생성 헬퍼
function companyFilter(companyCode: string, paramIndex: number, alias?: string): { condition: string; param: string; nextIndex: number } {
  const col = alias ? `${alias}.company_code` : "company_code";
  if (companyCode === "*") {
    return { condition: "", param: "", nextIndex: paramIndex };
  }
  return { condition: `${col} = $${paramIndex}`, param: companyCode, nextIndex: paramIndex + 1 };
}

// ============================================
// 설계의뢰/설변요청 (DR/ECR) CRUD
// ============================================

export async function getDesignRequestList(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { source_type, status, priority, search } = req.query;

    const conditions: string[] = [];
    const params: any[] = [];
    let pi = 1;

    if (companyCode !== "*") {
      conditions.push(`r.company_code = $${pi}`);
      params.push(companyCode);
      pi++;
    }
    if (source_type) { conditions.push(`r.source_type = $${pi}`); params.push(source_type); pi++; }
    if (status) { conditions.push(`r.status = $${pi}`); params.push(status); pi++; }
    if (priority) { conditions.push(`r.priority = $${pi}`); params.push(priority); pi++; }
    if (search) {
      conditions.push(`(r.target_name ILIKE $${pi} OR r.request_no ILIKE $${pi} OR r.requester ILIKE $${pi})`);
      params.push(`%${search}%`);
      pi++;
    }

    const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
    const sql = `
      SELECT r.*,
        COALESCE(json_agg(json_build_object('id', h.id, 'step', h.step, 'history_date', h.history_date, 'user_name', h.user_name, 'description', h.description)) FILTER (WHERE h.id IS NOT NULL), '[]') AS history,
        COALESCE((SELECT json_agg(i.impact_type) FROM dsn_request_impact i WHERE i.request_id = r.id), '[]') AS impact
      FROM dsn_design_request r
      LEFT JOIN dsn_request_history h ON h.request_id = r.id
      ${where}
      GROUP BY r.id
      ORDER BY r.created_date DESC
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("설계의뢰 목록 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function getDesignRequestDetail(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;

    const conditions = [`r.id = $1`];
    const params: any[] = [id];
    if (companyCode !== "*") { conditions.push(`r.company_code = $2`); params.push(companyCode); }

    const sql = `
      SELECT r.*,
        COALESCE((SELECT json_agg(json_build_object('id', h.id, 'step', h.step, 'history_date', h.history_date, 'user_name', h.user_name, 'description', h.description) ORDER BY h.created_date) FROM dsn_request_history h WHERE h.request_id = r.id), '[]') AS history,
        COALESCE((SELECT json_agg(i.impact_type) FROM dsn_request_impact i WHERE i.request_id = r.id), '[]') AS impact
      FROM dsn_design_request r
      WHERE ${conditions.join(" AND ")}
    `;
    const result = await query(sql, params);
    if (!result.length) { res.status(404).json({ success: false, message: "의뢰를 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("설계의뢰 상세 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createDesignRequest(req: AuthenticatedRequest, res: Response): Promise<void> {
  const pool = getPool();
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const {
      request_no, source_type, request_date, due_date, priority, status,
      target_name, customer, req_dept, requester, designer, order_no,
      design_type, spec, change_type, drawing_no, urgency, reason,
      content, apply_timing, review_memo, project_id, ecn_no,
      impact, history,
    } = req.body;

    const sql = `
      INSERT INTO dsn_design_request (
        request_no, source_type, request_date, due_date, priority, status,
        target_name, customer, req_dept, requester, designer, order_no,
        design_type, spec, change_type, drawing_no, urgency, reason,
        content, apply_timing, review_memo, project_id, ecn_no,
        writer, company_code
      ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25)
      RETURNING *
    `;
    const result = await client.query(sql, [
      request_no, source_type || "dr", request_date, due_date, priority || "보통", status || "신규접수",
      target_name, customer, req_dept, requester, designer, order_no,
      design_type, spec, change_type, drawing_no, urgency || "보통", reason,
      content, apply_timing, review_memo, project_id, ecn_no,
      userId, companyCode,
    ]);

    const requestId = result.rows[0].id;

    if (impact?.length) {
      for (const imp of impact) {
        await client.query(
          `INSERT INTO dsn_request_impact (request_id, impact_type, writer, company_code) VALUES ($1,$2,$3,$4)`,
          [requestId, imp, userId, companyCode]
        );
      }
    }

    if (history?.length) {
      for (const h of history) {
        await client.query(
          `INSERT INTO dsn_request_history (request_id, step, history_date, user_name, description, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7)`,
          [requestId, h.step, h.history_date, h.user_name, h.description, userId, companyCode]
        );
      }
    }

    await client.query("COMMIT");
    res.json({ success: true, data: result.rows[0] });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("설계의뢰 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

export async function updateDesignRequest(req: AuthenticatedRequest, res: Response): Promise<void> {
  const pool = getPool();
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { id } = req.params;
    const {
      request_no, source_type, request_date, due_date, priority, status, approval_step,
      target_name, customer, req_dept, requester, designer, order_no,
      design_type, spec, change_type, drawing_no, urgency, reason,
      content, apply_timing, review_memo, project_id, ecn_no,
      impact, history,
    } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [id];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const setClauses = [];
    const setParams: any[] = [];
    const fields: Record<string, any> = {
      request_no, source_type, request_date, due_date, priority, status, approval_step,
      target_name, customer, req_dept, requester, designer, order_no,
      design_type, spec, change_type, drawing_no, urgency, reason,
      content, apply_timing, review_memo, project_id, ecn_no,
    };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) {
        setClauses.push(`${key} = $${pi}`);
        setParams.push(val);
        pi++;
      }
    }
    setClauses.push(`updated_date = now()`);

    const sql = `UPDATE dsn_design_request SET ${setClauses.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`;
    const result = await client.query(sql, [...params, ...setParams]);
    if (!result.rowCount) { await client.query("ROLLBACK"); res.status(404).json({ success: false, message: "의뢰를 찾을 수 없습니다." }); return; }

    if (impact !== undefined) {
      await client.query(`DELETE FROM dsn_request_impact WHERE request_id = $1`, [id]);
      for (const imp of impact) {
        await client.query(
          `INSERT INTO dsn_request_impact (request_id, impact_type, writer, company_code) VALUES ($1,$2,$3,$4)`,
          [id, imp, userId, companyCode]
        );
      }
    }

    if (history !== undefined) {
      await client.query(`DELETE FROM dsn_request_history WHERE request_id = $1`, [id]);
      for (const h of history) {
        await client.query(
          `INSERT INTO dsn_request_history (request_id, step, history_date, user_name, description, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7)`,
          [id, h.step, h.history_date, h.user_name, h.description, userId, companyCode]
        );
      }
    }

    await client.query("COMMIT");
    res.json({ success: true, data: result.rows[0] });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("설계의뢰 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

export async function deleteDesignRequest(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;

    const conditions = [`id = $1`];
    const params: any[] = [id];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const sql = `DELETE FROM dsn_design_request WHERE ${conditions.join(" AND ")} RETURNING id`;
    const result = await query(sql, params);
    if (!result.length) { res.status(404).json({ success: false, message: "의뢰를 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("설계의뢰 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// 이력 추가 (단건)
export async function addRequestHistory(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { id } = req.params;
    const { step, history_date, user_name, description } = req.body;

    const sql = `INSERT INTO dsn_request_history (request_id, step, history_date, user_name, description, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`;
    const result = await query(sql, [id, step, history_date, user_name, description, userId, companyCode]);
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("의뢰 이력 추가 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 설계 프로젝트 CRUD
// ============================================

export async function getProjectList(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { status, search } = req.query;

    const conditions: string[] = [];
    const params: any[] = [];
    let pi = 1;

    if (companyCode !== "*") { conditions.push(`p.company_code = $${pi}`); params.push(companyCode); pi++; }
    if (status) { conditions.push(`p.status = $${pi}`); params.push(status); pi++; }
    if (search) {
      conditions.push(`(p.name ILIKE $${pi} OR p.project_no ILIKE $${pi} OR p.customer ILIKE $${pi})`);
      params.push(`%${search}%`);
      pi++;
    }

    const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
    const sql = `
      SELECT p.*,
        COALESCE(
          (SELECT json_agg(json_build_object(
            'id', t.id, 'name', t.name, 'category', t.category, 'assignee', t.assignee,
            'start_date', t.start_date, 'end_date', t.end_date, 'status', t.status,
            'progress', t.progress, 'priority', t.priority, 'remark', t.remark, 'sort_order', t.sort_order
          ) ORDER BY t.sort_order, t.start_date)
          FROM dsn_project_task t WHERE t.project_id = p.id), '[]'
        ) AS tasks
      FROM dsn_project p
      ${where}
      ORDER BY p.created_date DESC
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("프로젝트 목록 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function getProjectDetail(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;

    const conditions = [`p.id = $1`];
    const params: any[] = [id];
    if (companyCode !== "*") { conditions.push(`p.company_code = $2`); params.push(companyCode); }

    const sql = `
      SELECT p.*,
        COALESCE(
          (SELECT json_agg(json_build_object(
            'id', t.id, 'name', t.name, 'category', t.category, 'assignee', t.assignee,
            'start_date', t.start_date, 'end_date', t.end_date, 'status', t.status,
            'progress', t.progress, 'priority', t.priority, 'remark', t.remark, 'sort_order', t.sort_order
          ) ORDER BY t.sort_order, t.start_date)
          FROM dsn_project_task t WHERE t.project_id = p.id), '[]'
        ) AS tasks
      FROM dsn_project p
      WHERE ${conditions.join(" AND ")}
    `;
    const result = await query(sql, params);
    if (!result.length) { res.status(404).json({ success: false, message: "프로젝트를 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("프로젝트 상세 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createProject(req: AuthenticatedRequest, res: Response): Promise<void> {
  const pool = getPool();
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { project_no, name, status: pStatus, pm, customer, start_date, end_date, source_no, description, progress, parent_id, relation_type, tasks } = req.body;

    const result = await client.query(
      `INSERT INTO dsn_project (project_no, name, status, pm, customer, start_date, end_date, source_no, description, progress, parent_id, relation_type, writer, company_code)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14) RETURNING *`,
      [project_no, name, pStatus || "계획", pm, customer, start_date, end_date, source_no, description, progress || "0", parent_id, relation_type, userId, companyCode]
    );

    const projectId = result.rows[0].id;
    if (tasks?.length) {
      for (let i = 0; i < tasks.length; i++) {
        const t = tasks[i];
        await client.query(
          `INSERT INTO dsn_project_task (project_id, name, category, assignee, start_date, end_date, status, progress, priority, remark, sort_order, writer, company_code)
           VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)`,
          [projectId, t.name, t.category, t.assignee, t.start_date, t.end_date, t.status || "대기", t.progress || "0", t.priority || "보통", t.remark, String(i), userId, companyCode]
        );
      }
    }

    await client.query("COMMIT");
    res.json({ success: true, data: result.rows[0] });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("프로젝트 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

export async function updateProject(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;
    const { project_no, name, status: pStatus, pm, customer, start_date, end_date, source_no, description, progress, parent_id, relation_type } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [id];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const sets: string[] = [];
    const fields: Record<string, any> = { project_no, name, status: pStatus, pm, customer, start_date, end_date, source_no, description, progress, parent_id, relation_type };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) { sets.push(`${key} = $${pi}`); params.push(val); pi++; }
    }
    sets.push(`updated_date = now()`);

    const result = await query(`UPDATE dsn_project SET ${sets.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "프로젝트를 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("프로젝트 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function deleteProject(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;
    const conditions = [`id = $1`];
    const params: any[] = [id];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const result = await query(`DELETE FROM dsn_project WHERE ${conditions.join(" AND ")} RETURNING id`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "프로젝트를 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("프로젝트 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 프로젝트 태스크 CRUD
// ============================================

export async function getTasksByProject(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { projectId } = req.params;

    const conditions = [`t.project_id = $1`];
    const params: any[] = [projectId];
    if (companyCode !== "*") { conditions.push(`t.company_code = $2`); params.push(companyCode); }

    const sql = `
      SELECT t.*,
        COALESCE((SELECT json_agg(json_build_object('id', w.id, 'start_dt', w.start_dt, 'end_dt', w.end_dt, 'hours', w.hours, 'description', w.description, 'progress_before', w.progress_before, 'progress_after', w.progress_after, 'author', w.author, 'sub_item_id', w.sub_item_id) ORDER BY w.start_dt) FROM dsn_work_log w WHERE w.task_id = t.id), '[]') AS work_logs,
        COALESCE((SELECT json_agg(json_build_object('id', i.id, 'title', i.title, 'status', i.status, 'priority', i.priority, 'description', i.description, 'registered_by', i.registered_by, 'registered_date', i.registered_date, 'resolved_date', i.resolved_date)) FROM dsn_task_issue i WHERE i.task_id = t.id), '[]') AS issues,
        COALESCE((SELECT json_agg(json_build_object('id', s.id, 'name', s.name, 'weight', s.weight, 'progress', s.progress, 'status', s.status) ORDER BY s.created_date) FROM dsn_task_sub_item s WHERE s.task_id = t.id), '[]') AS sub_items
      FROM dsn_project_task t
      WHERE ${conditions.join(" AND ")}
      ORDER BY t.sort_order, t.start_date
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("태스크 목록 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createTask(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { projectId } = req.params;
    const { name, category, assignee, start_date, end_date, status, progress, priority, remark, sort_order } = req.body;

    const result = await query(
      `INSERT INTO dsn_project_task (project_id, name, category, assignee, start_date, end_date, status, progress, priority, remark, sort_order, writer, company_code)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13) RETURNING *`,
      [projectId, name, category, assignee, start_date, end_date, status || "대기", progress || "0", priority || "보통", remark, sort_order || "0", userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("태스크 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function updateTask(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { taskId } = req.params;
    const { name, category, assignee, start_date, end_date, status, progress, priority, remark, sort_order } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [taskId];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const sets: string[] = [];
    const fields: Record<string, any> = { name, category, assignee, start_date, end_date, status, progress, priority, remark, sort_order };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) { sets.push(`${key} = $${pi}`); params.push(val); pi++; }
    }
    sets.push(`updated_date = now()`);

    const result = await query(`UPDATE dsn_project_task SET ${sets.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "태스크를 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("태스크 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function deleteTask(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { taskId } = req.params;
    const conditions = [`id = $1`];
    const params: any[] = [taskId];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const result = await query(`DELETE FROM dsn_project_task WHERE ${conditions.join(" AND ")} RETURNING id`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "태스크를 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("태스크 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 작업일지 CRUD
// ============================================

export async function getWorkLogsByTask(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { taskId } = req.params;

    const conditions = [`w.task_id = $1`];
    const params: any[] = [taskId];
    if (companyCode !== "*") { conditions.push(`w.company_code = $2`); params.push(companyCode); }

    const sql = `
      SELECT w.*,
        COALESCE((SELECT json_agg(json_build_object('id', a.id, 'file_name', a.file_name, 'file_type', a.file_type, 'file_size', a.file_size)) FROM dsn_work_attachment a WHERE a.work_log_id = w.id), '[]') AS attachments,
        COALESCE((SELECT json_agg(json_build_object('id', p.id, 'item', p.item, 'qty', p.qty, 'unit', p.unit, 'reason', p.reason, 'status', p.status)) FROM dsn_purchase_req p WHERE p.work_log_id = w.id), '[]') AS purchase_reqs,
        COALESCE((SELECT json_agg(json_build_object(
          'id', c.id, 'to_user', c.to_user, 'to_dept', c.to_dept, 'title', c.title, 'description', c.description, 'status', c.status, 'due_date', c.due_date,
          'responses', COALESCE((SELECT json_agg(json_build_object('id', cr.id, 'response_date', cr.response_date, 'user_name', cr.user_name, 'content', cr.content)) FROM dsn_coop_response cr WHERE cr.coop_req_id = c.id), '[]')
        )) FROM dsn_coop_req c WHERE c.work_log_id = w.id), '[]') AS coop_reqs
      FROM dsn_work_log w
      WHERE ${conditions.join(" AND ")}
      ORDER BY w.start_dt DESC
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("작업일지 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createWorkLog(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { taskId } = req.params;
    const { start_dt, end_dt, hours, description, progress_before, progress_after, author, sub_item_id } = req.body;

    const result = await query(
      `INSERT INTO dsn_work_log (task_id, start_dt, end_dt, hours, description, progress_before, progress_after, author, sub_item_id, writer, company_code)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING *`,
      [taskId, start_dt, end_dt, hours || "0", description, progress_before || "0", progress_after || "0", author, sub_item_id, userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("작업일지 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function deleteWorkLog(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { workLogId } = req.params;
    const conditions = [`id = $1`];
    const params: any[] = [workLogId];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const result = await query(`DELETE FROM dsn_work_log WHERE ${conditions.join(" AND ")} RETURNING id`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "작업일지를 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("작업일지 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 태스크 하위항목 CRUD
// ============================================

export async function createSubItem(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { taskId } = req.params;
    const { name, weight, progress, status } = req.body;

    const result = await query(
      `INSERT INTO dsn_task_sub_item (task_id, name, weight, progress, status, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING *`,
      [taskId, name, weight || "0", progress || "0", status || "대기", userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("하위항목 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function updateSubItem(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { subItemId } = req.params;
    const { name, weight, progress, status } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [subItemId];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const sets: string[] = [];
    const fields: Record<string, any> = { name, weight, progress, status };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) { sets.push(`${key} = $${pi}`); params.push(val); pi++; }
    }
    sets.push(`updated_date = now()`);

    const result = await query(`UPDATE dsn_task_sub_item SET ${sets.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "하위항목을 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("하위항목 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function deleteSubItem(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { subItemId } = req.params;
    const conditions = [`id = $1`];
    const params: any[] = [subItemId];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const result = await query(`DELETE FROM dsn_task_sub_item WHERE ${conditions.join(" AND ")} RETURNING id`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "하위항목을 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("하위항목 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 태스크 이슈 CRUD
// ============================================

export async function createIssue(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { taskId } = req.params;
    const { title, status, priority, description, registered_by, registered_date } = req.body;

    const result = await query(
      `INSERT INTO dsn_task_issue (task_id, title, status, priority, description, registered_by, registered_date, writer, company_code)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING *`,
      [taskId, title, status || "등록", priority || "보통", description, registered_by, registered_date, userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("이슈 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function updateIssue(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { issueId } = req.params;
    const { title, status, priority, description, resolved_date } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [issueId];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const sets: string[] = [];
    const fields: Record<string, any> = { title, status, priority, description, resolved_date };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) { sets.push(`${key} = $${pi}`); params.push(val); pi++; }
    }
    sets.push(`updated_date = now()`);

    const result = await query(`UPDATE dsn_task_issue SET ${sets.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "이슈를 찾을 수 없습니다." }); return; }
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("이슈 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// ECN (설변통보) CRUD
// ============================================

export async function getEcnList(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { status, search } = req.query;

    const conditions: string[] = [];
    const params: any[] = [];
    let pi = 1;

    if (companyCode !== "*") { conditions.push(`e.company_code = $${pi}`); params.push(companyCode); pi++; }
    if (status) { conditions.push(`e.status = $${pi}`); params.push(status); pi++; }
    if (search) {
      conditions.push(`(e.ecn_no ILIKE $${pi} OR e.target ILIKE $${pi})`);
      params.push(`%${search}%`);
      pi++;
    }

    const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
    const sql = `
      SELECT e.*,
        COALESCE((SELECT json_agg(json_build_object('id', h.id, 'status', h.status, 'history_date', h.history_date, 'user_name', h.user_name, 'description', h.description) ORDER BY h.created_date) FROM dsn_ecn_history h WHERE h.ecn_id = e.id), '[]') AS history,
        COALESCE((SELECT json_agg(nd.dept_name) FROM dsn_ecn_notify_dept nd WHERE nd.ecn_id = e.id), '[]') AS notify_depts
      FROM dsn_ecn e
      ${where}
      ORDER BY e.created_date DESC
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("ECN 목록 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createEcn(req: AuthenticatedRequest, res: Response): Promise<void> {
  const pool = getPool();
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { ecn_no, ecr_id, ecn_date, apply_date, status, target, drawing_before, drawing_after, designer, before_content, after_content, reason, remark, notify_depts, history } = req.body;

    const result = await client.query(
      `INSERT INTO dsn_ecn (ecn_no, ecr_id, ecn_date, apply_date, status, target, drawing_before, drawing_after, designer, before_content, after_content, reason, remark, writer, company_code)
       VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING *`,
      [ecn_no, ecr_id, ecn_date, apply_date, status || "ECN발행", target, drawing_before, drawing_after, designer, before_content, after_content, reason, remark, userId, companyCode]
    );

    const ecnId = result.rows[0].id;

    if (notify_depts?.length) {
      for (const dept of notify_depts) {
        await client.query(`INSERT INTO dsn_ecn_notify_dept (ecn_id, dept_name, writer, company_code) VALUES ($1,$2,$3,$4)`, [ecnId, dept, userId, companyCode]);
      }
    }

    if (history?.length) {
      for (const h of history) {
        await client.query(
          `INSERT INTO dsn_ecn_history (ecn_id, status, history_date, user_name, description, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7)`,
          [ecnId, h.status, h.history_date, h.user_name, h.description, userId, companyCode]
        );
      }
    }

    await client.query("COMMIT");
    res.json({ success: true, data: result.rows[0] });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("ECN 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

export async function updateEcn(req: AuthenticatedRequest, res: Response): Promise<void> {
  const pool = getPool();
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { id } = req.params;
    const { ecn_no, ecn_date, apply_date, status, target, drawing_before, drawing_after, designer, before_content, after_content, reason, remark, notify_depts, history } = req.body;

    const conditions = [`id = $1`];
    const params: any[] = [id];
    let pi = 2;
    if (companyCode !== "*") { conditions.push(`company_code = $${pi}`); params.push(companyCode); pi++; }

    const sets: string[] = [];
    const fields: Record<string, any> = { ecn_no, ecn_date, apply_date, status, target, drawing_before, drawing_after, designer, before_content, after_content, reason, remark };
    for (const [key, val] of Object.entries(fields)) {
      if (val !== undefined) { sets.push(`${key} = $${pi}`); params.push(val); pi++; }
    }
    sets.push(`updated_date = now()`);

    const result = await client.query(`UPDATE dsn_ecn SET ${sets.join(", ")} WHERE ${conditions.join(" AND ")} RETURNING *`, params);
    if (!result.rowCount) { await client.query("ROLLBACK"); res.status(404).json({ success: false, message: "ECN을 찾을 수 없습니다." }); return; }

    if (notify_depts !== undefined) {
      await client.query(`DELETE FROM dsn_ecn_notify_dept WHERE ecn_id = $1`, [id]);
      for (const dept of notify_depts) {
        await client.query(`INSERT INTO dsn_ecn_notify_dept (ecn_id, dept_name, writer, company_code) VALUES ($1,$2,$3,$4)`, [id, dept, userId, companyCode]);
      }
    }
    if (history !== undefined) {
      await client.query(`DELETE FROM dsn_ecn_history WHERE ecn_id = $1`, [id]);
      for (const h of history) {
        await client.query(
          `INSERT INTO dsn_ecn_history (ecn_id, status, history_date, user_name, description, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7)`,
          [id, h.status, h.history_date, h.user_name, h.description, userId, companyCode]
        );
      }
    }

    await client.query("COMMIT");
    res.json({ success: true, data: result.rows[0] });
  } catch (error: any) {
    await client.query("ROLLBACK");
    logger.error("ECN 수정 오류", error);
    res.status(500).json({ success: false, message: error.message });
  } finally {
    client.release();
  }
}

export async function deleteEcn(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const { id } = req.params;
    const conditions = [`id = $1`];
    const params: any[] = [id];
    if (companyCode !== "*") { conditions.push(`company_code = $2`); params.push(companyCode); }

    const result = await query(`DELETE FROM dsn_ecn WHERE ${conditions.join(" AND ")} RETURNING id`, params);
    if (!result.length) { res.status(404).json({ success: false, message: "ECN을 찾을 수 없습니다." }); return; }
    res.json({ success: true });
  } catch (error: any) {
    logger.error("ECN 삭제 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 나의 업무 (My Work) - 로그인 사용자 기준
// ============================================

export async function getMyWork(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userName = req.user!.userName;
    const { status, project_id } = req.query;

    const conditions = [`t.assignee = $1`];
    const params: any[] = [userName];
    let pi = 2;

    if (companyCode !== "*") { conditions.push(`t.company_code = $${pi}`); params.push(companyCode); pi++; }
    if (status) { conditions.push(`t.status = $${pi}`); params.push(status); pi++; }
    if (project_id) { conditions.push(`t.project_id = $${pi}`); params.push(project_id); pi++; }

    const sql = `
      SELECT t.*,
        p.project_no, p.name AS project_name, p.customer AS project_customer, p.status AS project_status,
        COALESCE((SELECT json_agg(json_build_object('id', s.id, 'name', s.name, 'weight', s.weight, 'progress', s.progress, 'status', s.status) ORDER BY s.created_date) FROM dsn_task_sub_item s WHERE s.task_id = t.id), '[]') AS sub_items,
        COALESCE((SELECT json_agg(json_build_object(
          'id', w.id, 'start_dt', w.start_dt, 'end_dt', w.end_dt, 'hours', w.hours, 'description', w.description, 'sub_item_id', w.sub_item_id,
          'attachments', COALESCE((SELECT json_agg(json_build_object('id', a.id, 'file_name', a.file_name, 'file_type', a.file_type, 'file_size', a.file_size)) FROM dsn_work_attachment a WHERE a.work_log_id = w.id), '[]'),
          'purchase_reqs', COALESCE((SELECT json_agg(json_build_object('id', pr.id, 'item', pr.item, 'qty', pr.qty, 'unit', pr.unit, 'reason', pr.reason, 'status', pr.status)) FROM dsn_purchase_req pr WHERE pr.work_log_id = w.id), '[]'),
          'coop_reqs', COALESCE((SELECT json_agg(json_build_object(
            'id', c.id, 'to_user', c.to_user, 'to_dept', c.to_dept, 'title', c.title, 'description', c.description, 'status', c.status, 'due_date', c.due_date,
            'responses', COALESCE((SELECT json_agg(json_build_object('id', cr.id, 'response_date', cr.response_date, 'user_name', cr.user_name, 'content', cr.content)) FROM dsn_coop_response cr WHERE cr.coop_req_id = c.id), '[]')
          )) FROM dsn_coop_req c WHERE c.work_log_id = w.id), '[]')
        ) ORDER BY w.start_dt DESC) FROM dsn_work_log w WHERE w.task_id = t.id), '[]') AS work_logs
      FROM dsn_project_task t
      JOIN dsn_project p ON p.id = t.project_id
      WHERE ${conditions.join(" AND ")}
      ORDER BY
        CASE t.status WHEN '진행중' THEN 1 WHEN '대기' THEN 2 WHEN '검토중' THEN 3 ELSE 4 END,
        t.end_date ASC
    `;
    const result = await query(sql, params);
    res.json({ success: true, data: result });
  } catch (error: any) {
    logger.error("나의 업무 조회 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

// ============================================
// 구매요청 / 협업요청 CRUD (my-work에서 사용)
// ============================================

export async function createPurchaseReq(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { workLogId } = req.params;
    const { item, qty, unit, reason, status } = req.body;

    const result = await query(
      `INSERT INTO dsn_purchase_req (work_log_id, item, qty, unit, reason, status, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING *`,
      [workLogId, item, qty, unit, reason, status || "요청", userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("구매요청 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function createCoopReq(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { workLogId } = req.params;
    const { to_user, to_dept, title, description, due_date } = req.body;

    const result = await query(
      `INSERT INTO dsn_coop_req (work_log_id, to_user, to_dept, title, description, status, due_date, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING *`,
      [workLogId, to_user, to_dept, title, description, "요청", due_date, userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("협업요청 생성 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}

export async function addCoopResponse(req: AuthenticatedRequest, res: Response): Promise<void> {
  try {
    const companyCode = req.user!.companyCode!;
    const userId = req.user!.userId;
    const { coopReqId } = req.params;
    const { response_date, user_name, content } = req.body;

    const result = await query(
      `INSERT INTO dsn_coop_response (coop_req_id, response_date, user_name, content, writer, company_code) VALUES ($1,$2,$3,$4,$5,$6) RETURNING *`,
      [coopReqId, response_date, user_name, content, userId, companyCode]
    );
    res.json({ success: true, data: result[0] });
  } catch (error: any) {
    logger.error("협업응답 추가 오류", error);
    res.status(500).json({ success: false, message: error.message });
  }
}
