import * as React from "react";
import { 
  Button,
  makeStyles,
  Label,
  Slider,
  SpinButton,
  Divider,
  ToggleButton,
  tokens,
  Input
} from "@fluentui/react-components";
import { 
  GridRegular,
  DismissRegular,
  AddRegular,
  LineHorizontal3Regular,
  SplitVerticalRegular,
  GridDotsRegular,
  ArrowResetRegular
} from "@fluentui/react-icons";
import { useStatusContext } from "./App";
import { useCommonStyles } from "./commonStyles";

const useStyles = makeStyles({
  buttonGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: "8px",
    width: "100%",
    marginBottom: "8px"
  },
  gridButton: {
    width: "100%",
    minWidth: 0,
    padding: "8px 4px",
    "& span": {
      justifyContent: "center"
    }
  },
  controlRow: {
    display: "flex",
    alignItems: "center",
    gap: "8px",
    marginBottom: "8px"
  },
  controlLabel: {
    minWidth: "80px",
    marginBottom: "0"
  },
  controlInput: {
    flex: 1,
    "& input[type=number]::-webkit-inner-spin-button, & input[type=number]::-webkit-outer-spin-button": {
      "-webkit-appearance": "none",
      margin: 0
    },
    "& input[type=number]": {
      "-moz-appearance": "textfield"
    }
  },
  guidesContainer: {
    marginTop: "16px"
  },
  guideButtonGrid: {
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: "8px",
    width: "100%",
    marginTop: "8px"
  },
  colorButton: {
    width: "24px",
    height: "24px",
    minWidth: "24px",
    padding: "0",
    border: "1px solid " + tokens.colorNeutralStroke1,
    marginLeft: "8px"
  },
  colorButtonSelected: {
    border: "2px solid " + tokens.colorBrandForeground1
  }
});

type GridColor = "blue" | "red" | "yellow" | "green";

const GRID_PREFIX = "edison_grid_";
const GUIDE_PREFIX = "edison_guide_";

