import { Component, Input } from '@angular/core';
import { OnInit } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { SiteTreeservice } from '../SiteBuilderGrid/SiteTree.service';
import { ActivatedRoute } from '@angular/router';


interface Section {
  type: string;
  content: string;
}

interface Page {
  name: string;
  sections: Section[];
  children?: Page[];
}

interface SiteStructure {
  pages: Page[];
}

@Component({
  selector: 'app-tree-node',
  templateUrl: './tree-node.component.html',
  styleUrls: ['./tree-node.component.css']
})
export class TreeNodeComponent implements OnInit {

  @Input() node: any;
  showJsonInput = true;
  jsonInput = '';
  errorMessage = '';
  siteStructure: SiteStructure = { pages: [] };
  rootPage: Page | null = null;
  selectedPage: Page | null = null;
  selectedSection: Section | null = null;
  editMode: 'page' | 'section' | null = null;
  currentOutputJson = '';

  // Form controls
  newSectionType = '';
  newSectionContent = '';
  newPageName = '';
  showAddChildForm = false;
  id: number;


  constructor(
    private siteTreeService: SiteTreeservice,
    private route: ActivatedRoute,

  ) { }

  ngOnInit(): void {
    this.id = this.route.snapshot.params['id'];

    console.log(' id is :  ', this.id)

    this.fetchTreeById(this.id);
  }
  // Will be populated dynamically from incoming JSON
  availableSectionTypes: string[] = [];


  getSections(data: any): { title: string, description: string }[] {
    const sections: { title: string, description: string }[] = [];
    for (const key in data) {
      if (key !== 'Children' && typeof data[key] === 'string') {
        sections.push({ title: key, description: data[key] });
      }
      if (key !== 'Children' && Array.isArray(data[key])) {
        sections.push({ title: key, description: data[key].join('\n') });
      }
    }
    return sections;
  }

  getChildren(data: any): any[] {
    if (data.Children) {
      return Object.keys(data.Children).map((key) => ({
        title: key,
        data: data.Children[key]
      }));
    }
    return [];
  }


  // Code by harsh




  fetchTreeById(id: number) {
    this.siteTreeService.getById(id).subscribe({
      next: (res) => {
        console.log('📥 Fetched from getById:', res);

        // Check if model key exists and has some value
        if (res && res.model) {
          try {
            // Optional: if model is already a stringified JSON
            const maybeParsed = typeof res.model === 'string' ? JSON.parse(res.model) : res.model;
            this.jsonInput = JSON.stringify(maybeParsed, null, 2);
            this.parseJsonInput(); // convert it immediately
          } catch (err) {
            console.error('❌ Error parsing model JSON:', err);
            alert('Model data is not valid JSON format');
          }
        } else {
          console.warn('⚠️ Model key not found or empty, keeping inputJson as is.');
        }
      },
      error: (err) => {
        console.error('❌ Error in getById:', err);
        alert('Failed to fetch data from server');
      }
    });
  }


  parseJsonInput(): void {
    try {
      const parsedData = JSON.parse(this.jsonInput);

      // Transform the nested JSON format to our page structure
      if (parsedData && typeof parsedData === 'object') {
        this.siteStructure = { pages: [] };
        this.rootPage = {
          name: 'Primary Sitemap',
          sections: [],
          children: []
        };

        // Collect all section types dynamically
        this.availableSectionTypes = [];
        this.availableSectionTypes.push('callToAction');


        // Process the root level objects (Home, etc.)
        Object.keys(parsedData).forEach(pageName => {
          const pageData = parsedData[pageName];
          const page: Page = {
            name: pageName,
            sections: this.extractSections(pageData),
            children: []
          };

          // Process children if they exist
          if (pageData.Children) {
            Object.keys(pageData.Children).forEach(childName => {
              const childData = pageData.Children[childName];
              const childPage: Page = {
                name: childName,
                sections: this.extractSections(childData),
                children: []
              };

              // Process grandchildren if they exist
              if (childData.Children) {
                Object.keys(childData.Children).forEach(grandchildName => {
                  const grandchildData = childData.Children[grandchildName];
                  const grandchildPage: Page = {
                    name: grandchildName,
                    sections: this.extractSections(grandchildData),
                  };
                  childPage.children?.push(grandchildPage);
                });
              }

              page.children?.push(childPage);
            });
          }

          this.rootPage?.children?.push(page);
        });

        this.siteStructure.pages.push(this.rootPage);
        this.showJsonInput = false;
        this.errorMessage = '';

        // Generate initial output JSON
        this.updateOutputJson();
      } else {
        this.errorMessage = 'Invalid JSON structure';
      }
    } catch (e) {
      this.errorMessage = 'Invalid JSON format: ' + (e as Error).message;
    }
  }

