import { query, queryOne } from "../database/db";

export interface DbTypeCategory {
  type_code: string;
  display_name: string;
  icon?: string | null;
  color?: string | null;
  sort_order?: number | null;
  is_active: boolean;
  created_at: Date;
  updated_at: Date;
}

export interface CreateDbTypeCategoryRequest {
  type_code: string;
  display_name: string;
  icon?: string;
  color?: string;
  sort_order?: number;
}

export interface UpdateDbTypeCategoryRequest {
  display_name?: string;
  icon?: string;
  color?: string;
  sort_order?: number;
  is_active?: boolean;
}

export interface ApiResponse<T> {
  success: boolean;
  data?: T;
  message: string;
  error?: string;
}

export class DbTypeCategoryService {
  /**
   * 모든 DB 타입 카테고리 조회
   */
  static async getAllCategories(): Promise<ApiResponse<DbTypeCategory[]>> {
    try {
      const categories = await query<DbTypeCategory>(
        `SELECT * FROM db_type_categories 
         WHERE is_active = $1 
         ORDER BY sort_order ASC, display_name ASC`,
        [true]
      );

      return {
        success: true,
        data: categories,
        message: "DB 타입 카테고리 목록을 조회했습니다.",
      };
    } catch (error) {
      console.error("DB 타입 카테고리 조회 오류:", error);
      return {
        success: false,
        message: "DB 타입 카테고리 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * 특정 DB 타입 카테고리 조회
   */
  static async getCategoryByTypeCode(
    typeCode: string
  ): Promise<ApiResponse<DbTypeCategory>> {
    try {
      const category = await queryOne<DbTypeCategory>(
        `SELECT * FROM db_type_categories WHERE type_code = $1`,
        [typeCode]
      );

      if (!category) {
        return {
          success: false,
          message: "해당 DB 타입 카테고리를 찾을 수 없습니다.",
        };
      }

      return {
        success: true,
        data: category,
        message: "DB 타입 카테고리를 조회했습니다.",
      };
    } catch (error) {
      console.error("DB 타입 카테고리 조회 오류:", error);
      return {
        success: false,
        message: "DB 타입 카테고리 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * DB 타입 카테고리 생성
   */
  static async createCategory(
    data: CreateDbTypeCategoryRequest
  ): Promise<ApiResponse<DbTypeCategory>> {
    try {
      // 중복 체크
      const existing = await queryOne<DbTypeCategory>(
        `SELECT * FROM db_type_categories WHERE type_code = $1`,
        [data.type_code]
      );

      if (existing) {
        return {
          success: false,
          message: "이미 존재하는 DB 타입 코드입니다.",
        };
      }

      const category = await queryOne<DbTypeCategory>(
        `INSERT INTO db_type_categories 
         (type_code, display_name, icon, color, sort_order, is_active, created_at, updated_at)
         VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
         RETURNING *`,
        [
          data.type_code,
          data.display_name,
          data.icon || null,
          data.color || null,
          data.sort_order || 0,
          true,
        ]
      );

      return {
        success: true,
        data: category || undefined,
        message: "DB 타입 카테고리가 생성되었습니다.",
      };
    } catch (error) {
      console.error("DB 타입 카테고리 생성 오류:", error);
      return {
        success: false,
        message: "DB 타입 카테고리 생성 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * DB 타입 카테고리 수정
   */
  static async updateCategory(
    typeCode: string,
    data: UpdateDbTypeCategoryRequest
  ): Promise<ApiResponse<DbTypeCategory>> {
    try {
      // 동적 UPDATE 쿼리 생성
      const updateFields: string[] = ["updated_at = NOW()"];
      const values: any[] = [];
      let paramIndex = 1;

      if (data.display_name !== undefined) {
        updateFields.push(`display_name = $${paramIndex++}`);
        values.push(data.display_name);
      }
      if (data.icon !== undefined) {
        updateFields.push(`icon = $${paramIndex++}`);
        values.push(data.icon);
      }
      if (data.color !== undefined) {
        updateFields.push(`color = $${paramIndex++}`);
        values.push(data.color);
      }
      if (data.sort_order !== undefined) {
        updateFields.push(`sort_order = $${paramIndex++}`);
        values.push(data.sort_order);
      }
      if (data.is_active !== undefined) {
        updateFields.push(`is_active = $${paramIndex++}`);
        values.push(data.is_active);
      }

      const category = await queryOne<DbTypeCategory>(
        `UPDATE db_type_categories 
         SET ${updateFields.join(", ")}
         WHERE type_code = $${paramIndex}
         RETURNING *`,
        [...values, typeCode]
      );

      return {
        success: true,
        data: category || undefined,
        message: "DB 타입 카테고리가 수정되었습니다.",
      };
    } catch (error) {
      console.error("DB 타입 카테고리 수정 오류:", error);
      return {
        success: false,
        message: "DB 타입 카테고리 수정 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * DB 타입 카테고리 삭제 (비활성화)
   */
  static async deleteCategory(typeCode: string): Promise<ApiResponse<void>> {
    try {
      // 해당 타입을 사용하는 연결이 있는지 확인
      const countResult = await queryOne<{ count: string }>(
        `SELECT COUNT(*) as count FROM external_db_connections 
         WHERE db_type = $1 AND is_active = $2`,
        [typeCode, "Y"]
      );
      const connectionsCount = parseInt(countResult?.count || "0");

      if (connectionsCount > 0) {
        return {
          success: false,
          message: `해당 DB 타입을 사용하는 연결이 ${connectionsCount}개 있어 삭제할 수 없습니다.`,
        };
      }

      await query(
        `UPDATE db_type_categories 
         SET is_active = $1, updated_at = NOW()
         WHERE type_code = $2`,
        [false, typeCode]
      );

      return {
        success: true,
        message: "DB 타입 카테고리가 삭제되었습니다.",
      };
    } catch (error) {
      console.error("DB 타입 카테고리 삭제 오류:", error);
      return {
        success: false,
        message: "DB 타입 카테고리 삭제 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * DB 타입별 연결 통계 조회
   */
  static async getConnectionStatsByType(): Promise<ApiResponse<any[]>> {
    try {
      // LEFT JOIN으로 한 번에 조회
      const result = await query<any>(
        `SELECT 
           c.*,
           COUNT(e.id) as connection_count
         FROM db_type_categories c
         LEFT JOIN external_db_connections e ON c.type_code = e.db_type AND e.is_active = $1
         WHERE c.is_active = $2
         GROUP BY c.type_code, c.display_name, c.icon, c.color, c.sort_order, c.is_active, c.created_at, c.updated_at
         ORDER BY c.sort_order ASC`,
        ["Y", true]
      );

      // connection_count를 숫자로 변환
      const formattedResult = result.map((row) => ({
        ...row,
        connection_count: parseInt(row.connection_count),
      }));

      return {
        success: true,
        data: formattedResult,
        message: "DB 타입별 연결 통계를 조회했습니다.",
      };
    } catch (error) {
      console.error("DB 타입별 통계 조회 오류:", error);
      return {
        success: false,
        message: "DB 타입별 통계 조회 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }

  /**
   * 기본 DB 타입 카테고리 초기화
   */
  static async initializeDefaultCategories(): Promise<ApiResponse<void>> {
    try {
      const defaultCategories = [
        {
          type_code: "postgresql",
          display_name: "PostgreSQL",
          icon: "postgresql",
          color: "#336791",
          sort_order: 1,
        },
        {
          type_code: "oracle",
          display_name: "Oracle",
          icon: "oracle",
          color: "#F80000",
          sort_order: 2,
        },
        {
          type_code: "mysql",
          display_name: "MySQL",
          icon: "mysql",
          color: "#4479A1",
          sort_order: 3,
        },
        {
          type_code: "mariadb",
          display_name: "MariaDB",
          icon: "mariadb",
          color: "#003545",
          sort_order: 4,
        },
        {
          type_code: "mssql",
          display_name: "SQL Server",
          icon: "mssql",
          color: "#CC2927",
          sort_order: 5,
        },
      ];

      for (const category of defaultCategories) {
        await query(
          `INSERT INTO db_type_categories 
           (type_code, display_name, icon, color, sort_order, is_active, created_at, updated_at)
           VALUES ($1, $2, $3, $4, $5, $6, NOW(), NOW())
           ON CONFLICT (type_code) DO NOTHING`,
          [
            category.type_code,
            category.display_name,
            category.icon,
            category.color,
            category.sort_order,
            true,
          ]
        );
      }

      return {
        success: true,
        message: "기본 DB 타입 카테고리가 초기화되었습니다.",
      };
    } catch (error) {
      console.error("기본 카테고리 초기화 오류:", error);
      return {
        success: false,
        message: "기본 카테고리 초기화 중 오류가 발생했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      };
    }
  }
}
