/**
 * @file DraftButtons.tsx
 * @description Component that provides functionality to add and remove draft watermarks
 * on PowerPoint master slides. The watermarks appear as large, light-colored text
 * across the slide background.
 */

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

/**
 * Configuration constants for draft watermarks
 */
const DRAFT_CONFIG = {
  // Shape name used to identify draft watermarks
  SHAPE_NAME: "DraftWatermark",
  // Font configuration
  FONT: {
    NAME: "Inter",
    SIZE: 54,
    COLOR: "#FFE9E8" // Light pink RGB(255, 233, 232)
  },
  // Text box configuration
  TEXT_BOX: {
    LEFT: -330,
    TOP: 32,
    WIDTH: 2400,
    HEIGHT: 540
  },
  // Watermark text (repeated pattern)
  TEXT: [
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT",
    "DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT"
  ].join("\n")
};

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

/**
 * Interface for master slide processing results
 */
interface ProcessingResult {
  processedMasters: number;
  errorMasters: number;
  affectedCount: number; // Either added or removed watermarks
}

/**
 * DraftButtons component provides UI and functionality to add or remove
 * draft watermarks on PowerPoint master slides.
 * 
 * @returns React component
 */
export const DraftButtons: React.FC = () => {
  const styles = useStyles();
  const commonStyles = useCommonStyles();
  const { 
    setStatusMessage,
    setStatusType,
    isProcessing, 
    setIsProcessing
  } = useStatusContext();

  /**
   * Handles errors and updates the status message
   * 
   * @param error - The error object
   * @param operation - The operation being performed (for logging)
   */
  const handleError = (error: any, operation: string): void => {
    setStatusMessage(`Error: ${error.message || "Unknown error occurred"}`);
    setStatusType("error");
    console.error(`${operation} error:`, error);
    setIsProcessing(false);
  };

  /**
   * Updates the status message based on processing results
   * 
   * @param result - The processing result object
   * @param isAddOperation - Whether this was an add operation (true) or remove operation (false)
   */
  const updateStatusFromResult = (result: ProcessingResult, isAddOperation: boolean): void => {
    const { processedMasters, errorMasters, affectedCount } = result;
    
    if (affectedCount > 0) {
      const action = isAddOperation ? "Added" : "Removed";
      const pluralWatermark = affectedCount > 1 ? 's' : '';
      const pluralMasters = processedMasters > 1 ? 's' : '';
      
      setStatusMessage(`${action} draft watermark${pluralWatermark} to ${processedMasters} master slide${pluralMasters}.`);
      setStatusType("success");
    } else if (errorMasters > 0) {
      const pluralMasters = errorMasters > 1 ? 's' : '';
      setStatusMessage(`Failed to ${isAddOperation ? "add" : "remove"} watermarks. Errors on ${errorMasters} master slide${pluralMasters}.`);
      setStatusType("error");
    } else {
      if (isAddOperation) {
        setStatusMessage("No master slides found to add draft watermark.");
      } else {
        setStatusMessage("No draft watermark found to remove.");
      }
      setStatusType(isAddOperation ? "warning" : "info");
    }
  };

  /**
   * Adds draft watermarks to all master slides in the presentation
   */
  const addDraftWatermark = async (): Promise<void> => {
    setIsProcessing(true);
    try {
      await PowerPoint.run(async (context) => {
        // Get the slide masters collection
        const masters = context.presentation.slideMasters;
        masters.load("items");
        await context.sync();
          
        if (masters.items.length === 0) {
          setStatusMessage("Could not access slide masters.");
          setStatusType("error");
          return;
        }

        const result = await processAddWatermarks(context, masters.items);
        updateStatusFromResult(result, true);
      });
    } catch (error) {
      handleError(error, "Add draft watermark");
    } finally {
      setIsProcessing(false);
    }
  };

  /**
   * Processes all master slides to add draft watermarks
   * 
   * @param context - The PowerPoint API context
   * @param masters - Array of master slides to process
   * @returns Processing result with counts of processed and error slides
   */
  const processAddWatermarks = async (
    context: PowerPoint.RequestContext, 
    masters: PowerPoint.SlideMaster[]
  ): Promise<ProcessingResult> => {
    const result: ProcessingResult = {
      processedMasters: 0,
      errorMasters: 0,
      affectedCount: 0
    };
    
    // Process each slide master (usually there's just one)
    for (let i = 0; i < masters.length; i++) {
      try {
        const master = masters[i];
        
        // Create the textbox on the master slide
        const textBox = master.shapes.addTextBox("");
        
        // Set position and size in a single batch
        textBox.left = DRAFT_CONFIG.TEXT_BOX.LEFT;
        textBox.top = DRAFT_CONFIG.TEXT_BOX.TOP;
        textBox.width = DRAFT_CONFIG.TEXT_BOX.WIDTH;
        textBox.height = DRAFT_CONFIG.TEXT_BOX.HEIGHT;
        textBox.name = DRAFT_CONFIG.SHAPE_NAME;
        
        // Load textFrame to set text properties
        textBox.load("textFrame");
        await context.sync();
        
        if (textBox.textFrame) {
          // Load textRange to set text and properties
          textBox.textFrame.load("textRange");
          await context.sync();
        
          // Set text and load font properties in a single batch
          textBox.textFrame.textRange.text = DRAFT_CONFIG.TEXT;
          textBox.textFrame.textRange.load("font,paragraphFormat");
          await context.sync();
          
          try {
            // Apply all font properties in a single batch
            const font = textBox.textFrame.textRange.font;
            font.name = DRAFT_CONFIG.FONT.NAME;
            font.size = DRAFT_CONFIG.FONT.SIZE;
            font.bold = true;
            font.color = DRAFT_CONFIG.FONT.COLOR;
            
            // Set alignment
            textBox.textFrame.verticalAlignment = "MiddleCentered";
            
            await context.sync();
            result.affectedCount++;
          } catch (fontError) {
            console.error("Error setting font properties:", fontError);
            // Continue with default font if custom font fails
          }
        }
        
        result.processedMasters++;
      } catch (masterError) {
        console.error(`Error processing master ${i+1}:`, masterError);
        result.errorMasters++;
        // Continue to the next master
      }
    }
    
    return result;
  };

  /**
   * Removes draft watermarks from all master slides in the presentation
   */
  const removeDraftWatermark = async (): Promise<void> => {
    setIsProcessing(true);
    try {
      await PowerPoint.run(async (context) => {
        // Get the slide masters collection
        const masters = context.presentation.slideMasters;
        masters.load("items");
        await context.sync();
        
        if (masters.items.length === 0) {
          setStatusMessage("Could not access slide masters.");
          setStatusType("error");
          return;
        }
        
        const result = await processRemoveWatermarks(context, masters.items);
        updateStatusFromResult(result, false);
      });
    } catch (error) {
      handleError(error, "Remove draft watermark");
    } finally {
      setIsProcessing(false);
    }
  };

  /**
   * Processes all master slides to remove draft watermarks
   * 
   * @param context - The PowerPoint API context
   * @param masters - Array of master slides to process
   * @returns Processing result with counts of processed and affected slides
   */
  const processRemoveWatermarks = async (
    context: PowerPoint.RequestContext, 
    masters: PowerPoint.SlideMaster[]
  ): Promise<ProcessingResult> => {
    const result: ProcessingResult = {
      processedMasters: 0,
      errorMasters: 0,
      affectedCount: 0
    };
    
    // Process each master slide
    for (let i = 0; i < masters.length; i++) {
      try {
        const master = masters[i];
        
        // Load all shapes on the master slide
        master.shapes.load("items");
        await context.sync();
        
        // Collect shapes to delete
        const shapesToDelete: PowerPoint.Shape[] = [];
        
        // Load all shape names in a single batch
        for (let j = 0; j < master.shapes.items.length; j++) {
          const shape = master.shapes.items[j];
          shape.load("name");
        }
        
        // Wait for all shape names to load
        await context.sync();
        
        // Now check names and collect shapes to delete
        for (let j = 0; j < master.shapes.items.length; j++) {
          const shape = master.shapes.items[j];
          if (shape.name === DRAFT_CONFIG.SHAPE_NAME) {
            shapesToDelete.push(shape);
          }
        }
        
        // Delete all matching shapes in one batch
        shapesToDelete.forEach(shape => shape.delete());
        result.affectedCount += shapesToDelete.length;
        
        await context.sync();
        result.processedMasters++;
      } catch (masterError) {
        console.error(`Error processing master slide ${i+1}:`, masterError);
        result.errorMasters++;
        // Continue to the next master slide
      }
    }
    
    return result;
  };

  return (
    <div className={commonStyles.container}>
      <div className={styles.buttonGrid}>
        <Button 
          appearance="primary" 
          className={styles.draftButton}
          onClick={addDraftWatermark} 
          icon={<Edit24Regular />}
          disabled={isProcessing}
          title="Add Draft"
        >
          Add
        </Button>
        <Button 
          appearance="primary" 
          className={styles.draftButton}
          onClick={removeDraftWatermark} 
          icon={<DismissRegular />}
          disabled={isProcessing}
          title="Remove Draft"
        >
          Remove
        </Button>
      </div>
    </div>
  );
};

export default DraftButtons;
