"use client";

import React from "react";

/**
 * 연결 메타 항목: 컴포넌트가 보내거나 받을 수 있는 데이터 슬롯
 */
export interface ConnectionMetaItem {
  key: string;
  label: string;
  type: "filter_value" | "selected_row" | "action_trigger" | "data_refresh" | string;
  category?: "event" | "filter" | "data";
  description?: string;
}

/**
 * 컴포넌트 연결 메타데이터: 디자이너가 연결 가능한 입출력 정의
 */
export interface ComponentConnectionMeta {
  sendable: ConnectionMetaItem[];
  receivable: ConnectionMetaItem[];
}

/**
 * POP 컴포넌트 정의 인터페이스
 */
export interface PopComponentDefinition {
  id: string;
  name: string;
  description: string;
  category: PopComponentCategory;
  icon?: string;
  component: React.ComponentType<any>;
  configPanel?: React.ComponentType<any>;
  preview?: React.ComponentType<{ config?: any }>; // 디자이너 미리보기용
  defaultProps?: Record<string, any>;
  connectionMeta?: ComponentConnectionMeta;
  getDynamicConnectionMeta?: (config: Record<string, unknown>) => ComponentConnectionMeta;
  // POP 전용 속성
  touchOptimized?: boolean;
  minTouchArea?: number;
  supportedDevices?: ("mobile" | "tablet")[];
  createdAt?: Date;
  updatedAt?: Date;
}

/**
 * POP 컴포넌트 카테고리
 */
export type PopComponentCategory =
  | "display" // 데이터 표시 (카드, 리스트, 배지)
  | "input" // 입력 (스캐너, 터치 입력)
  | "action" // 액션 (버튼, 스와이프)
  | "layout" // 레이아웃 (컨테이너, 그리드)
  | "feedback"; // 피드백 (토스트, 로딩)

/**
 * POP 컴포넌트 레지스트리 이벤트
 */
export interface PopComponentRegistryEvent {
  type: "component_registered" | "component_unregistered";
  data: PopComponentDefinition;
  timestamp: Date;
}

/**
 * POP 컴포넌트 레지스트리 클래스
 * 모바일/태블릿 전용 컴포넌트를 등록, 관리, 조회할 수 있는 중앙 레지스트리
 */
export class PopComponentRegistry {
  private static components = new Map<string, PopComponentDefinition>();
  private static eventListeners: Array<(event: PopComponentRegistryEvent) => void> = [];

  /**
   * 컴포넌트 등록
   */
  static registerComponent(definition: PopComponentDefinition): void {
    // 유효성 검사
    if (!definition.id || !definition.name || !definition.component) {
      throw new Error(
        `POP 컴포넌트 등록 실패 (${definition.id || "unknown"}): 필수 필드 누락`
      );
    }

    // 중복 등록 체크
    if (this.components.has(definition.id)) {
      console.warn(`[POP Registry] 컴포넌트 중복 등록: ${definition.id} - 기존 정의를 덮어씁니다.`);
    }

    // 타임스탬프 추가
    const enhancedDefinition: PopComponentDefinition = {
      ...definition,
      touchOptimized: definition.touchOptimized ?? true,
      minTouchArea: definition.minTouchArea ?? 44,
      supportedDevices: definition.supportedDevices ?? ["mobile", "tablet"],
      createdAt: definition.createdAt || new Date(),
      updatedAt: new Date(),
    };

    this.components.set(definition.id, enhancedDefinition);

    // 이벤트 발생
    this.emitEvent({
      type: "component_registered",
      data: enhancedDefinition,
      timestamp: new Date(),
    });

    // 개발 모드에서만 로깅
    if (process.env.NODE_ENV === "development") {
      console.log(`[POP Registry] 컴포넌트 등록: ${definition.id}`);
    }
  }

  /**
   * 컴포넌트 등록 해제
   */
  static unregisterComponent(id: string): void {
    const definition = this.components.get(id);
    if (!definition) {
      console.warn(`[POP Registry] 등록되지 않은 컴포넌트 해제 시도: ${id}`);
      return;
    }

    this.components.delete(id);

    // 이벤트 발생
    this.emitEvent({
      type: "component_unregistered",
      data: definition,
      timestamp: new Date(),
    });

    console.log(`[POP Registry] 컴포넌트 해제: ${id}`);
  }

