#!/usr/bin/env node

const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");

/**
 * 레이아웃 스캐폴딩 CLI 도구
 *
 * 사용법:
 * npm run create-layout <layoutName> [options]
 *
 * 예시:
 * npm run create-layout accordion
 * npm run create-layout sidebar --category=navigation --zones=3
 */

// 명령행 인자 파싱
const args = process.argv.slice(2);
const layoutName = args[0];

if (!layoutName) {
  console.error("❌ 레이아웃 이름이 필요합니다.");
  console.log("사용법: npm run create-layout <layoutName> [options]");
  console.log("예시: npm run create-layout accordion --category=navigation");
  process.exit(1);
}

// 옵션 파싱
const options = {};
args.slice(1).forEach((arg) => {
  if (arg.startsWith("--")) {
    const [key, value] = arg.slice(2).split("=");
    options[key] = value || true;
  }
});

/**
 * 하이픈을 카멜케이스로 변환
 */
function toCamelCase(str) {
  return str.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
}

/**
 * 하이픈을 파스칼케이스로 변환
 */
function toPascalCase(str) {
  const camelCase = toCamelCase(str);
  return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
}

/**
 * 안전한 식별자명 생성 (하이픈 제거)
 */
function toSafeId(str) {
  return str.toLowerCase().replace(/[^a-z0-9]/g, "");
}

// 안전한 이름들 생성
const safeLayoutName = toCamelCase(layoutName);
const pascalLayoutName = toPascalCase(layoutName);
const safeId = layoutName.toLowerCase(); // kebab-case는 id로 유지

// 기본 옵션
const config = {
  name: safeLayoutName,
  id: safeId,
  className: pascalLayoutName,
  category: options.category || "basic",
  zones: parseInt(options.zones) || 2,
  description: options.description || `${safeLayoutName} 레이아웃입니다.`,
  author: options.author || "Developer",
  ...options,
};

// 검증
if (!/^[a-z][a-z0-9-]*$/.test(config.id)) {
  console.error("❌ 레이아웃 이름은 소문자로 시작하고 소문자, 숫자, 하이픈만 포함해야 합니다.");
  process.exit(1);
}

const layoutDir = path.join(__dirname, "../lib/registry/layouts", config.id);

// 디렉토리 존재 확인
if (fs.existsSync(layoutDir)) {
  console.error(`❌ 레이아웃 디렉토리가 이미 존재합니다: ${layoutDir}`);
  process.exit(1);
}

console.log("🚀 새 레이아웃 생성 중...");
console.log(`📁 이름: ${config.name}`);
console.log(`🔖 ID: ${config.id}`);
console.log(`📂 카테고리: ${config.category}`);
console.log(`🎯 존 개수: ${config.zones}`);

// 디렉토리 생성
fs.mkdirSync(layoutDir, { recursive: true });

// 템플릿 파일들 생성
createIndexFile();
createLayoutComponent();
createLayoutRenderer();
createConfigFile();
createTypesFile();
createReadme();

// package.json 스크립트 업데이트
updatePackageScripts();

console.log("");
console.log("✅ 레이아웃 생성 완료!");
console.log("");
console.log("📝 다음 단계:");
console.log(`1. ${layoutDir}/${config.className}Layout.tsx 에서 비즈니스 로직 구현`);
console.log("2. 파일을 저장하면 자동으로 화면편집기에서 사용 가능");
console.log("3. 필요에 따라 config.ts에서 기본 설정 조정");
console.log("");
console.log("🔧 개발 팁:");
console.log("- 브라우저 개발자 도구에서 window.__LAYOUT_REGISTRY__.list() 로 등록 확인");
console.log("- Hot Reload 지원으로 파일 수정 시 자동 업데이트");

/**
 * index.ts 파일 생성
 */
function createIndexFile() {
  const content = `"use client";

import { createLayoutDefinition } from "../../utils/createLayoutDefinition";
import { ${config.className}Layout } from "./${config.className}Layout";
import { ${config.className}LayoutRenderer } from "./${config.className}LayoutRenderer";
import { LayoutRendererProps } from "../BaseLayoutRenderer";
import React from "react";

/**
 * ${config.name} 래퍼 컴포넌트 (DynamicLayoutRenderer용)
 */
const ${config.className}LayoutWrapper: React.FC<LayoutRendererProps> = (props) => {
  const renderer = new ${config.className}LayoutRenderer(props);
  return renderer.render();
};

/**
 * ${config.name} 레이아웃 정의
 */
export const ${config.className}LayoutDefinition = createLayoutDefinition({
  id: "${config.id}",
  name: "${config.name}",
  nameEng: "${config.className} Layout",
  description: "${config.description}",
  category: "${config.category}",
  icon: "${config.icon || config.id}",
  component: ${config.className}LayoutWrapper,
  defaultConfig: {
    ${toCamelCase(config.id)}: {
      // TODO: 레이아웃별 설정 정의
    },
  },
  defaultZones: [${generateDefaultZones()}
  ],
  tags: ["${config.id}", "${config.category}", "layout"],
  version: "1.0.0",
  author: "${config.author}",
  documentation: "${config.description}",
});

// 자동 등록을 위한 export
export { ${config.className}LayoutRenderer } from "./${config.className}LayoutRenderer";
`;

  fs.writeFileSync(path.join(layoutDir, "index.ts"), content);
  console.log("✅ index.ts 생성됨");
}

