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

export class WebTypeStandardController {
  // 웹타입 목록 조회
  static async getWebTypes(req: Request, res: Response) {
    try {
      const { active, category, search } = req.query;

      // 동적 WHERE 절 생성
      const whereConditions: string[] = [];
      const queryParams: any[] = [];
      let paramIndex = 1;

      if (active) {
        whereConditions.push(`is_active = $${paramIndex}`);
        queryParams.push(active);
        paramIndex++;
      }

      if (category) {
        whereConditions.push(`category = $${paramIndex}`);
        queryParams.push(category);
        paramIndex++;
      }

      if (search && typeof search === "string") {
        whereConditions.push(`(
          type_name ILIKE $${paramIndex} OR
          type_name_eng ILIKE $${paramIndex} OR
          description ILIKE $${paramIndex}
        )`);
        queryParams.push(`%${search}%`);
        paramIndex++;
      }

      const whereClause =
        whereConditions.length > 0
          ? `WHERE ${whereConditions.join(" AND ")}`
          : "";

      const webTypes = await query<any>(
        `SELECT * FROM web_type_standards
         ${whereClause}
         ORDER BY sort_order ASC, web_type ASC`,
        queryParams
      );

      return res.json({
        success: true,
        data: webTypes,
        message: "웹타입 목록을 성공적으로 조회했습니다.",
      });
    } catch (error) {
      console.error("웹타입 목록 조회 오류:", error);
      return res.status(500).json({
        success: false,
        message: "웹타입 목록 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 상세 조회
  static async getWebType(req: Request, res: Response) {
    try {
      const { webType } = req.params;

      const webTypeData = await queryOne<any>(
        `SELECT * FROM web_type_standards WHERE web_type = $1`,
        [webType]
      );

      if (!webTypeData) {
        return res.status(404).json({
          success: false,
          message: "해당 웹타입을 찾을 수 없습니다.",
        });
      }

      return res.json({
        success: true,
        data: webTypeData,
        message: "웹타입 정보를 성공적으로 조회했습니다.",
      });
    } catch (error) {
      console.error("웹타입 상세 조회 오류:", error);
      return res.status(500).json({
        success: false,
        message: "웹타입 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 생성
  static async createWebType(req: AuthenticatedRequest, res: Response) {
    try {
      const {
        web_type,
        type_name,
        type_name_eng,
        description,
        category = "input",
        component_name = "TextWidget",
        config_panel,
        default_config,
        validation_rules,
        default_style,
        input_properties,
        sort_order = 0,
        is_active = "Y",
      } = req.body;

      // 필수 필드 검증
      if (!web_type || !type_name) {
        return res.status(400).json({
          success: false,
          message: "웹타입 코드와 이름은 필수입니다.",
        });
      }

      // 중복 체크
      const existingWebType = await queryOne<any>(
        `SELECT web_type FROM web_type_standards WHERE web_type = $1`,
        [web_type]
      );

      if (existingWebType) {
        return res.status(409).json({
          success: false,
          message: "이미 존재하는 웹타입 코드입니다.",
        });
      }

      const [newWebType] = await query<any>(
        `INSERT INTO web_type_standards (
          web_type, type_name, type_name_eng, description, category,
          component_name, config_panel, default_config, validation_rules,
          default_style, input_properties, sort_order, is_active,
          created_by, created_date, updated_by, updated_date
        ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, NOW(), $15, NOW())
        RETURNING *`,
        [
          web_type,
          type_name,
          type_name_eng,
          description,
          category,
          component_name,
          config_panel,
          default_config,
          validation_rules,
          default_style,
          input_properties,
          sort_order,
          is_active,
          req.user?.userId || "system",
          req.user?.userId || "system",
        ]
      );

      return res.status(201).json({
        success: true,
        data: newWebType,
        message: "웹타입이 성공적으로 생성되었습니다.",
      });
    } catch (error) {
      console.error("웹타입 생성 오류:", error);
      return res.status(500).json({
        success: false,
        message: "웹타입 생성 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 수정
  static async updateWebType(req: AuthenticatedRequest, res: Response) {
    try {
      const { webType } = req.params;
      const {
        type_name,
        type_name_eng,
        description,
        category,
        component_name,
        config_panel,
        default_config,
        validation_rules,
        default_style,
        input_properties,
        sort_order,
        is_active,
      } = req.body;

      // 동적 UPDATE 쿼리 생성
      const updateFields: string[] = [];
      const updateValues: any[] = [];
      let paramIndex = 1;

      if (type_name !== undefined) {
        updateFields.push(`type_name = $${paramIndex}`);
        updateValues.push(type_name);
        paramIndex++;
      }
      if (type_name_eng !== undefined) {
        updateFields.push(`type_name_eng = $${paramIndex}`);
        updateValues.push(type_name_eng);
        paramIndex++;
      }
      if (description !== undefined) {
        updateFields.push(`description = $${paramIndex}`);
        updateValues.push(description);
        paramIndex++;
      }
      if (category !== undefined) {
        updateFields.push(`category = $${paramIndex}`);
        updateValues.push(category);
        paramIndex++;
      }
      if (component_name !== undefined) {
        updateFields.push(`component_name = $${paramIndex}`);
        updateValues.push(component_name);
        paramIndex++;
      }
      if (config_panel !== undefined) {
        updateFields.push(`config_panel = $${paramIndex}`);
        updateValues.push(config_panel);
        paramIndex++;
      }
      if (default_config !== undefined) {
        updateFields.push(`default_config = $${paramIndex}`);
        updateValues.push(default_config);
        paramIndex++;
      }
      if (validation_rules !== undefined) {
        updateFields.push(`validation_rules = $${paramIndex}`);
        updateValues.push(validation_rules);
        paramIndex++;
      }
      if (default_style !== undefined) {
        updateFields.push(`default_style = $${paramIndex}`);
        updateValues.push(default_style);
        paramIndex++;
      }
      if (input_properties !== undefined) {
        updateFields.push(`input_properties = $${paramIndex}`);
        updateValues.push(input_properties);
        paramIndex++;
      }
      if (sort_order !== undefined) {
        updateFields.push(`sort_order = $${paramIndex}`);
        updateValues.push(sort_order);
        paramIndex++;
      }
      if (is_active !== undefined) {
        updateFields.push(`is_active = $${paramIndex}`);
        updateValues.push(is_active);
        paramIndex++;
      }

      // updated_by, updated_date는 항상 추가
      updateFields.push(`updated_by = $${paramIndex}`);
      updateValues.push(req.user?.userId || "system");
      paramIndex++;

      updateFields.push(`updated_date = NOW()`);

      if (updateFields.length === 2) {
        // updated_by, updated_date만 있는 경우 = 수정할 내용이 없음
        return res.status(400).json({
          success: false,
          message: "수정할 내용이 없습니다.",
        });
      }

      // WHERE 조건용 파라미터 추가
      updateValues.push(webType);

      const result = await query<any>(
        `UPDATE web_type_standards
         SET ${updateFields.join(", ")}
         WHERE web_type = $${paramIndex}
         RETURNING *`,
        updateValues
      );

      if (result.length === 0) {
        return res.status(404).json({
          success: false,
          message: "해당 웹타입을 찾을 수 없습니다.",
        });
      }

      const updatedWebType = result[0];

      return res.json({
        success: true,
        data: updatedWebType,
        message: "웹타입이 성공적으로 수정되었습니다.",
      });
    } catch (error) {
      console.error("웹타입 수정 오류:", error);
      return res.status(500).json({
        success: false,
        message: "웹타입 수정 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 삭제
  static async deleteWebType(req: Request, res: Response) {
    try {
      const { webType } = req.params;

      const result = await query<any>(
        `DELETE FROM web_type_standards WHERE web_type = $1 RETURNING *`,
        [webType]
      );

      if (result.length === 0) {
        return res.status(404).json({
          success: false,
          message: "해당 웹타입을 찾을 수 없습니다.",
        });
      }

      return res.json({
        success: true,
        message: "웹타입이 성공적으로 삭제되었습니다.",
      });
    } catch (error) {
      console.error("웹타입 삭제 오류:", error);
      return res.status(500).json({
        success: false,
        message: "웹타입 삭제 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 정렬 순서 업데이트
  static async updateWebTypeSortOrder(
    req: AuthenticatedRequest,
    res: Response
  ) {
    try {
      const { webTypes } = req.body; // [{ web_type: 'text', sort_order: 1 }, ...]

      if (!Array.isArray(webTypes)) {
        return res.status(400).json({
          success: false,
          message: "유효하지 않은 데이터 형식입니다.",
        });
      }

      // 트랜잭션으로 일괄 업데이트
      await transaction(async (client) => {
        for (const item of webTypes) {
          await client.query(
            `UPDATE web_type_standards
             SET sort_order = $1, updated_by = $2, updated_date = NOW()
             WHERE web_type = $3`,
            [item.sort_order, req.user?.userId || "system", item.web_type]
          );
        }
      });

      return res.json({
        success: true,
        message: "웹타입 정렬 순서가 성공적으로 업데이트되었습니다.",
      });
    } catch (error) {
      console.error("웹타입 정렬 순서 업데이트 오류:", error);
      return res.status(500).json({
        success: false,
        message: "정렬 순서 업데이트 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }

  // 웹타입 카테고리 목록 조회
  static async getWebTypeCategories(req: Request, res: Response) {
    try {
      const categories = await query<{ category: string; count: string }>(
        `SELECT category, COUNT(*) as count
         FROM web_type_standards
         WHERE is_active = 'Y'
         GROUP BY category`,
        []
      );

      const categoryList = categories.map((item) => ({
        category: item.category,
        count: parseInt(item.count, 10),
      }));

      return res.json({
        success: true,
        data: categoryList,
        message: "웹타입 카테고리 목록을 성공적으로 조회했습니다.",
      });
    } catch (error) {
      console.error("웹타입 카테고리 조회 오류:", error);
      return res.status(500).json({
        success: false,
        message: "카테고리 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
    }
  }
}