const colorValues = {
  blue: "#4472C4",
  red: "#C00000",
  yellow: "#FFC000",
  green: "#70AD47"
};

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

  // Grid state
  const [gridSpacing, setGridSpacing] = React.useState(50);
  const [gridColor, setGridColor] = React.useState<GridColor>("blue");
  const [gridOpacity, setGridOpacity] = React.useState(30);
  
  // Guidelines state
  const [guidePosition, setGuidePosition] = React.useState(240);
  const [guideDirection, setGuideDirection] = React.useState<"horizontal" | "vertical">("horizontal");
  const [guideColor, setGuideColor] = React.useState<GridColor>("red");

  // Helper function to create a line shape
  const createLineShape = (
    slide: PowerPoint.Slide, 
    startX: number, 
    startY: number, 
    endX: number, 
    endY: number
  ) => {
    // Create a line using alternative approach with a rectangle shape
    const line = slide.shapes.addGeometricShape("Rectangle");
    
    if (startX === endX) {
      // Vertical line
      line.left = startX;
      line.top = startY;
      line.height = endY - startY;
      line.width = 1; // Make it 1pt wide
    } else {
      // Horizontal line
      line.left = startX;
      line.top = startY;
      line.width = endX - startX;
      line.height = 1; // Make it 1pt tall
    }
    
    return line;
  };

  const createGrid = async () => {
    setIsProcessing(true);
    try {
      await PowerPoint.run(async (context) => {
        // Remove any existing grid first
        await removeGrid(false);
        
        // Get the current slide using the selected slides collection
        const selectedSlides = context.presentation.getSelectedSlides();
        selectedSlides.load("items");
        await context.sync();
        
        if (selectedSlides.items.length === 0) {
          throw new Error("No slide selected");
        }
        
        const currentSlide = selectedSlides.items[0];
        
        // Standard dimensions for PowerPoint slides
        const slideWidth = 960; // Width in points
        const slideHeight = 540; // Height in points
        
        // Calculate number of lines needed
        const numHorizontalLines = Math.floor(slideHeight / gridSpacing);
        const numVerticalLines = Math.floor(slideWidth / gridSpacing);
        
        // Create horizontal grid lines
        for (let i = 1; i <= numHorizontalLines; i++) {
          const yPosition = i * gridSpacing;
          
          // Skip if we're at the edge of the slide
          if (yPosition >= slideHeight) continue;
          
          // Create horizontal line
          const line = createLineShape(currentSlide, 0, yPosition, slideWidth, yPosition);
          line.name = `${GRID_PREFIX}h_${i}`;
          
          // Set line properties
          line.fill.setSolidColor(colorValues[gridColor]);
          line.lineFormat.weight = 0.75; // Thin line
          line.lineFormat.visible = false; // No outline, just fill
          
          // Set transparency (opacity is inverse of transparency)
          line.fill.transparency = (100 - gridOpacity) / 100;
        }
        
        // Create vertical grid lines
        for (let i = 1; i <= numVerticalLines; i++) {
          const xPosition = i * gridSpacing;
          
          // Skip if we're at the edge of the slide
          if (xPosition >= slideWidth) continue;
          
          // Create vertical line
          const line = createLineShape(currentSlide, xPosition, 0, xPosition, slideHeight);
          line.name = `${GRID_PREFIX}v_${i}`;
          
          // Set line properties
          line.fill.setSolidColor(colorValues[gridColor]);
          line.lineFormat.weight = 0.75; // Thin line
          line.lineFormat.visible = false; // No outline, just fill
          
          // Set transparency (opacity is inverse of transparency)
          line.fill.transparency = (100 - gridOpacity) / 100;
        }
        
        setStatusMessage("Grid created on current slide");
        setStatusType("success");
      });
    } catch (error) {
      setStatusMessage(`Error: ${error.message}`);
      setStatusType("error");
      console.error("Create grid error:", error);
    } finally {
      setIsProcessing(false);
    }
  };
  
  const removeGrid = async (showStatus = true) => {
    if (showStatus) {
      setIsProcessing(true);
    }
    
    try {
      await PowerPoint.run(async (context) => {
        // Get the current slide using the selected slides collection
        const selectedSlides = context.presentation.getSelectedSlides();
        selectedSlides.load("items");
        await context.sync();
        
        if (selectedSlides.items.length === 0) {
          throw new Error("No slide selected");
        }
        
        const currentSlide = selectedSlides.items[0];
        
        // Load all shapes on this slide
        const shapes = currentSlide.shapes;
        shapes.load("items");
        await context.sync();
        
        // Load all shape names at once
        const allShapes = shapes.items;
        for (let i = 0; i < allShapes.length; i++) {
          allShapes[i].load("name");
        }
        await context.sync();
        
        // Find shapes that are part of our grid and mark them for deletion
        let removedCount = 0;
        for (let i = 0; i < allShapes.length; i++) {
          const shape = allShapes[i];
          // Check if this shape is part of our grid
          if (shape.name && shape.name.startsWith(GRID_PREFIX)) {
            shape.delete();
            removedCount++;
          }
        }
        
        // Single sync after all deletions
        await context.sync();
        
        if (showStatus) {
          if (removedCount > 0) {
            setStatusMessage(`Removed grid from slide`);
          } else {
            setStatusMessage("No grid found to remove");
          }
          setStatusType("success");
        }
      });
    } catch (error) {
      if (showStatus) {
        setStatusMessage(`Error: ${error.message}`);
        setStatusType("error");
      }
      console.error("Remove grid error:", error);
    } finally {
      if (showStatus) {
        setIsProcessing(false);
      }
    }
  };

  const addGuideline = async () => {
    setIsProcessing(true);
    try {
      await PowerPoint.run(async (context) => {
        // Get the current slide using the selected slides collection
        const selectedSlides = context.presentation.getSelectedSlides();
        selectedSlides.load("items");
        await context.sync();
        
        if (selectedSlides.items.length === 0) {
          throw new Error("No slide selected");
        }
        
        const currentSlide = selectedSlides.items[0];
        
        // Standard dimensions for PowerPoint slides
        const slideWidth = 960; // Width in points
        const slideHeight = 540; // Height in points
        
        // Create a unique identifier for this guide
        const timestamp = new Date().getTime();
        const guideId = `${GUIDE_PREFIX}${guideDirection}_${timestamp}`;
        
        // Add the guide line
        let line;
        if (guideDirection === "horizontal") {
          // Create horizontal guideline
          line = createLineShape(currentSlide, 0, guidePosition, slideWidth, guidePosition);
        } else {
          // Create vertical guideline
          line = createLineShape(currentSlide, guidePosition, 0, guidePosition, slideHeight);
        }
        
        line.name = guideId;
        
        // Set line properties
        line.fill.setSolidColor(colorValues[guideColor]);
        line.lineFormat.visible = false; // No outline, just fill
        
        // We want solid lines for guidelines
        line.fill.transparency = 0;
        
        setStatusMessage(`Added ${guideDirection} guideline`);
        setStatusType("success");
      });
    } catch (error) {
      setStatusMessage(`Error: ${error.message}`);
      setStatusType("error");
      console.error("Add guideline error:", error);
    } finally {
      setIsProcessing(false);
    }
  };
  
  const removeGuidelines = async () => {
    setIsProcessing(true);
    try {
      await PowerPoint.run(async (context) => {
        // Get the current slide using the selected slides collection
        const selectedSlides = context.presentation.getSelectedSlides();
        selectedSlides.load("items");
        await context.sync();
        
        if (selectedSlides.items.length === 0) {
          throw new Error("No slide selected");
        }
        
        const currentSlide = selectedSlides.items[0];
        
        // Load all shapes on this slide
        const shapes = currentSlide.shapes;
        shapes.load("items");
        await context.sync();
        
        // Find shapes that are guidelines
        let removedCount = 0;
        for (let i = 0; i < shapes.items.length; i++) {
          const shape = shapes.items[i];
          shape.load("name");
          await context.sync();
          
          // Check if this shape is a guideline
          if (shape.name && shape.name.startsWith(GUIDE_PREFIX)) {
            shape.delete();
            removedCount++;
          }
        }
        
        await context.sync();
        
        if (removedCount > 0) {
          setStatusMessage(`Removed ${removedCount} guidelines`);
        } else {
          setStatusMessage("No guidelines found to remove");
        }
        setStatusType("success");
      });
    } catch (error) {
      setStatusMessage(`Error: ${error.message}`);
      setStatusType("error");
      console.error("Remove guidelines error:", error);
    } finally {
      setIsProcessing(false);
    }
  };

  // Color picker button component
  const ColorButton = ({ color, selectedColor, onClick }: 
    { color: GridColor, selectedColor: GridColor, onClick: (color: GridColor) => void }) => {
    return (
      <Button 
        className={`${styles.colorButton} ${color === selectedColor ? styles.colorButtonSelected : ''}`}
        style={{ backgroundColor: colorValues[color] }}
        onClick={() => onClick(color)}
        title={color.charAt(0).toUpperCase() + color.slice(1)}
      />
    );
  };

  return (
    <div className={commonStyles.container} style={{ maxHeight: "400px", overflowY: "auto" }}>
      {/* Grid Controls */}
      <Label style={{ 
        fontWeight: "600", 
        marginBottom: "12px", 
        fontSize: "16px" 
      }}>
        Grid
      </Label>
      
      <div className={styles.controlRow}>
        <Label className={styles.controlLabel}>Spacing</Label>
        <div style={{ width: "80px", flex: "none" }}>
          <input
            type="text"
            value={gridSpacing}
            onChange={(e) => {
              const newValue = e.target.value;
              const parsed = parseInt(newValue);
              if (newValue === '') {
                setGridSpacing(0);
              } else if (!isNaN(parsed)) {
                setGridSpacing(parsed);
              }
            }}
            onClick={(e) => (e.target as HTMLInputElement).select()}
            style={{ 
              width: "100%", 
              padding: "5px 8px",
              border: "1px solid #d1d1d1",
              borderRadius: "4px",
              fontSize: "14px"
            }}
          />
        </div>
      </div>
      
      <div className={styles.controlRow}>
        <Label className={styles.controlLabel}>Opacity</Label>
        <div style={{ width: "80px", flex: "none" }}>
          <input
            type="text"
            value={gridOpacity}
            onChange={(e) => {
              const newValue = e.target.value;
              const parsed = parseInt(newValue);
              if (newValue === '') {
                setGridOpacity(0);
              } else if (!isNaN(parsed)) {
                setGridOpacity(parsed);
              }
            }}
            onClick={(e) => (e.target as HTMLInputElement).select()}
            style={{ 
              width: "100%", 
              padding: "5px 8px",
              border: "1px solid #d1d1d1",
              borderRadius: "4px",
              fontSize: "14px"
            }}
          />
        </div>
      </div>
      
      <div className={styles.controlRow}>
        <Label className={styles.controlLabel}>Color</Label>
        <div style={{ display: "flex" }}>
          <ColorButton color="blue" selectedColor={gridColor} onClick={setGridColor} />
          <ColorButton color="red" selectedColor={gridColor} onClick={setGridColor} />
          <ColorButton color="yellow" selectedColor={gridColor} onClick={setGridColor} />
          <ColorButton color="green" selectedColor={gridColor} onClick={setGridColor} />
        </div>
      </div>
      
      <div className={styles.buttonGrid} style={{ marginTop: "8px" }}>
        <Button 
          appearance="primary" 
          className={styles.gridButton}
          onClick={createGrid} 
          icon={<GridDotsRegular />}
          disabled={isProcessing}
          title="Create Grid"
        >
          Add
        </Button>
        <Button 
          appearance="primary" 
          className={styles.gridButton}
          onClick={() => removeGrid(true)} 
          icon={<DismissRegular />}
          disabled={isProcessing}
          title="Remove Grid"
        >
          Remove
        </Button>
      </div>
      
      {/* Guidelines Section */}
      <div className={styles.guidesContainer}>
        <Label style={{ 
          fontWeight: "600", 
          marginBottom: "12px", 
          fontSize: "16px" 
        }}>
          Guidelines
        </Label>
        
        <div className={styles.controlRow}>
          <Label className={styles.controlLabel}>Position</Label>
          <div style={{ width: "80px", flex: "none" }}>
            <input
              type="text"
              value={guidePosition}
              onChange={(e) => {
                const newValue = e.target.value;
                const parsed = parseInt(newValue);
                if (newValue === '') {
                  setGuidePosition(0);
                } else if (!isNaN(parsed)) {
                  setGuidePosition(parsed);
                }
              }}
              onClick={(e) => (e.target as HTMLInputElement).select()}
              style={{ 
                width: "100%", 
                padding: "5px 8px",
                border: "1px solid #d1d1d1",
                borderRadius: "4px",
                fontSize: "14px"
              }}
            />
          </div>
        </div>
        
        <div className={styles.controlRow}>
          <Label className={styles.controlLabel}>Type</Label>
          <div style={{ display: "flex", gap: "8px" }}>
            <ToggleButton
              size="small"
              appearance="outline"
              checked={guideDirection === "horizontal"}
              onClick={() => setGuideDirection("horizontal")}
              icon={<LineHorizontal3Regular />}
              style={{ minWidth: "40px", padding: "2px 8px" }}
            >
              Horizontal
            </ToggleButton>
            <ToggleButton
              size="small"
              appearance="outline"
              checked={guideDirection === "vertical"}
              onClick={() => setGuideDirection("vertical")}
              icon={<SplitVerticalRegular />}
              style={{ minWidth: "40px", padding: "2px 8px" }}
            >
              Vertical
            </ToggleButton>
          </div>
        </div>
        
        <div className={styles.controlRow}>
          <Label className={styles.controlLabel}>Color</Label>
          <div style={{ display: "flex" }}>
            <ColorButton color="blue" selectedColor={guideColor} onClick={setGuideColor} />
            <ColorButton color="red" selectedColor={guideColor} onClick={setGuideColor} />
            <ColorButton color="yellow" selectedColor={guideColor} onClick={setGuideColor} />
            <ColorButton color="green" selectedColor={guideColor} onClick={setGuideColor} />
          </div>
        </div>
        
        <div className={styles.guideButtonGrid}>
          <Button 
            appearance="primary" 
            className={styles.gridButton}
            onClick={addGuideline} 
            icon={<AddRegular />}
            disabled={isProcessing}
            title="Add Guideline"
          >
            Add
          </Button>
          <Button 
            appearance="primary" 
            className={styles.gridButton}
            onClick={removeGuidelines} 
            icon={<DismissRegular />}
            disabled={isProcessing}
            title="Remove All Guidelines"
          >
            Remove
          </Button>
        </div>
      </div>
    </div>
  );
};

export default GridGuidelineManager;