import { Component } from '@angular/core';
import { treeVisualizerService } from './tree-visualizer.service';
import { SiteTreeservice } from './SiteBuilderGrid/SiteTree.service';
import { ActivatedRoute } from '@angular/router';

import { ViewChild } from '@angular/core';
import { trigger, transition, style, animate, state } from '@angular/animations';
// Make sure path is correct

@Component({
  selector: 'app-tree-visualizer',
  templateUrl: './tree-visualizer.component.html',
  styleUrls: ['./tree-visualizer.component.scss'],
  animations: [
    trigger('fadeIn', [
      transition(':enter', [
        style({ opacity: 0 }),
        animate('200ms ease-out', style({ opacity: 1 }))
      ]),
      transition(':leave', [
        animate('200ms ease-in', style({ opacity: 0 }))
      ])
    ]),
    trigger('slideIn', [
      transition(':enter', [
        style({ transform: 'scale(0.9)', opacity: 0 }),
        animate('300ms ease-out', style({ transform: 'scale(1)', opacity: 1 }))
      ]),
      transition(':leave', [
        animate('200ms ease-in', style({ transform: 'scale(0.9)', opacity: 0 }))
      ])
    ]),
    trigger('buttonHover', [
      state('void', style({ transform: 'translateY(0)' })),
      state('hover', style({ transform: 'translateY(-2px)', boxShadow: '0 4px 8px rgba(0,0,0,0.2)' }))
    ]),
    trigger('focusBorder', [
      state('void', style({ borderColor: '#ccc' })),
      state('focus', style({ borderColor: '#1976d2', boxShadow: '0 0 0 2px rgba(25,118,210,0.2)' }))
    ]),
    trigger('pulseOnHover', [
      state('void', style({ backgroundColor: 'transparent' })),
      state('hover', style({ backgroundColor: 'rgba(0,0,0,0.05)' }))
    ])
  ]

})
export class TreeVisualizerComponent {

  activeTab: 'sitemap' | 'wireframe' = 'sitemap';
  showPopup: boolean = false;
  openPopup() {
    this.showPopup = true;
  }
  inputJson: string = `{
    "Login": {
        "Navbar": {},
        "Header Section": "Login form...",
        "Footer": {}
    },
    "Sign Up": {
        "Navbar": {},
        "Header Section": "Create account...",
        "Feature Section": "Get started with a new icard",
        "Children": {
            "Add Icard": {
                "Navbar": {},
                "Header Section": "Add Icard detail",
                "Feature Section": "Enter details to add an icard"
            },
            "Upload Excel": {
                "Navbar": {},
                "Header Section": "Upload student data",
                "Feature Section": "Upload excel file for student data"
            }
        }
    },
    "Icard Details": {
        "Navbar": {},
        "Header Section": "View Icard details",
        "Feature Section": "Enter icard detail to view"
    },
    "Excel Upload": {
        "Navbar": {},
        "Header Section": "Upload excel file for icard data",
        "Feature Section": "Upload excel file and convert it"
    },
    "Icard Template": {
        "Navbar": {},
        "Header Section": "Select Icard template",
        "Feature Section": "Choose a template to replace with uploaded data"
    }
}`;


  suffix1: string = `
    🔁   You are a JSON structure generator for website page hierarchies. 
    You will return only a JSON object in a strictly hierarchical tree structure. Do not include any explanation, text, or markdown formatting like \`\`\`json — just return pure JSON only.
    Each page should be a key. For subpages like "Login", "Projects", or "New Project", nest them under a "Children" key of their parent page.
    Each page must include specific sections as keys (like "Navbar", "Header Section", "Feature Section" etc.) with either an empty object {} or a short description as the value.
    Do not return any explanation, text, or markdown formatting — only return the raw JSON object exactly in this format.
    
    ❌ Do not include:
    - Any explanation before or after the JSON
    - Any markdown formatting like \`\`\` or json
    - Any text like "Here is..." or "Please note..."
    
    ✅ Output must look like this:
    
    {
      "Home": {
        "Navbar": {},
        "Header Section": "Intro...",
        "Children": {
          "Login": {
            "Navbar": {},
            "Header Section": "Login form...",
            "Footer": {}
          }
        }
      }
    }`;
  treeData: any = null;
  rawInputText: string = `make a website , where we can login , sign up.
  inside that there is a menu of icard where we can add a icard detail iacardname, description
  after click this icard inside we upload excel of student data, icard template, after click convert it fetch all data of excel and replace the key value of icard template..`;
  id: number;
  selectedPageRange: string = '5-10'; // 👈 Default value


