/**
 * @file ProgressBarButtons.tsx
 * @description Component that provides functionality to add and remove progress bars
 * on PowerPoint slides. The progress bars visually indicate the current position within
 * the presentation, with colored segments showing completed and upcoming slides.
 */

import * as React from "react";
import { 
  Button,
  makeStyles
} from "@fluentui/react-components";
import { 
  GaugeRegular,
  DismissRegular
} from "@fluentui/react-icons";
import { useStatusContext } from "./App";
import { useCommonStyles } from "./commonStyles";

// Constants for progress bar configuration
const PROGRESS_BAR_CONFIG = {
  // Standard PowerPoint slide dimensions in points
  slideWidth: 960,
  slideHeight: 540,
  // Progress bar appearance
  barHeight: 1,
  distanceFromBottom: 28,
  overlap: 0.5, // Small overlap to ensure no gaps between segments
  // Colors
  completedColor: "#205170", // Blue for progressed segments (RGB 32, 81, 112)
  pendingColor: "#F2F2F2"    // Grey for segments not yet progressed (RGB 242, 242, 242)
};

// Layouts that should receive progress bars
const SUPPORTED_LAYOUTS = [
  "Title",
  "Content",
  "Two Content",
  "Blank"
];

const useStyles = makeStyles({
  buttonGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: "8px",
    width: "100%"
  },
  progressButton: {
    width: "100%",
    minWidth: 0,
    padding: "8px 4px",
    "& span": {
      justifyContent: "center"
    }
  }
});

export const ProgressBarButtons: React.FC = () => {
  const styles = useStyles();
  const commonStyles = useCommonStyles();
  const { 
    statusMessage, setStatusMessage,
    statusType, setStatusType,
    isProcessing, setIsProcessing
  } = useStatusContext();

  /**
   * Adds a progress bar to the bottom of each slide in the presentation
   * The progress bar shows the current position within the presentation
   * with colored segments indicating progress
   */
  const addProgressBar = async () => {
    setIsProcessing(true);
    const startTime = performance.now();
    
    try {
      await PowerPoint.run(async (context) => {
        // Get all slides at once
        const presentation = context.presentation;
        const slides = presentation.slides;
        slides.load("items");
        
        // Single sync to get all slides
        await context.sync();
        
        if (slides.items.length === 0) {
          throw new Error("No slides in the presentation");
        }
        
        // Calculate dimensions based on slide count
        const { slideWidth, slideHeight, barHeight, distanceFromBottom, overlap } = PROGRESS_BAR_CONFIG;
        const slideCount = slides.items.length;
        const segmentWidth = slideWidth / slideCount;
        const startY = slideHeight - distanceFromBottom;
        
        // Load all slide layouts at once to reduce API calls
        for (let i = 0; i < slideCount; i++) {
          slides.items[i].load("layout");
        }
        
        // Single sync to get all layouts
        await context.sync();
        
        // Process each slide without unnecessary syncs
        for (let i = 0; i < slideCount; i++) {
          const slide = slides.items[i];
          const layoutName = slide.layout.name;
          
          // Check if this is a layout we want to add the progress bar to
          const isCompatibleLayout = SUPPORTED_LAYOUTS.some(layout => 
            layoutName.includes(layout)
          );
          
          if (isCompatibleLayout) {
            // Create all segments for this slide in a batch
            for (let j = 0; j < slideCount; j++) {
              // Calculate segment position and dimensions
              const startX = j * segmentWidth;
              const endX = (j + 1) * segmentWidth;
              
              // Create a rectangle with minimal height to simulate a line
              const segment = slide.shapes.addGeometricShape("Rectangle");
              
              // Set the rectangle's position to look like a line
              segment.left = startX - (j > 0 ? overlap : 0);
              segment.top = startY;
              segment.width = (endX - startX) + (j > 0 ? overlap : 0) + (j < slideCount - 1 ? overlap : 0);
              segment.height = barHeight;
              
              // Set fill color based on progress
              const isCompleted = j <= i;
              segment.fill.setSolidColor(isCompleted ? 
                PROGRESS_BAR_CONFIG.completedColor : 
                PROGRESS_BAR_CONFIG.pendingColor
              );
              
              // Make the current slide indicator slightly more prominent
              if (j == i) {
                segment.width += 1;
              }
              
              // Remove the border/outline entirely
              segment.lineFormat.visible = false;
              
              // Use shape name as identifier for later removal
              segment.name = "progress_bar_" + j;
            }
          }
        }
        
        // Single final sync to commit all changes
        await context.sync();
        
        const endTime = performance.now();
        console.log(`Progress bar creation took ${endTime - startTime}ms`);
        
        setStatusMessage("Added progress bar to slides.");
        setStatusType("success");
      });
    } catch (error) {
      setStatusMessage(`Error: ${error.message}`);
      setStatusType("error");
      console.error("Add progress bar error:", error);
    } finally {
      setIsProcessing(false);
    }
  };
  
  /**
   * Removes all progress bar elements from all slides in the presentation
   * Identifies progress bar elements by their name prefix "progress_bar_"
   */
  const removeProgressBar = async () => {
    setIsProcessing(true);
    const startTime = performance.now();
    
    try {
      await PowerPoint.run(async (context) => {
        // Get all slides at once
        const presentation = context.presentation;
        const slides = presentation.slides;
        slides.load("items");
        await context.sync();
        
        let removedCount = 0;
        const shapesToLoad = [];
        
        // First, load all shapes from all slides in a batch
        for (let i = 0; i < slides.items.length; i++) {
          const slide = slides.items[i];
          const shapes = slide.shapes;
          shapes.load("items");
          shapesToLoad.push({ slide, shapes });
        }
        
        // Single sync to get all shapes
        await context.sync();
        
        // Now load all shape names in a batch
        const allShapesWithNames = [];
        
        for (const { slide, shapes } of shapesToLoad) {
          for (let j = 0; j < shapes.items.length; j++) {
            const shape = shapes.items[j];
            shape.load("name");
            allShapesWithNames.push({ slide, shape });
          }
        }
        
        // Single sync to get all shape names
        await context.sync();
        
        // Filter shapes that are progress bars and delete them
        const progressBarShapes = allShapesWithNames.filter(
          ({ shape }) => shape.name && shape.name.startsWith("progress_bar_")
        );
        
        // Delete all progress bar shapes
        for (const { shape } of progressBarShapes) {
          shape.delete();
          removedCount++;
        }
        
        // Single final sync to commit all deletions
        await context.sync();
        
        const endTime = performance.now();
        console.log(`Progress bar removal took ${endTime - startTime}ms`);
        
        if (removedCount > 0) {
          setStatusMessage(`Removed progress bar from slides.`);
        } else {
          setStatusMessage("No progress bar found to remove.");
        }
        setStatusType("success");
      });
    } catch (error) {
      setStatusMessage(`Error: ${error.message}`);
      setStatusType("error");
      console.error("Remove progress bar error:", error);
    } finally {
      setIsProcessing(false);
    }
  };

  return (
    <div className={commonStyles.container}>
      <div className={styles.buttonGrid}>
        <Button 
          appearance="primary" 
          className={styles.progressButton}
          onClick={addProgressBar} 
          icon={<GaugeRegular />}
          disabled={isProcessing}
          title="Add Progress Bar"
        >
          Add
        </Button>
        <Button 
          appearance="primary" 
          className={styles.progressButton}
          onClick={removeProgressBar} 
          icon={<DismissRegular />}
          disabled={isProcessing}
          title="Remove Progress Bar"
        >
          Remove
        </Button>
      </div>
    </div>
  );
};

export default ProgressBarButtons;