  /**
   * 특정 컴포넌트 조회
   */
  static getComponent(id: string): PopComponentDefinition | undefined {
    return this.components.get(id);
  }

  /**
   * URL로 컴포넌트 조회
   */
  static getComponentByUrl(url: string): PopComponentDefinition | undefined {
    // "@/lib/registry/pop-components/pop-card-list" → "pop-card-list"
    const parts = url.split("/");
    const componentId = parts[parts.length - 1];
    return this.getComponent(componentId);
  }

  /**
   * 모든 컴포넌트 조회
   */
  static getAllComponents(): PopComponentDefinition[] {
    return Array.from(this.components.values()).sort((a, b) => {
      // 카테고리별 정렬, 그 다음 이름순
      if (a.category !== b.category) {
        return a.category.localeCompare(b.category);
      }
      return a.name.localeCompare(b.name);
    });
  }

  /**
   * 카테고리별 컴포넌트 조회
   */
  static getComponentsByCategory(category: PopComponentCategory): PopComponentDefinition[] {
    return Array.from(this.components.values())
      .filter((def) => def.category === category)
      .sort((a, b) => a.name.localeCompare(b.name));
  }

  /**
   * 디바이스별 컴포넌트 조회
   */
  static getComponentsByDevice(device: "mobile" | "tablet"): PopComponentDefinition[] {
    return Array.from(this.components.values())
      .filter((def) => def.supportedDevices?.includes(device))
      .sort((a, b) => a.name.localeCompare(b.name));
  }

  /**
   * 컴포넌트 검색
   */
  static searchComponents(query: string): PopComponentDefinition[] {
    const lowerQuery = query.toLowerCase();
    return Array.from(this.components.values()).filter(
      (def) =>
        def.id.toLowerCase().includes(lowerQuery) ||
        def.name.toLowerCase().includes(lowerQuery) ||
        def.description?.toLowerCase().includes(lowerQuery)
    );
  }

  /**
   * 등록된 컴포넌트 개수
   */
  static getComponentCount(): number {
    return this.components.size;
  }

  /**
   * 카테고리별 통계
   */
  static getStatsByCategory(): Record<PopComponentCategory, number> {
    const stats: Record<PopComponentCategory, number> = {
      display: 0,
      input: 0,
      action: 0,
      layout: 0,
      feedback: 0,
    };

    for (const def of this.components.values()) {
      stats[def.category]++;
    }

    return stats;
  }

  /**
   * 이벤트 리스너 등록
   */
  static addEventListener(callback: (event: PopComponentRegistryEvent) => void): void {
    this.eventListeners.push(callback);
  }

  /**
   * 이벤트 리스너 해제
   */
  static removeEventListener(callback: (event: PopComponentRegistryEvent) => void): void {
    const index = this.eventListeners.indexOf(callback);
    if (index > -1) {
      this.eventListeners.splice(index, 1);
    }
  }

  /**
   * 이벤트 발생
   */
  private static emitEvent(event: PopComponentRegistryEvent): void {
    for (const listener of this.eventListeners) {
      try {
        listener(event);
      } catch (error) {
        console.error("[POP Registry] 이벤트 리스너 오류:", error);
      }
    }
  }

  /**
   * 레지스트리 초기화 (테스트용)
   */
  static clear(): void {
    this.components.clear();
    console.log("[POP Registry] 레지스트리 초기화됨");
  }

  /**
   * 컴포넌트 존재 여부 확인
   */
  static hasComponent(id: string): boolean {
    return this.components.has(id);
  }

  /**
   * 디버그 정보 출력
   */
  static debug(): void {
    console.group("[POP Registry] 등록된 컴포넌트");
    console.log(`총 ${this.components.size}개 컴포넌트`);
    console.table(
      Array.from(this.components.values()).map((c) => ({
        id: c.id,
        name: c.name,
        category: c.category,
        touchOptimized: c.touchOptimized,
        devices: c.supportedDevices?.join(", "),
      }))
    );
    console.groupEnd();
  }
}

// 기본 export
export default PopComponentRegistry;
