/**
 * Template Factory System
 * 서비스 티어별 템플릿 생성 및 관리 시스템
 */

import { v4 as uuidv4 } from "uuid";
import {
  TemplateFactory,
  BaseTemplate,
  ServiceTier,
  ComponentType,
  TemplateValidationResult,
  TemplateValidationError,
  TemplateValidationWarning,
  GlobalTemplateSettings,
  CustomizationOptions,
  TemplateMetadata,
  BaseComponent,
  ComponentSettings,
} from "../../types/template-system";
import { componentRegistry } from "./component-registry";

export class AgentCTemplateFactory implements TemplateFactory {
  /**
   * 새 템플릿 생성
   */
  create(tier: ServiceTier, config: Partial<BaseTemplate>): BaseTemplate {
    const templateId = config.id || uuidv4();
    const slug =
      config.slug ||
      this.generateSlug(config.name || `template-${tier.toLowerCase()}`);

    const template: BaseTemplate = {
      id: templateId,
      name: config.name || `${tier} Template`,
      slug,
      tier,
      description: config.description || this.getDefaultDescription(tier),
      components: this.createDefaultComponents(tier),
      globalSettings: this.createDefaultGlobalSettings(tier),
      customizationOptions: this.createDefaultCustomizationOptions(tier),
      metadata: this.createDefaultMetadata(tier, config),
      ...config,
    };

    return template;
  }

  /**
   * 템플릿 복제
   */
  clone(template: BaseTemplate): BaseTemplate {
    const newId = uuidv4();
    const newSlug = this.generateSlug(`${template.slug}-copy`);

    return {
      ...JSON.parse(JSON.stringify(template)), // Deep clone
      id: newId,
      slug: newSlug,
      name: `${template.name} (Copy)`,
      metadata: {
        ...template.metadata,
        lastModified: new Date(),
        version: "1.0.0",
      },
    };
  }

  /**
   * 템플릿을 다른 티어로 마이그레이션
   */
  migrate(template: BaseTemplate, newTier: ServiceTier): BaseTemplate {
    const migratedTemplate = this.clone(template);
    migratedTemplate.tier = newTier;
    migratedTemplate.name = `${template.name} (${newTier})`;

    // 컴포넌트 필터링 - 새 티어에서 지원하지 않는 컴포넌트 제거
    migratedTemplate.components = this.filterComponentsForTier(
      template.components,
      newTier
    );

    // 커스터마이제이션 옵션 업데이트
    migratedTemplate.customizationOptions =
      this.updateCustomizationOptionsForTier(
        template.customizationOptions,
        newTier
      );

    // 글로벌 설정 업데이트
    migratedTemplate.globalSettings = this.updateGlobalSettingsForTier(
      template.globalSettings,
      newTier
    );

    // 메타데이터 업데이트
    migratedTemplate.metadata = {
      ...template.metadata,
      minimumTier: newTier,
      lastModified: new Date(),
      version: "1.0.0",
    };

    return migratedTemplate;
  }

  /**
   * 템플릿 검증
   */
  validate(template: BaseTemplate): TemplateValidationResult {
    const errors: TemplateValidationError[] = [];
    const warnings: TemplateValidationWarning[] = [];

    // 기본 필드 검증
    if (!template.id || !template.name || !template.slug) {
      errors.push({
        code: "MISSING_REQUIRED_FIELDS",
        message: "필수 필드(id, name, slug)가 누락되었습니다.",
        severity: "error",
      });
    }

    // 컴포넌트 검증
    template.components.forEach((component, index) => {
      if (!componentRegistry.validate(component, template.tier)) {
        errors.push({
          code: "INVALID_COMPONENT",
          message: `컴포넌트 ${component.type}가 ${template.tier} 티어에서 유효하지 않습니다.`,
          component: component.id,
          severity: "error",
        });
      }

      // 중복 컴포넌트 타입 검사
      const duplicates = template.components.filter(
        (c, i) => i !== index && c.type === component.type
      );
      if (duplicates.length > 0) {
        warnings.push({
          code: "DUPLICATE_COMPONENT_TYPE",
          message: `중복된 컴포넌트 타입 ${component.type}이 발견되었습니다.`,
          component: component.id,
          suggestion: "중복된 컴포넌트를 제거하거나 다른 타입으로 변경하세요.",
        });
      }
    });

    // 티어별 제한사항 검증
    const tierRestrictions = componentRegistry.getTierRestrictions(
      template.tier
    );
    template.components.forEach((component) => {
      if (!tierRestrictions.allowedComponents.includes(component.type)) {
        errors.push({
          code: "TIER_RESTRICTION_VIOLATION",
          message: `컴포넌트 ${component.type}는 ${template.tier} 티어에서 허용되지 않습니다.`,
          component: component.id,
          severity: "error",
        });
      }
    });

    // 커스터마이제이션 옵션 검증
    if (
      template.tier === ServiceTier.STARTER &&
      template.customizationOptions.advanced.allowCustomCSS
    ) {
      warnings.push({
        code: "ADVANCED_FEATURE_IN_STARTER",
        message:
          "Starter 티어에서 고급 CSS 커스터마이제이션이 활성화되어 있습니다.",
        suggestion:
          "Starter 티어에서는 고급 기능을 비활성화하는 것을 권장합니다.",
      });
    }

    return {
      isValid: errors.length === 0,
      errors,
      warnings,
    };
  }