/**
 * 레이아웃 컴포넌트 파일 생성
 */
function createLayoutComponent() {
  const content = `"use client";

import React from "react";
import { LayoutRendererProps } from "../BaseLayoutRenderer";

/**
 * ${config.name} 컴포넌트
 */
export interface ${config.className}LayoutProps extends LayoutRendererProps {
  renderer: any; // ${config.className}LayoutRenderer 타입
}

export const ${config.className}Layout: React.FC<${config.className}LayoutProps> = ({
  layout,
  isDesignMode = false,
  isSelected = false,
  onClick,
  className = "",
  renderer,
  ...props
}) => {
  if (!layout.layoutConfig.${toCamelCase(config.id)}) {
    return (
      <div className="error-layout flex items-center justify-center p-4 border-2 border-red-300 bg-red-50 rounded">
        <div className="text-center text-red-600">
          <div className="font-medium">${config.name} 설정이 없습니다.</div>
          <div className="text-sm mt-1">layoutConfig.${toCamelCase(config.id)}가 필요합니다.</div>
        </div>
      </div>
    );
  }

  const ${config.name}Config = layout.layoutConfig.${toCamelCase(config.id)};
  const containerStyle = renderer.getLayoutContainerStyle();

  // ${config.name} 컨테이너 스타일
  const ${config.name}Style: React.CSSProperties = {
    ...containerStyle,
    // TODO: 레이아웃 전용 스타일 정의
    height: "100%",
    width: "100%",
  };

  // 디자인 모드 스타일
  if (isDesignMode) {
    ${config.name}Style.border = isSelected ? "2px solid #3b82f6" : "1px solid #e2e8f0";
    ${config.name}Style.borderRadius = "8px";
  }

  return (
    <div
      className={\`${config.id}-layout \${isDesignMode ? "design-mode" : ""} \${className}\`}
      style={${config.name}Style}
      onClick={onClick}
      draggable={isDesignMode}
      onDragStart={props.onDragStart}
      onDragEnd={props.onDragEnd}
      {...props}
    >
      {layout.zones.map((zone: any) => {
        const zoneChildren = renderer.getZoneChildren(zone.id);

        // TODO: 존별 스타일 정의
        const zoneStyle: React.CSSProperties = {
          // 레이아웃별 존 스타일 구현
        };

        return renderer.renderZone(zone, zoneChildren, {
          style: zoneStyle,
          className: "${config.id}-zone",
        });
      })}

      {/* 디자인 모드에서 빈 영역 표시 */}
      {isDesignMode && layout.zones.length === 0 && (
        <div
          className="empty-${config.id}-container"
          style={{
            flex: 1,
            border: "2px dashed #cbd5e1",
            borderRadius: "8px",
            backgroundColor: "rgba(148, 163, 184, 0.05)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            fontSize: "14px",
            color: "#64748b",
            minHeight: "100px",
            padding: "20px",
            textAlign: "center",
          }}
        >
          ${config.name}에 존을 추가하세요
        </div>
      )}
    </div>
  );
};
`;

  fs.writeFileSync(path.join(layoutDir, `${config.className}Layout.tsx`), content);
  console.log(`✅ ${config.className}Layout.tsx 생성됨`);
}

/**
 * 레이아웃 렌더러 파일 생성
 */
function createLayoutRenderer() {
  const content = `"use client";

import { AutoRegisteringLayoutRenderer } from "../AutoRegisteringLayoutRenderer";
import { LayoutRendererProps } from "../BaseLayoutRenderer";
import { ${config.className}LayoutDefinition } from "./index";
import { ${config.className}Layout } from "./${config.className}Layout";

/**
 * ${config.name} 렌더러 (새 구조)
 */
export class ${config.className}LayoutRenderer extends AutoRegisteringLayoutRenderer {
  /**
   * 레이아웃 정의 (자동 등록용)
   */
  static readonly layoutDefinition = ${config.className}LayoutDefinition;

  /**
   * 클래스 로드 시 자동 등록 실행
   */
  static {
    this.registerSelf();
  }

  /**
   * 렌더링 실행
   */
  render(): React.ReactElement {
    return <${config.className}Layout {...this.props} renderer={this} />;
  }
}

/**
 * React 함수 컴포넌트로 래핑 (외부 사용용)
 */
export const ${config.className}LayoutComponent: React.FC<LayoutRendererProps> = (props) => {
  const renderer = new ${config.className}LayoutRenderer(props);
  return renderer.render();
};

// 개발 모드에서 Hot Reload 지원
if (process.env.NODE_ENV === 'development') {
  // HMR API 등록
  if ((module as any).hot) {
    (module as any).hot.accept();
    (module as any).hot.dispose(() => {
      ${config.className}LayoutRenderer.unregisterSelf();
    });
  }
}
`;

  fs.writeFileSync(path.join(layoutDir, `${config.className}LayoutRenderer.tsx`), content);
  console.log(`✅ ${config.className}LayoutRenderer.tsx 생성됨`);
}