  // Extract sections from page data and collect section types
  extractSections(pageData: any): Section[] {
    const sections: Section[] = [];

    Object.keys(pageData).forEach(key => {
      // Skip the Children key as it's not a section
      if (key !== 'Children') {
        const value = pageData[key];

        // Add to available section types if not already included
        if (!this.availableSectionTypes.includes(key)) {
          this.availableSectionTypes.push(key);
        }

        // Handle array of sections
        if (Array.isArray(value)) {
          sections.push({
            type: key,
            content: value.join('\n')
          });
        }
        // Handle object sections with empty content
        else if (typeof value === 'object' && value !== null) {
          sections.push({
            type: key,
            content: JSON.stringify(value)
          });
        }
        // Handle string content
        else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
          sections.push({
            type: key,
            content: String(value)
          });
        }
      }
    });

    return sections;
  }

  resetEditor(): void {
    this.rootPage = null;
    this.siteStructure = { pages: [] };
    this.selectedPage = null;
    this.selectedSection = null;
    this.editMode = null;
    this.showJsonInput = true;
    this.jsonInput = '';
    this.errorMessage = '';
    this.availableSectionTypes = [];
    this.currentOutputJson = '';
  }

  updateOutputJson(): void {
    if (this.rootPage) {
      const output = this.transformToNestedJson();
      this.currentOutputJson = JSON.stringify(output, null, 2);

      console.log('updtae json output ', this.currentOutputJson);

      // 🔁 Now call update API
      const updatePayload = {
        model: this.currentOutputJson  // model format expected by backend
      };

      console.log('payload : ', updatePayload);
      this.siteTreeService.update(this.id, updatePayload).subscribe({
        next: (resp) => {
          console.log('✅ JSON updated on server:', resp);
        },
        error: (err) => {
          console.error('❌ Failed to update JSON on server:', err);
          alert('Update to server failed');
        }
      });
    } else {
      this.currentOutputJson = '';
    }
  }

  downloadJson(): void {
    if (this.rootPage) {
      const output = this.transformToNestedJson();
      const dataStr = JSON.stringify(output, null, 2);
      const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);

      const exportName = 'site-structure.json';
      const linkElement = document.createElement('a');
      linkElement.setAttribute('href', dataUri);
      linkElement.setAttribute('download', exportName);
      linkElement.click();
    }
  }

  // Transform our page structure back to the nested JSON format
  transformToNestedJson(): any {
    const result: any = {};

    // Process only the first level (Home)
    if (this.rootPage && this.rootPage.children && this.rootPage.children.length > 0) {
      this.rootPage.children.forEach(page => {
        result[page.name] = {};

        // Add sections
        page.sections.forEach(section => {
          // Try to parse content as JSON if it looks like JSON
          if (section.content.trim().startsWith('{') && section.content.trim().endsWith('}')) {
            try {
              result[page.name][section.type] = JSON.parse(section.content);
            } catch (e) {
              result[page.name][section.type] = section.content || {};
            }
          }
          // Try to parse as array if it looks like array
          else if (section.content.trim().startsWith('[') && section.content.trim().endsWith(']')) {
            try {
              result[page.name][section.type] = JSON.parse(section.content);
            } catch (e) {
              result[page.name][section.type] = section.content || [];
            }
          }
          // Handle numeric values
          else if (!isNaN(Number(section.content)) && section.content.trim() !== '') {
            result[page.name][section.type] = Number(section.content);
          }
          // Handle boolean values
          else if (section.content.trim() === 'true' || section.content.trim() === 'false') {
            result[page.name][section.type] = section.content.trim() === 'true';
          }
          // Default to string
          else {
            result[page.name][section.type] = section.content || "";
          }
        });

        // Add children
        if (page.children && page.children.length > 0) {
          result[page.name]['Children'] = {};

          page.children.forEach(childPage => {
            result[page.name]['Children'][childPage.name] = {};

            // Add child sections
            childPage.sections.forEach(section => {
              // Try to parse content as JSON if it looks like JSON
              if (section.content.trim().startsWith('{') && section.content.trim().endsWith('}')) {
                try {
                  result[page.name]['Children'][childPage.name][section.type] = JSON.parse(section.content);
                } catch (e) {
                  result[page.name]['Children'][childPage.name][section.type] = section.content || {};
                }
              }
              // Try to parse as array if it looks like array
              else if (section.content.trim().startsWith('[') && section.content.trim().endsWith(']')) {
                try {
                  result[page.name]['Children'][childPage.name][section.type] = JSON.parse(section.content);
                } catch (e) {
                  result[page.name]['Children'][childPage.name][section.type] = section.content || [];
                }
              }
              // Handle numeric values
              else if (!isNaN(Number(section.content)) && section.content.trim() !== '') {
                result[page.name]['Children'][childPage.name][section.type] = Number(section.content);
              }
              // Handle boolean values
              else if (section.content.trim() === 'true' || section.content.trim() === 'false') {
                result[page.name]['Children'][childPage.name][section.type] = section.content.trim() === 'true';
              }
              // Default to string
              else {
                result[page.name]['Children'][childPage.name][section.type] = section.content || "";
              }
            });

            // Add grandchildren
            if (childPage.children && childPage.children.length > 0) {
              result[page.name]['Children'][childPage.name]['Children'] = {};

              childPage.children.forEach(grandchildPage => {
                result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name] = {};

                // Add grandchild sections
                grandchildPage.sections.forEach(section => {
                  // Try to parse content as JSON if it looks like JSON
                  if (section.content.trim().startsWith('{') && section.content.trim().endsWith('}')) {
                    try {
                      result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = JSON.parse(section.content);
                    } catch (e) {
                      result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = section.content || {};
                    }
                  }
                  // Try to parse as array if it looks like array
                  else if (section.content.trim().startsWith('[') && section.content.trim().endsWith(']')) {
                    try {
                      result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = JSON.parse(section.content);
                    } catch (e) {
                      result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = section.content || [];
                    }
                  }
                  // Handle numeric values
                  else if (!isNaN(Number(section.content)) && section.content.trim() !== '') {
                    result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = Number(section.content);
                  }
                  // Handle boolean values
                  else if (section.content.trim() === 'true' || section.content.trim() === 'false') {
                    result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = section.content.trim() === 'true';
                  }
                  // Default to string
                  else {
                    result[page.name]['Children'][childPage.name]['Children'][grandchildPage.name][section.type] = section.content || "";
                  }
                });
              });
            }
          });
        }
      });
    }

    return result;
  }

  selectPage(page: Page): void {
    this.selectedPage = page;
    this.selectedSection = null;
    this.editMode = 'page';
  }

  selectSection(section: Section): void {
    this.selectedSection = section;
    this.editMode = 'section';
  }

  addSectionToPage(page: Page): void {
    if (this.newSectionType && page) {
      // Create new section type if it doesn't exist
      if (!this.availableSectionTypes.includes(this.newSectionType)) {
        this.availableSectionTypes.push(this.newSectionType);
      }

      page.sections.push({
        type: this.newSectionType,
        content: this.newSectionContent || ""
      });

      this.newSectionType = '';
      this.newSectionContent = '';

      // Update JSON output
      this.updateOutputJson();
    }
  }

  updatePage(): void {
    // Already updated via ngModel binding
    this.updateOutputJson();
  }

  updateSection(): void {
    // Already updated via ngModel binding
    this.updateOutputJson();
  }

  addChildPage(parentPage: Page): void {
    if (!this.newPageName) return;

    if (!parentPage.children) {
      parentPage.children = [];
    }

    parentPage.children.push({
      name: this.newPageName,
      sections: []
    });

    this.newPageName = '';
    this.updateOutputJson();
  }

  addSectionType(): void {
    if (this.newSectionType && !this.availableSectionTypes.includes(this.newSectionType)) {
      this.availableSectionTypes.push(this.newSectionType);
    }
  }

  deletePage(page: Page, parentPage: Page | null): void {
    if (parentPage && parentPage.children) {
      const index = parentPage.children.indexOf(page);
      if (index > -1) {
        parentPage.children.splice(index, 1);

        // Reset selection if deleting selected page
        if (this.selectedPage === page) {
          this.selectedPage = null;
          this.editMode = null;
        }

        this.updateOutputJson();
      }
    }
  }

  deleteSection(section: Section, page: Page): void {
    const index = page.sections.indexOf(section);
    if (index > -1) {
      page.sections.splice(index, 1);

      // Reset selection if deleting selected section
      if (this.selectedSection === section) {
        this.selectedSection = null;
        this.editMode = null;
      }

      this.updateOutputJson();
    }
  }

  onPageDrop(event: CdkDragDrop<Page[]>, parentPage: Page): void {
    if (parentPage.children) {
      moveItemInArray(parentPage.children, event.previousIndex, event.currentIndex);
      this.updateOutputJson();
    }
  }

  onSectionDrop(event: CdkDragDrop<Section[]>, page: Page): void {
    moveItemInArray(page.sections, event.previousIndex, event.currentIndex);
    this.updateOutputJson();
  }

  getParentPage(childPage: Page | null): Page | null {
    if (!this.rootPage || !childPage) return null;

    // Check all levels recursively
    return this.findParentPageRecursive(this.rootPage, childPage);
  }

  findParentPageRecursive(currentPage: Page, targetPage: Page): Page | null {
    if (!currentPage.children) return null;

    // Check direct children
    if (currentPage.children.includes(targetPage)) {
      return currentPage;
    }

    // Check nested children
    for (const child of currentPage.children) {
      const result = this.findParentPageRecursive(child, targetPage);
      if (result) return result;
    }

    return null;
  }

  canAddChildPage(page: Page | null): boolean {
    if (!page) return false;

    // Root can have unlimited children in dynamic mode
    if (page === this.rootPage) {
      return true;
    }

    // First level children can have children
    const pageLevel = this.getPageLevel(page);
    if (pageLevel === 1) {
      return true;
    }

    // Second level children can't have children
    return pageLevel < 2;
  }

  getPageLevel(page: Page): number {
    if (page === this.rootPage) return 0;

    let currentPage = page;
    let level = 0;

    while (currentPage !== this.rootPage) {
      const parent = this.getParentPage(currentPage);
      if (!parent) break;

      level++;
      currentPage = parent;
    }

    return level;
  }

  getHomePageFromRoot(): Page | null {
    return this.rootPage?.children?.[0] || null;
  }

  getChildrenPages(parentPageName: string): Page[] {
    const parentPage = this.findPageByName(parentPageName);
    return parentPage?.children || [];
  }

  findPageByName(name: string): Page | null {
    if (!this.rootPage) return null;

    return this.findPageByNameRecursive(this.rootPage, name);
  }

  findPageByNameRecursive(currentPage: Page, name: string): Page | null {
    if (currentPage.name === name) return currentPage;

    if (!currentPage.children) return null;

    for (const child of currentPage.children) {
      const result = this.findPageByNameRecursive(child, name);
      if (result) return result;
    }

    return null;
  }

  hasChildPages(page: Page | null): boolean {
    return !!page?.children && page.children.length > 0;
  }

  getSectionContentPreview(content: string): string {
    return content?.length > 50 ? content.slice(0, 50) + '...' : content || '';
  }
}