  /**
   * 티어별 기본 컴포넌트 생성
   */
  private createDefaultComponents(tier: ServiceTier): BaseComponent[] {
    const tierRestrictions = componentRegistry.getTierRestrictions(tier);
    const components: BaseComponent[] = [];

    // 필수 컴포넌트들을 순서대로 추가
    const requiredComponents = [
      ComponentType.HERO,
      ComponentType.ABOUT,
      ComponentType.CONTACT,
      ComponentType.FOOTER,
    ];

    requiredComponents.forEach((type, index) => {
      if (tierRestrictions.allowedComponents.includes(type)) {
        components.push(this.createComponent(type, tier, index));
      }
    });

    // 티어별 추가 컴포넌트
    if (tier === ServiceTier.STANDARD || tier === ServiceTier.PLUS) {
      const standardComponents = [
        ComponentType.SERVICES,
        ComponentType.TESTIMONIALS,
      ];
      standardComponents.forEach((type, index) => {
        components.push(
          this.createComponent(type, tier, requiredComponents.length + index)
        );
      });
    }

    if (tier === ServiceTier.PLUS) {
      const plusComponents = [ComponentType.TEAM, ComponentType.GALLERY];
      plusComponents.forEach((type, index) => {
        const order = requiredComponents.length + 2 + index;
        components.push(this.createComponent(type, tier, order));
      });
    }

    return components;
  }

  /**
   * 개별 컴포넌트 생성
   */
  private createComponent(
    type: ComponentType,
    tier: ServiceTier,
    order: number
  ): BaseComponent {
    const settings: ComponentSettings = {
      enabled: true,
      visible: true,
      customizable: tier !== ServiceTier.STARTER,
    };

    return {
      id: uuidv4(),
      type,
      title: this.getComponentTitle(type),
      description: this.getComponentDescription(type),
      isRequired: this.isComponentRequired(type),
      availableIn: this.getComponentAvailability(type),
      order,
      settings,
    };
  }

  /**
   * 컴포넌트 제목 반환
   */
  private getComponentTitle(type: ComponentType): string {
    const titles: Record<ComponentType, string> = {
      [ComponentType.HERO]: "메인 히어로 섹션",
      [ComponentType.ABOUT]: "소개 섹션",
      [ComponentType.SERVICES]: "서비스 섹션",
      [ComponentType.TESTIMONIALS]: "고객 후기",
      [ComponentType.BLOG]: "블로그",
      [ComponentType.CONTACT]: "연락처",
      [ComponentType.FOOTER]: "푸터",
      [ComponentType.TEAM]: "팀 소개",
      [ComponentType.GALLERY]: "갤러리",
      [ComponentType.NEWSLETTER]: "뉴스레터",
      [ComponentType.CASE_STUDIES]: "사례 연구",
    };
    return titles[type];
  }

  /**
   * 컴포넌트 설명 반환
   */
  private getComponentDescription(type: ComponentType): string {
    const descriptions: Record<ComponentType, string> = {
      [ComponentType.HERO]: "사이트의 첫인상을 결정하는 메인 배너 영역",
      [ComponentType.ABOUT]: "회사나 개인에 대한 소개 내용",
      [ComponentType.SERVICES]: "제공하는 서비스나 상품 안내",
      [ComponentType.TESTIMONIALS]: "고객들의 후기와 평가",
      [ComponentType.BLOG]: "블로그 포스트 목록 및 내용",
      [ComponentType.CONTACT]: "연락처 정보 및 문의 양식",
      [ComponentType.FOOTER]: "사이트 하단 정보 영역",
      [ComponentType.TEAM]: "팀 멤버 소개",
      [ComponentType.GALLERY]: "이미지 갤러리",
      [ComponentType.NEWSLETTER]: "뉴스레터 구독 양식",
      [ComponentType.CASE_STUDIES]: "프로젝트 사례 연구",
    };
    return descriptions[type];
  }

