import { Injectable, inject } from '@angular/core';
import { PageConfig } from '../../shared/models/config';
import { PageRenderModel } from '../page-renderer/page-renderer.model';
import { SectionRendererService } from '../section-renderer/section-renderer.service';
import { PlatformLayoutConfig, PlatformLayoutType } from '../../shared/models/config';
import { SectionConfig } from '../../shared/models/config';
import { ConfigService } from '../../core/config/config.service';

@Injectable({ providedIn: 'root' })
export class SectionEngineService {
  private readonly configService = inject(ConfigService);

  constructor(private readonly sectionRenderer: SectionRendererService) {}

  toPageRenderModel(page: PageConfig): PageRenderModel {
    const layoutType = this.resolveLayoutType(page.layout);

    const sections = this.normalizeSectionsByLayout(page.sections ?? [], layoutType)
      .filter((section) => section.visible !== false)
      .sort((a, b) => a.order - b.order)
      .map((section) => this.sectionRenderer.toRenderNode(section));

    return {
      id: page.id,
      key: page.key,
      title: page.title,
      layout: layoutType,
      sections,
      source: page
    };
  }

  /**
   * Falls back to the site-wide builder setting (bootstrap.layout.type,
   * "Site Layout" in the theme editor) when a page has no layout of its
   * own - previously that global setting was saved but never read by
   * rendering at all, so it had no visible effect.
   */
  private resolveLayoutType(layout: PageConfig['layout']): string {
    if (typeof layout === 'string') {
      return layout;
    }

    const pageLayoutType = (layout as PlatformLayoutConfig)?.type;
    if (pageLayoutType) {
      return pageLayoutType;
    }

    return this.configService.getBootstrapSnapshot()?.layout?.type ?? 'default';
  }

  private normalizeSectionsByLayout(sections: PageConfig['sections'], layoutType: string): PageConfig['sections'] {
    const normalized = [...sections];
    const lowerLayout = (layoutType as PlatformLayoutType).toLowerCase();

    if (lowerLayout === 'minimal') {
      return normalized.filter(section => {
        const type = section.type.toLowerCase();
        return type === 'product-collection' || type === 'products' || type === 'catalog';
      });
    }

    if (lowerLayout === 'sidebar-left') {
      return this.composeSidebarLayout(normalized);
    }

    if (lowerLayout === 'carousel-home') {
      return normalized.sort((left, right) => this.getCarouselPriority(left.type) - this.getCarouselPriority(right.type));
    }

    if (lowerLayout === 'default') {
      return normalized.sort((left, right) => this.getDefaultPriority(left.type) - this.getDefaultPriority(right.type));
    }

    return normalized;
  }

  private getDefaultPriority(type: string): number {
    const normalizedType = type.toLowerCase();
    if (normalizedType === 'categories') return 10;
    if (normalizedType === 'product-collection' || normalizedType === 'products') return 20;
    if (normalizedType === 'hero') return 30;
    return 100;
  }

  private getSidebarPriority(type: string): number {
    const normalizedType = type.toLowerCase();
    if (normalizedType === 'categories') return 10;
    if (normalizedType === 'product-collection' || normalizedType === 'products') return 20;
    if (normalizedType === 'hero') return 30;
    return 100;
  }

  private getCarouselPriority(type: string): number {
    const normalizedType = type.toLowerCase();
    if (normalizedType === 'hero' || normalizedType === 'banner') return 10;
    if (normalizedType === 'product-collection' || normalizedType === 'product-carousel') return 20;
    if (normalizedType === 'categories') return 30;
    return 100;
  }

  private composeSidebarLayout(sections: PageConfig['sections']): PageConfig['sections'] {
    const categoriesSection = sections.find(section => section.type.toLowerCase() === 'categories');
    const productsSection = sections.find(section => {
      const type = section.type.toLowerCase();
      return type === 'product-collection' || type === 'products' || type === 'catalog';
    });

    if (!categoriesSection || !productsSection) {
      return [...sections].sort((left, right) => this.getSidebarPriority(left.type) - this.getSidebarPriority(right.type));
    }

    const combined: SectionConfig = {
      ...categoriesSection,
      id: `${categoriesSection.id}-sidebar-layout`,
      type: 'sidebar-left',
      order: Math.min(categoriesSection.order, productsSection.order),
      layout: {
        strategy: 'grid',
        columns: 2,
        gap: '1.5rem',
        align: 'start'
      },
      widgets: [
        ...categoriesSection.widgets.map((widget, index) => ({
          ...widget,
          order: index,
          padding: widget.padding ?? '0',
          visibility: widget.visibility ?? { desktop: true, tablet: true, mobile: true }
        })),
        ...productsSection.widgets.map((widget, index) => ({
          ...widget,
          order: 100 + index,
          padding: widget.padding ?? '0',
          visibility: widget.visibility ?? { desktop: true, tablet: true, mobile: true }
        }))
      ]
    };

    return [
      combined,
      ...sections.filter(section => section.id !== categoriesSection.id && section.id !== productsSection.id)
    ].sort((left, right) => left.order - right.order);
  }
}