  constructor(private treeService: treeVisualizerService,
    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);
  }


  // Add these properties to your component class
  isLoading = false;
  showError = false;

  // Method to handle the enhanced generate flow

  generateJsonWithLoading() {
    this.isLoading = true;
    this.showError = false;

    console.log('🔄 Starting generateJsonWithLoading...');

    // Call the actual generateJson method

    const prompt = `
    You are a JSON structure generator for website UI and sitemap hierarchy.

    Your task is to generate a strictly hierarchical JSON tree that represents the full page flow of a website. The root of the tree must always be the "Home" page. Other pages (like Login, Sign Up, Dashboard, etc.) must be nested logically using a "Children" key — never flatten the structure.

    Each page must contain:

    - 4 to 5 meaningful UI sections (e.g., "Header Section", "Form Section", "Feature Section", etc.)
    - A "Navbar" and a "Footer" section (always included on every page)
    - A short, clear description for each section (to support frontend development)

    Constraints:
    - Total number of pages (including nested children) must be between ${this.selectedPageRange}
    - Do NOT create unnecessary or generic pages (e.g., no "Blog", "FAQ", etc.) unless explicitly present in the user flow
    - Pages that appear after user actions (e.g., clicking a card or after login) must be nested under the relevant parent using a "Children" key
    - DO NOT include any standalone section like "FAQ" or "Blog" as top-level pages unless mentioned

    📘 Website Context:
    ${this.rawInputText}



    --- Reference Format (DO NOT COPY; for structure only) ---
    {
      "Home": {
        "Navbar": "...",
        "Header Section": "...",
        "Feature Section": "...",
        "Footer": "...",
        "Children": {
          "About": {
            "Navbar": "...",
            "Header Section": "...",
            "Footer": "..."
          }
        }
      },
      "Services": {
        "Navbar": "...",
        "Content Section": "...",
        "Footer": "..."
      }
    }
    ---

    🚫 DO NOT:
    - Include any explanation, notes, comments, or formatting (like \`\`\` or \`json\`)
    - Do NOT return escaped or markdown-formatted JSON
    - Do NOT wrap the output inside code blocks
    - Do NOT return anything except plain raw JSON

    📤 Output ONLY the final JSON structure — nothing more.
    `;

    const payload = {
      // query: this.rawInputText + '  \n ' + suffix,
      query: prompt,
      conversationId: '677'
    };

    console.log('🚀 Calling LLM with payload:', payload.query);

    this.siteTreeService.callGemini(payload).subscribe({
      next: (res) => {
        console.log('✅ LLM response received:', res);

        if (res && res.responseContent) {
          try {
            let parsedJson = JSON.parse(res.responseContent);
            const topLevelPages = Object.keys(parsedJson);
            let pendingCalls = topLevelPages.length;

            // If no pages to process, just complete
            if (pendingCalls === 0) {
              this.completeGeneration(parsedJson);
              return;
            }

            topLevelPages.forEach(pageName => {
              this.siteTreeService.getDesignLibraryByheader(2, 'template 1', pageName).subscribe({
                next: (designResponse) => {
                  if (designResponse && Object.keys(designResponse).length > 0) {
                    console.log(`✅ Design library found for "${pageName}":`, designResponse.htmljson);

                    try {
                      let raw = designResponse.htmljson;
                      const parsed = typeof raw === 'string' ? JSON.parse(`{${raw}}`) : raw;
                      const firstKey = Object.keys(parsed)[0];
                      const extractedValue = parsed[firstKey];

                      // Preserve existing Children
                      const existingPageData = parsedJson[pageName] || {};
                      const preservedChildren = existingPageData['Children'];

                      // Merge design + preserve Children
                      parsedJson[pageName] = {
                        ...extractedValue,
                        ...(preservedChildren ? { Children: preservedChildren } : {})
                      };

                      console.log(`✅ Merged design for "${pageName}"`);
                    } catch (parseErr) {
                      console.warn(`⚠️ Could not parse design library JSON for "${pageName}":`, parseErr);
                    }
                  } else {
                    console.log(`ℹ️ No design library found for "${pageName}"`);
                  }

                  this.checkAndCompleteGeneration(parsedJson, --pendingCalls);
                },
                error: (err) => {
                  console.error(`❌ Error fetching design library for "${pageName}":`, err);
                  this.checkAndCompleteGeneration(parsedJson, --pendingCalls);
                }
              });
            });

          } catch (err) {
            console.error('❌ Failed to parse LLM JSON:', err);
            this.handleGenerationError('Invalid JSON received from AI');
          }
        } else {
          this.handleGenerationError('No response content received');
        }
      },
      error: (err) => {
        console.error('❌ LLM API Error:', err);
        this.handleGenerationError('Failed to generate site structure');
      }
    });
  }

  // Helper method to check if all calls are complete
  private checkAndCompleteGeneration(parsedJson: any, pendingCalls: number) {
    if (pendingCalls === 0) {
      this.completeGeneration(parsedJson);
    }
  }

  // Helper method to complete the generation process
  private completeGeneration(parsedJson: any) {
    this.inputJson = JSON.stringify(parsedJson);

    const updatePayload = {
      prompt: this.rawInputText + ' ',
      model: this.inputJson
    };

    console.log('✅ Final merged JSON ready, updating server...');

    this.siteTreeService.update(this.id, updatePayload).subscribe({
      next: (resp) => {
        console.log('✅ Successfully updated server:', resp);

        // Success - close popup and show results
        this.isLoading = false;
        this.showPopup = false;
        this.activeTab = 'sitemap';

        // Convert and display the tree
        this.convertJson();

        console.log('🎉 Generation completed successfully!');
      },
      error: (err) => {
        console.error('❌ Failed to update server:', err);
        this.handleGenerationError('Failed to save site structure');
      }
    });
  }

  // Helper method to handle errors
  private handleGenerationError(message: string) {
    console.error('❌ Generation failed:', message);
    this.isLoading = false;
    this.showError = true;
    // Don't close popup so user can retry
  }

  // Enhanced close method
  closePopup() {
    this.showPopup = false;
    this.isLoading = false;
    this.showError = false;
  }

  // Retry method for error state
  retryGeneration() {
    this.showError = false;
    this.generateJsonWithLoading();
  }
  convertJson() {
    try {
      const parsed = JSON.parse(this.inputJson);

      const keys = Object.keys(parsed);

      if (keys.length === 1) {
        // 🟢 Case 1: Only one root key (like: { "Login": { ... } })
        this.treeData = {
          title: keys[0],
          data: parsed[keys[0]]
        };
      } else {
        // 🔵 Case 2: Multiple root keys (like: { "Login": {...}, "Signup": {...}, ... })
        this.treeData = {
          title: 'App',
          data: {
            Children: parsed
          }
        };
      }

      console.log('✅ Final treeData:', this.treeData);
    } catch (e) {
      alert('❌ Invalid JSON format');
      console.error(e);
    }
  }

  // convertJson() {
  //   try {
  //     const parsed = JSON.parse(this.inputJson);
  //     const rootKey = Object.keys(parsed)[0];

  //     console.log(' root key  ', rootKey)
  //     this.treeData = {
  //       title: rootKey,
  //       data: parsed[rootKey]
  //     };

  //     console.log(' tree data ', this.treeData)
  //   } catch (e) {
  //     alert('Invalid JSON');
  //   }
  // }

  isWireframeLoaded = false;

  generateWireframe() {
    this.activeTab = 'wireframe';
    this.isWireframeLoaded = true;

  }

  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 [];
  }

  generateJson() {
    console.log('genearte json start  ')

    const prompt = `
    You are a JSON structure generator for website UI and sitemap hierarchy.

Your task is to generate a strictly hierarchical JSON tree that represents the entire page flow of a website. The root of the tree must always be the "Home" page. All other pages (like Login, Sign Up, Dashboard, etc.) must be nested as subpages using a "Children" key under their logical parent based on the described user flow — do not flatten the structure.

Each page must include meaningful UI sections as keys — such as "Navbar", "Header Section", "Feature Section", "Form Section", "Footer", etc.  
Each section must include a short, clear description of its purpose or content — this helps frontend development.



Constraints:
- Total number of pages must be between ${this.selectedPageRange}, including nested subpages.
- Each page must include 4 to 5 meaningful UI sections like "Navbar", "Header Section", "Feature Section", "Form Section", "Footer", etc.
- Do not flatten the structure — pages that come after actions (e.g., after login or click) must be nested under "Children" of their logical parent.
- Do not invent extra pages not needed by the flow.

📘 Website Context:


${this.rawInputText}
---

💡 Reference Format Only — DO NOT COPY below content. It's here to show the format and structure style.

{
  "Home": {
    "Navbar": "Top navigation with logo, links to all main pages, and call-to-action button",
    "Header Section": "Headline with subheading and call-to-action button",
    "Feature Section": "Three features highlighted with icons and descriptions",
    "Testimonial Section": "Customer reviews in carousel layout",
    "Footer": "Footer with navigation links, social icons, and legal page links",
    "Children": {
      "About": {
        "Header Section": "Intro about company mission and values",
        "Team Section": "Photos and bios of core team members"
      },
      "Services": {
        "Header Section": "List of core services offered",
        "Pricing Section": "Cards with service pricing and features"
      },
      "Contact": {
        "Header Section": "Contact form with name, email, and message fields",
        "Map Section": "Google Maps iframe showing location"
      }
    }
  },
  "Privacy Policy": {
    "Content Section": "Full legal description of data usage and user rights"
  },
  "Terms and Conditions": {
    "Content Section": "Rules and legal terms for using the site or service"
  }
}

---

📤 Now generate the actual website structure JSON for the iCard website described above.

🚫 Do NOT:
- Include any explanation, comments, or headings
- Wrap the output in code blocks (no \`\`\` or \`json\`)
- Copy any part of the example above
- Include markdown formatting

✅ Only return raw JSON output — reflecting the new website's structure and UI flow.

    
  `;


    const payload = {
      // query: this.rawInputText + '  \n ' + suffix,
      query: prompt,

      conversationId: '677'
    };

    console.log(' query : ', payload.query)

    this.siteTreeService.callGemini(payload).subscribe({
      next: (res) => {

        console.log('llm response ', res)

        if (res && res.responseContent) {
          // this.inputJson = res.responseContent;
          // console.log('input json ', this.inputJson)
          // 🔁 Now call update API
          // const updatePayload = {
          //   prompt: this.rawInputText + ' ',
          //   model: this.inputJson  // model format expected by backend
          // console.log('payload : ', updatePayload);


          try {
            let parsedJson = JSON.parse(res.responseContent); // Parse LLM JSON
            const topLevelPages = Object.keys(parsedJson);
            let pendingCalls = topLevelPages.length;

            topLevelPages.forEach(pageName => {
              this.siteTreeService.getDesignLibraryByheader(2, 'template 1', pageName).subscribe({
                next: (designResponse) => {
                  if (designResponse && Object.keys(designResponse).length > 0) {
                    console.log(`✅ Replacing "${pageName}" with design library JSON that is : `, designResponse.htmljson);


                    // try {
                    //   // Parse the stringified JSON if necessary
                    //   let raw = designResponse.htmljson;

                    //   // If it's a string, parse it
                    //   const parsed = typeof raw === 'string' ? JSON.parse(`{${raw}}`) : raw;

                    //   // Automatically extract the first key’s value (usually same as pageName)
                    //   const firstKey = Object.keys(parsed)[0];
                    //   const extractedValue = parsed[firstKey];

                    //   console.log(`✅ Extracted value for "${pageName}":`, extractedValue);

                    //   // Replace just the content, not the outer key
                    //   parsedJson[pageName] = extractedValue;

                    //   console.log(`✅ after  Replaced "${pageName}" jso is  : `, parsedJson);

                    // } catch (parseErr) {
                    //   console.warn(`⚠️ Could not parse design library JSON for "${pageName}". Keeping original.`);
                    // }


                    try {
                      let raw = designResponse.htmljson;

                      // Parse the raw string into object if necessary
                      const parsed = typeof raw === 'string' ? JSON.parse(`{${raw}}`) : raw;

                      // Extract the first key’s value (actual page content)
                      const firstKey = Object.keys(parsed)[0];
                      const extractedValue = parsed[firstKey];

                      // Get existing Children (if any) before replacing
                      const existingPageData = parsedJson[pageName] || {};
                      const preservedChildren = existingPageData['Children'];

                      // Merge: use extractedValue + put Children back
                      parsedJson[pageName] = {
                        ...extractedValue,
                        ...(preservedChildren ? { Children: preservedChildren } : {})
                      };

                      console.log(`✅ Merged design + preserved Children for "${pageName}"`, parsedJson[pageName]);

                    } catch (parseErr) {
                      console.warn(`⚠️ Could not parse design library JSON for "${pageName}". Keeping original.`, parseErr);
                    }

                  } else {
                    console.log(`ℹ️ No design library found for "${pageName}", keeping original`);
                  }
                  checkAndUpload();
                },
                error: (err) => {
                  console.error(`❌ Error fetching design library for "${pageName}":`, err);
                  checkAndUpload(); // Still proceed
                }
              });
            });

            const checkAndUpload = () => {
              pendingCalls--;
              if (pendingCalls === 0) {
                this.inputJson = JSON.stringify(parsedJson);
                const updatePayload = {
                  prompt: this.rawInputText + ' ',
                  model: this.inputJson
                };

                console.log('✅ Final merged JSON ready:', 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');
                  }
                });
              }
            };
          } catch (err) {
            console.error('❌ Failed to parse LLM JSON:', err);
            alert('Invalid JSON received from LLM');
          }
        }
      },
      error: (err) => {
        console.error('API Error:', err);
        alert('Failed to fetch JSON from API');
      }
    });
  }

  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.inputJson = JSON.stringify(maybeParsed, null, 2);
            this.convertJson(); // 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');
      }
    });
  }


}