  /**
   * 컴포넌트 필수 여부 반환
   */
  private isComponentRequired(type: ComponentType): boolean {
    const requiredComponents = [ComponentType.HERO, ComponentType.FOOTER];
    return requiredComponents.includes(type);
  }

  /**
   * 컴포넌트 사용 가능 티어 반환
   */
  private getComponentAvailability(type: ComponentType): ServiceTier[] {
    const starterComponents = [
      ComponentType.HERO,
      ComponentType.ABOUT,
      ComponentType.CONTACT,
      ComponentType.FOOTER,
    ];
    const standardComponents = [
      ...starterComponents,
      ComponentType.SERVICES,
      ComponentType.TESTIMONIALS,
      ComponentType.BLOG,
    ];

    if (starterComponents.includes(type))
      return [ServiceTier.STARTER, ServiceTier.STANDARD, ServiceTier.PLUS];
    if (standardComponents.includes(type))
      return [ServiceTier.STANDARD, ServiceTier.PLUS];
    return [ServiceTier.PLUS];
  }

  /**
   * 티어별 기본 글로벌 설정 생성
   */
  private createDefaultGlobalSettings(
    tier: ServiceTier
  ): GlobalTemplateSettings {
    const baseSettings: GlobalTemplateSettings = {
      theme: {
        primaryColor: "#3b82f6",
        secondaryColor: "#64748b",
        fontFamily: "Inter, sans-serif",
        borderRadius: 8,
      },
      layout: {
        containerWidth: "contained",
        spacing: "normal",
        headerStyle: "simple",
        footerStyle: "minimal",
      },
      seo: {
        metaTitle: undefined,
        metaDescription: undefined,
        structuredData: false,
      },
      performance: {
        lazyLoading: true,
        cacheStrategy: "basic",
        optimizeImages: true,
      },
    };

    // 티어별 설정 향상
    if (tier === ServiceTier.STANDARD) {
      baseSettings.layout.headerStyle = "standard";
      baseSettings.layout.footerStyle = "standard";
      baseSettings.seo.structuredData = true;
      baseSettings.theme.accentColor = "#10b981";
    }

    if (tier === ServiceTier.PLUS) {
      baseSettings.layout.headerStyle = "advanced";
      baseSettings.layout.footerStyle = "comprehensive";
      baseSettings.performance.cacheStrategy = "aggressive";
      baseSettings.theme.accentColor = "#8b5cf6";
    }

    return baseSettings;
  }

  /**
   * 티어별 기본 커스터마이제이션 옵션 생성
   */
  private createDefaultCustomizationOptions(
    tier: ServiceTier
  ): CustomizationOptions {
    const baseOptions: CustomizationOptions = {
      colors: {
        allowCustomColors: false,
        predefinedPalettes: [
          ["#3b82f6", "#64748b"],
          ["#10b981", "#059669"],
          ["#f59e0b", "#d97706"],
        ],
      },
      typography: {
        allowFontChange: false,
        availableFonts: ["Inter", "Roboto"],
        allowFontSizeChange: false,
      },
      layout: {
        allowLayoutChange: false,
        availableLayouts: ["standard"],
        allowComponentReordering: false,
      },
      components: {
        allowComponentToggle: false,
        allowComponentSettings: false,
        restrictedComponents: [],
      },
      advanced: {
        allowCustomCSS: false,
        allowCustomJS: false,
        allowThirdPartyIntegrations: false,
      },
    };

    // Standard 티어 향상
    if (tier === ServiceTier.STANDARD) {
      baseOptions.colors.allowCustomColors = true;
      baseOptions.colors.maxCustomColors = 3;
      baseOptions.typography.allowFontChange = true;
      baseOptions.typography.availableFonts.push("Poppins", "Open Sans");
      baseOptions.layout.allowLayoutChange = true;
      baseOptions.layout.availableLayouts.push("wide", "boxed");
      baseOptions.components.allowComponentToggle = true;
    }

    // Plus 티어 모든 기능 허용
    if (tier === ServiceTier.PLUS) {
      baseOptions.colors.allowCustomColors = true;
      baseOptions.colors.maxCustomColors = 10;
      baseOptions.typography.allowFontChange = true;
      baseOptions.typography.allowFontSizeChange = true;
      baseOptions.typography.availableFonts.push(
        "Montserrat",
        "Lato",
        "Playfair Display"
      );
      baseOptions.layout.allowLayoutChange = true;
      baseOptions.layout.allowComponentReordering = true;
      baseOptions.layout.availableLayouts.push("wide", "boxed", "full-width");
      baseOptions.components.allowComponentToggle = true;
      baseOptions.components.allowComponentSettings = true;
      baseOptions.advanced.allowCustomCSS = true;
      baseOptions.advanced.allowThirdPartyIntegrations = true;
    }

    return baseOptions;
  }

