import { Request, Response } from "express";
import componentStandardService, {
  ComponentQueryParams,
} from "../services/componentStandardService";

interface AuthenticatedRequest extends Request {
  user?: {
    userId: string;
    companyCode: string;
    [key: string]: any;
  };
}

class ComponentStandardController {
  /**
   * 컴포넌트 목록 조회
   */
  async getComponents(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const {
        category,
        active,
        is_public,
        search,
        sort,
        order,
        limit,
        offset,
      } = req.query;

      const params: ComponentQueryParams = {
        category: category as string,
        active: (active as string) || "Y",
        is_public: is_public as string,
        company_code: req.user?.companyCode,
        search: search as string,
        sort: (sort as string) || "sort_order",
        order: (order as "asc" | "desc") || "asc",
        limit: limit ? parseInt(limit as string) : undefined,
        offset: offset ? parseInt(offset as string) : 0,
      };

      const result = await componentStandardService.getComponents(params);

      res.status(200).json({
        success: true,
        data: result,
        message: "컴포넌트 목록을 성공적으로 조회했습니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 목록 조회 실패:", error);
      res.status(500).json({
        success: false,
        message: "컴포넌트 목록 조회에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 상세 조회
   */
  async getComponent(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const { component_code } = req.params;

      if (!component_code) {
        res.status(400).json({
          success: false,
          message: "컴포넌트 코드가 필요합니다.",
        });
        return;
      }

      const component =
        await componentStandardService.getComponent(component_code);

      res.status(200).json({
        success: true,
        data: component,
        message: "컴포넌트를 성공적으로 조회했습니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 조회 실패:", error);
      res.status(404).json({
        success: false,
        message: "컴포넌트를 찾을 수 없습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 생성
   */
  async createComponent(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const {
        component_code,
        component_name,
        component_name_eng,
        description,
        category,
        icon_name,
        default_size,
        component_config,
        preview_image,
        sort_order,
        is_active,
        is_public,
      } = req.body;

      // 필수 필드 검증
      if (
        !component_code ||
        !component_name ||
        !category ||
        !component_config
      ) {
        res.status(400).json({
          success: false,
          message:
            "필수 필드가 누락되었습니다. (component_code, component_name, category, component_config)",
        });
        return;
      }

      const componentData = {
        component_code,
        component_name,
        component_name_eng,
        description,
        category,
        icon_name,
        default_size,
        component_config,
        preview_image,
        sort_order,
        is_active: is_active || "Y",
        is_public: is_public || "Y",
        company_code: req.user?.companyCode || "DEFAULT",
        created_by: req.user?.userId,
        updated_by: req.user?.userId,
      };

      const component =
        await componentStandardService.createComponent(componentData);

      res.status(201).json({
        success: true,
        data: component,
        message: "컴포넌트가 성공적으로 생성되었습니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 생성 실패:", error);
      res.status(400).json({
        success: false,
        message: "컴포넌트 생성에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 수정
   */
  async updateComponent(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const { component_code } = req.params;
      const updateData = {
        ...req.body,
        updated_by: req.user?.userId,
      };

      if (!component_code) {
        res.status(400).json({
          success: false,
          message: "컴포넌트 코드가 필요합니다.",
        });
        return;
      }

      const component = await componentStandardService.updateComponent(
        component_code,
        updateData
      );

      res.status(200).json({
        success: true,
        data: component,
        message: "컴포넌트가 성공적으로 수정되었습니다.",
      });
      return;
    } catch (error) {
      const { component_code } = req.params;
      const updateData = req.body;

      console.error("컴포넌트 수정 실패 [상세]:", {
        component_code,
        updateData,
        error: error instanceof Error ? error.message : error,
        stack: error instanceof Error ? error.stack : undefined,
      });
      res.status(400).json({
        success: false,
        message: "컴포넌트 수정에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 삭제
   */
  async deleteComponent(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const { component_code } = req.params;

      if (!component_code) {
        res.status(400).json({
          success: false,
          message: "컴포넌트 코드가 필요합니다.",
        });
        return;
      }

      const result =
        await componentStandardService.deleteComponent(component_code);

      res.status(200).json({
        success: true,
        data: result,
        message: "컴포넌트가 성공적으로 삭제되었습니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 삭제 실패:", error);
      res.status(400).json({
        success: false,
        message: "컴포넌트 삭제에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 정렬 순서 업데이트
   */
  async updateSortOrder(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const { updates } = req.body;

      if (!updates || !Array.isArray(updates)) {
        res.status(400).json({
          success: false,
          message: "업데이트 데이터가 필요합니다.",
        });
        return;
      }

      const result = await componentStandardService.updateSortOrder(updates);

      res.status(200).json({
        success: true,
        data: result,
        message: "정렬 순서가 성공적으로 업데이트되었습니다.",
      });
      return;
    } catch (error) {
      console.error("정렬 순서 업데이트 실패:", error);
      res.status(400).json({
        success: false,
        message: "정렬 순서 업데이트에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 복제
   */
  async duplicateComponent(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const { source_code, new_code, new_name } = req.body;

      if (!source_code || !new_code || !new_name) {
        res.status(400).json({
          success: false,
          message:
            "필수 필드가 누락되었습니다. (source_code, new_code, new_name)",
        });
        return;
      }

      const component = await componentStandardService.duplicateComponent(
        source_code,
        new_code,
        new_name
      );

      res.status(201).json({
        success: true,
        data: component,
        message: "컴포넌트가 성공적으로 복제되었습니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 복제 실패:", error);
      res.status(400).json({
        success: false,
        message: "컴포넌트 복제에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 카테고리 목록 조회
   */
  async getCategories(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const categories = await componentStandardService.getCategories(
        req.user?.companyCode
      );

      res.status(200).json({
        success: true,
        data: categories,
        message: "카테고리 목록을 성공적으로 조회했습니다.",
      });
      return;
    } catch (error) {
      console.error("카테고리 조회 실패:", error);
      res.status(500).json({
        success: false,
        message: "카테고리 조회에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 통계 조회
   */
  async getStatistics(req: AuthenticatedRequest, res: Response): Promise<void> {
    try {
      const statistics = await componentStandardService.getStatistics(
        req.user?.companyCode
      );

      res.status(200).json({
        success: true,
        data: statistics,
        message: "통계를 성공적으로 조회했습니다.",
      });
      return;
    } catch (error) {
      console.error("통계 조회 실패:", error);
      res.status(500).json({
        success: false,
        message: "통계 조회에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }

  /**
   * 컴포넌트 코드 중복 체크
   */
  async checkDuplicate(
    req: AuthenticatedRequest,
    res: Response
  ): Promise<void> {
    try {
      const { component_code } = req.params;

      if (!component_code) {
        res.status(400).json({
          success: false,
          message: "컴포넌트 코드가 필요합니다.",
        });
        return;
      }

      const isDuplicate = await componentStandardService.checkDuplicate(
        component_code,
        req.user?.companyCode
      );

      res.status(200).json({
        success: true,
        data: { isDuplicate, component_code },
        message: isDuplicate
          ? "이미 사용 중인 컴포넌트 코드입니다."
          : "사용 가능한 컴포넌트 코드입니다.",
      });
      return;
    } catch (error) {
      console.error("컴포넌트 코드 중복 체크 실패:", error);
      res.status(500).json({
        success: false,
        message: "컴포넌트 코드 중복 체크에 실패했습니다.",
        error: error instanceof Error ? error.message : "알 수 없는 오류",
      });
      return;
    }
  }
}

export default new ComponentStandardController();