/**
 * 설정 파일 생성
 */
function createConfigFile() {
  const content = `/**
 * ${config.name} 기본 설정
 */
export const ${config.className}LayoutConfig = {
  defaultConfig: {
    ${config.id}: {
      // TODO: 레이아웃 전용 설정 정의
      // 예시:
      // spacing: 16,
      // orientation: "vertical",
      // allowResize: true,
    },
  },
  
  defaultZones: [${generateDefaultZones()}
  ],
  
  // 설정 스키마 (검증용)
  configSchema: {
    type: "object",
    properties: {
      ${config.id}: {
        type: "object",
        properties: {
          // TODO: 설정 스키마 정의
        },
        additionalProperties: false,
      },
    },
    required: ["${config.id}"],
  },
};
`;

  fs.writeFileSync(path.join(layoutDir, "config.ts"), content);
  console.log("✅ config.ts 생성됨");
}

/**
 * 타입 정의 파일 생성
 */
function createTypesFile() {
  const content = `import { LayoutRendererProps } from "../BaseLayoutRenderer";

/**
 * ${config.name} 설정 타입
 */
export interface ${config.className}Config {
  // TODO: 레이아웃 전용 설정 타입 정의
  // 예시:
  // spacing?: number;
  // orientation?: "vertical" | "horizontal";
  // allowResize?: boolean;
}

/**
 * ${config.name} Props 타입
 */
export interface ${config.className}LayoutProps extends LayoutRendererProps {
  renderer: any; // ${config.className}LayoutRenderer 타입
}

/**
 * ${config.name} 존 타입
 */
export interface ${config.className}Zone {
  id: string;
  name: string;
  // TODO: 존별 전용 속성 정의
}
`;

  fs.writeFileSync(path.join(layoutDir, "types.ts"), content);
  console.log("✅ types.ts 생성됨");
}

/**
 * README 파일 생성
 */
function createReadme() {
  const content = `# ${config.name}

${config.description}

## 사용법

이 레이아웃은 자동으로 등록되어 화면편집기에서 사용할 수 있습니다.

## 구성

- \`${config.className}Layout.tsx\`: 메인 레이아웃 컴포넌트
- \`${config.className}LayoutRenderer.tsx\`: 렌더러 (자동 등록)
- \`config.ts\`: 기본 설정
- \`types.ts\`: 타입 정의
- \`index.ts\`: 진입점

## 개발

1. \`${config.className}Layout.tsx\`에서 레이아웃 로직 구현
2. \`config.ts\`에서 기본 설정 조정
3. \`types.ts\`에서 타입 정의 추가

## 설정

\`\`\`typescript
{
  ${config.id}: {
    // TODO: 설정 옵션 문서화
  }
}
\`\`\`

## 존 구성

${generateZoneDocumentation()}

---

생성일: ${new Date().toLocaleDateString()}
버전: 1.0.0
작성자: ${config.author}
`;

  fs.writeFileSync(path.join(layoutDir, "README.md"), content);
  console.log("✅ README.md 생성됨");
}

/**
 * 기본 존 생성
 */
function generateDefaultZones() {
  const zones = [];
  for (let i = 1; i <= config.zones; i++) {
    zones.push(`
    {
      id: "zone${i}",
      name: "존 ${i}",
      position: {},
      size: { width: "100%", height: "100%" },
    }`);
  }
  return zones.join(",");
}

/**
 * 존 문서화
 */
function generateZoneDocumentation() {
  const docs = [];
  for (let i = 1; i <= config.zones; i++) {
    docs.push(`- **존 ${i}** (\`zone${i}\`): 기본 영역`);
  }
  return docs.join("\n");
}

/**
 * package.json 스크립트 업데이트
 */
function updatePackageScripts() {
  const packagePath = path.join(__dirname, "../package.json");

  if (fs.existsSync(packagePath)) {
    try {
      const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));

      if (!packageJson.scripts) {
        packageJson.scripts = {};
      }

      if (!packageJson.scripts["create-layout"]) {
        packageJson.scripts["create-layout"] = "node scripts/create-layout.js";
        fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2));
        console.log("✅ package.json 스크립트 추가됨");
      }
    } catch (error) {
      console.warn("⚠️ package.json 업데이트 실패:", error.message);
    }
  }
}