  /**
   * 기본 메타데이터 생성
   */
  private createDefaultMetadata(
    tier: ServiceTier,
    config: Partial<BaseTemplate>
  ): TemplateMetadata {
    return {
      version: "1.0.0",
      lastModified: new Date(),
      author: "AgentC Team",
      category: config.metadata?.category || "Business",
      tags: config.metadata?.tags || [
        "responsive",
        "modern",
        tier.toLowerCase(),
      ],
      previewImages: [],
      minimumTier: tier,
      features: this.getTierFeatures(tier),
      compatibility: {
        browsers: ["Chrome 90+", "Firefox 88+", "Safari 14+", "Edge 90+"],
        devices: ["Desktop", "Tablet", "Mobile"],
        frameworks: ["Next.js 15+", "React 18+"],
      },
    };
  }

  /**
   * 티어별 기능 목록 반환
   */
  private getTierFeatures(tier: ServiceTier): string[] {
    const baseFeatures = ["반응형 디자인", "모바일 최적화", "기본 SEO"];

    if (tier === ServiceTier.STANDARD) {
      return [
        ...baseFeatures,
        "고급 커스터마이제이션",
        "컴포넌트 토글",
        "추가 레이아웃",
      ];
    }

    if (tier === ServiceTier.PLUS) {
      return [
        ...baseFeatures,
        "완전한 커스터마이제이션",
        "커스텀 CSS/JS",
        "서드파티 통합",
        "고급 SEO",
      ];
    }

    return baseFeatures;
  }

  /**
   * 티어에 맞게 컴포넌트 필터링
   */
  private filterComponentsForTier(
    components: BaseComponent[],
    tier: ServiceTier
  ): BaseComponent[] {
    const tierRestrictions = componentRegistry.getTierRestrictions(tier);
    return components.filter((component) =>
      tierRestrictions.allowedComponents.includes(component.type)
    );
  }

  /**
   * 티어에 맞게 커스터마이제이션 옵션 업데이트
   */
  private updateCustomizationOptionsForTier(
    options: CustomizationOptions,
    tier: ServiceTier
  ): CustomizationOptions {
    const newOptions = this.createDefaultCustomizationOptions(tier);

    // 기존 설정 중 새 티어에서 허용되는 것들만 유지
    if (tier === ServiceTier.STARTER) {
      // Starter는 기본 설정만 허용
      return newOptions;
    }

    // Standard와 Plus는 기존 설정을 최대한 유지하되 제한사항 적용
    return {
      ...options,
      advanced:
        tier === ServiceTier.PLUS ? options.advanced : newOptions.advanced,
    };
  }

  /**
   * 티어에 맞게 글로벌 설정 업데이트
   */
  private updateGlobalSettingsForTier(
    settings: GlobalTemplateSettings,
    tier: ServiceTier
  ): GlobalTemplateSettings {
    const newSettings = this.createDefaultGlobalSettings(tier);

    // 기존 테마 설정은 유지하되 고급 기능은 티어에 따라 제한
    return {
      ...settings,
      performance:
        tier === ServiceTier.PLUS
          ? settings.performance
          : newSettings.performance,
      seo: tier === ServiceTier.STARTER ? newSettings.seo : settings.seo,
    };
  }

  /**
   * 슬러그 생성
   */
  private generateSlug(name: string): string {
    return name
      .toLowerCase()
      .replace(/[^a-z0-9가-힣]/g, "-")
      .replace(/-+/g, "-")
      .replace(/^-|-$/g, "");
  }

  /**
   * 티어별 기본 설명 반환
   */
  private getDefaultDescription(tier: ServiceTier): string {
    const descriptions = {
      [ServiceTier.STARTER]:
        "시작하기 좋은 기본 템플릿입니다. 필수 기능들로 구성되어 있습니다.",
      [ServiceTier.STANDARD]:
        "향상된 기능과 커스터마이제이션 옵션을 제공하는 표준 템플릿입니다.",
      [ServiceTier.PLUS]:
        "모든 기능과 완전한 커스터마이제이션을 제공하는 프리미엄 템플릿입니다.",
    };
    return descriptions[tier];
  }
}

// 싱글톤 인스턴스 export
export const templateFactory = new AgentCTemplateFactory();
