/**
 * Canvas Toolbar
 * Drawing tools for canvas editing
 */

let currentTool = 'none';
let brushSize = 10;
let brushColor = '#ffffff';
let brushOpacity = 100;

// Patch tool settings
let patchSize = 30;
let patchBlend = 80;
let patchRadius = 2;
let patchCanvas = null;
let patchCtx = null;
let patchPreviewCircle = null;
let patchSelectionCircle = null;
let patchState = 'select'; // 'select' or 'drag'
let patchSelection = null; // { x, y, size }
let patchDragStart = null;

// Brush tool settings
let brushCanvas = null;
let brushCtx = null;
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let brushCursor = null;

/**
 * Initialize canvas toolbar
 */
function initCanvasToolbar() {
  const toolButtons = document.querySelectorAll('.canvas-tool-btn');
  
  toolButtons.forEach(btn => {
    btn.addEventListener('click', () => {
      const tool = btn.getAttribute('data-tool');
      
      // Toggle: if clicking the same tool, deselect it
      if (currentTool === tool) {
        selectTool('none');
      } else {
        selectTool(tool);
      }
    });
  });
  
  // Brush size slider
  const brushSizeSlider = document.getElementById('brushSizeSlider');
  if (brushSizeSlider) {
    brushSizeSlider.addEventListener('input', (e) => {
      brushSize = parseInt(e.target.value);
      document.getElementById('brushSizeValue').textContent = brushSize + 'px';
    });
  }
  
  // Brush color picker
  const brushColorPicker = document.getElementById('brushColorPicker');
  if (brushColorPicker) {
    brushColorPicker.addEventListener('input', (e) => {
      brushColor = e.target.value;
    });
  }
  
  // Brush opacity slider
  const brushOpacitySlider = document.getElementById('brushOpacitySlider');
  if (brushOpacitySlider) {
    brushOpacitySlider.addEventListener('input', (e) => {
      brushOpacity = parseInt(e.target.value);
      document.getElementById('brushOpacityValue').textContent = brushOpacity + '%';
    });
  }
  
  // Patch tool sliders
  const patchSizeSlider = document.getElementById('patchSizeSlider');
  if (patchSizeSlider) {
    patchSizeSlider.addEventListener('input', (e) => {
      patchSize = parseInt(e.target.value);
      document.getElementById('patchSizeValue').textContent = patchSize + 'px';
      updatePatchPreviewCircle();
    });
  }
  
  const patchBlendSlider = document.getElementById('patchBlendSlider');
  if (patchBlendSlider) {
    patchBlendSlider.addEventListener('input', (e) => {
      patchBlend = parseInt(e.target.value);
      document.getElementById('patchBlendValue').textContent = patchBlend + '%';
    });
  }
  
  const patchRadiusSlider = document.getElementById('patchRadiusSlider');
  if (patchRadiusSlider) {
    patchRadiusSlider.addEventListener('input', (e) => {
      patchRadius = parseFloat(e.target.value);
      document.getElementById('patchRadiusValue').textContent = patchRadius + 'x';
    });
  }
  
  // Initialize patch tool
  initPatchTool();
  
  // Initialize brush tool
  initBrushTool();
  
  // Keyboard shortcuts
  document.addEventListener('keydown', (e) => {
    if (e.target.tagName === 'INPUT') return;
    
    switch(e.key.toLowerCase()) {
      case 'v':
        selectTool('select');
        break;
      case 'b':
        selectTool('brush');
        break;
      case 'j':
        selectTool('patch');
        break;
      case 'e':
        selectTool('eraser');
        break;
    }
  });
  
  console.log('✓ Canvas toolbar initialized');
}

/**
 * Select a tool
 */
function selectTool(tool) {
  currentTool = tool;
  
  // Update button states
  document.querySelectorAll('.canvas-tool-btn').forEach(btn => {
    btn.classList.remove('active');
  });
  
  // Only highlight button if tool is not 'none'
  if (tool !== 'none') {
    const activeBtn = document.querySelector(`[data-tool="${tool}"]`);
    if (activeBtn) {
      activeBtn.classList.add('active');
    }
  }
  
  // Show/hide tool options
  const toolOptionsBrush = document.getElementById('toolOptionsBrush');
  const toolOptionsPatch = document.getElementById('toolOptionsPatch');
  
  if (toolOptionsBrush) toolOptionsBrush.style.display = 'none';
  if (toolOptionsPatch) toolOptionsPatch.style.display = 'none';
  
  if (tool === 'brush' && toolOptionsBrush) {
    toolOptionsBrush.style.display = 'block';
  } else if (tool === 'patch' && toolOptionsPatch) {
    toolOptionsPatch.style.display = 'block';
  }
  
  // Update canvas cursor
  const canvasContent = document.getElementById('canvasContent');
  if (canvasContent) {
    canvasContent.classList.remove('patch-cursor', 'brush-cursor');
    
    if (tool === 'patch') {
      canvasContent.classList.add('patch-cursor');
      showPatchPreviewCircle();
      hideBrushCursor();
    } else if (tool === 'brush') {
      canvasContent.classList.add('brush-cursor');
      showBrushCursor();
      hidePatchPreviewCircle();
      // Update brush canvas position when tool is selected
      if (typeof updateBrushCanvasPosition === 'function') {
        updateBrushCanvasPosition();
      }
    } else {
      // Tool is 'none' or other - hide all cursors
      hidePatchPreviewCircle();
      hideBrushCursor();
      // Reset patch state if it was in drag mode
      if (patchState === 'drag') {
        patchState = 'select';
        patchSelection = null;
        if (patchSelectionCircle) {
          patchSelectionCircle.style.display = 'none';
        }
      }
    }
  }
  
  // Show/hide brush canvas
  if (brushCanvas) {
    brushCanvas.style.display = tool === 'brush' ? 'block' : 'none';
  }
  
  console.log('Selected tool:', tool === 'none' ? 'none (deselected)' : tool);
}

/**
 * Get current tool
 */
function getCurrentTool() {
  return currentTool;
}

/**
 * Get brush settings
 */
function getBrushSettings() {
  return {
    size: brushSize,
    color: brushColor,
    opacity: brushOpacity
  };
}

// Auto-initialize
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initCanvasToolbar);
} else {
  initCanvasToolbar();
}

// Export functions
window.getCurrentTool = getCurrentTool;
window.getBrushSettings = getBrushSettings;
window.selectTool = selectTool;


/**
 * Initialize Patch Tool (Photoshop-style)
 */
function initPatchTool() {
  const imageContainer = document.getElementById('imageContainer');
  const previewImage = document.getElementById('previewImage');
  
  if (!imageContainer || !previewImage) return;
  
  // Create preview circle (for hovering)
  patchPreviewCircle = document.createElement('div');
  patchPreviewCircle.className = 'patch-preview-circle';
  patchPreviewCircle.style.display = 'none';
  document.body.appendChild(patchPreviewCircle);
  
  // Create selection circle (for selected area)
  patchSelectionCircle = document.createElement('div');
  patchSelectionCircle.className = 'patch-selection-circle';
  patchSelectionCircle.style.display = 'none';
  document.body.appendChild(patchSelectionCircle);
  
  let isDragging = false;
  
  // Mouse move
  imageContainer.addEventListener('mousemove', (e) => {
    if (currentTool !== 'patch') return;
    
    const rect = previewImage.getBoundingClientRect();
    const x = e.clientX;
    const y = e.clientY;
    
    if (patchState === 'select' && !isDragging) {
      // Show preview circle
      patchPreviewCircle.style.left = (x - patchSize / 2) + 'px';
      patchPreviewCircle.style.top = (y - patchSize / 2) + 'px';
      patchPreviewCircle.style.width = patchSize + 'px';
      patchPreviewCircle.style.height = patchSize + 'px';
    } else if (patchState === 'drag' && isDragging) {
      // Update selection circle position while dragging
      patchSelectionCircle.style.left = (x - patchSize / 2) + 'px';
      patchSelectionCircle.style.top = (y - patchSize / 2) + 'px';
    }
  });
  
  // Mouse down - start selection or drag
  imageContainer.addEventListener('mousedown', (e) => {
    if (currentTool !== 'patch') return;
    
    const rect = previewImage.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    // Check if click is on image
    if (x >= 0 && x <= rect.width && y >= 0 && y <= rect.height) {
      if (patchState === 'select') {
        // First click: select area to patch
        const scaleX = previewImage.naturalWidth / rect.width;
        const scaleY = previewImage.naturalHeight / rect.height;
        
        patchSelection = {
          x: Math.round(x * scaleX),
          y: Math.round(y * scaleY),
          size: patchSize,
          displayX: e.clientX,
          displayY: e.clientY
        };
        
        // Show selection circle
        patchSelectionCircle.style.left = (e.clientX - patchSize / 2) + 'px';
        patchSelectionCircle.style.top = (e.clientY - patchSize / 2) + 'px';
        patchSelectionCircle.style.width = patchSize + 'px';
        patchSelectionCircle.style.height = patchSize + 'px';
        patchSelectionCircle.style.display = 'block';
        
        // Hide preview circle
        patchPreviewCircle.style.display = 'none';
        
        // Change state to drag
        patchState = 'drag';
        isDragging = true;
        patchDragStart = { x: e.clientX, y: e.clientY };
        
        // Change cursor
        imageContainer.style.cursor = 'move';
      }
    }
  });
  
  // Mouse up - apply patch
  imageContainer.addEventListener('mouseup', (e) => {
    if (currentTool !== 'patch' || patchState !== 'drag' || !isDragging) return;
    
    isDragging = false;
    
    const rect = previewImage.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    // Check if release is on image
    if (x >= 0 && x <= rect.width && y >= 0 && y <= rect.height) {
      // Calculate source position (where we dragged to)
      const scaleX = previewImage.naturalWidth / rect.width;
      const scaleY = previewImage.naturalHeight / rect.height;
      
      const sourceX = Math.round(x * scaleX);
      const sourceY = Math.round(y * scaleY);
      
      // Apply patch from source to selection
      applyPhotoshopPatch(patchSelection.x, patchSelection.y, sourceX, sourceY, patchSize);
    }
    
    // Reset state
    patchState = 'select';
    patchSelection = null;
    patchSelectionCircle.style.display = 'none';
    patchPreviewCircle.style.display = 'block';
    imageContainer.style.cursor = 'crosshair';
  });
  
  // Mouse leave
  imageContainer.addEventListener('mouseleave', () => {
    if (currentTool === 'patch') {
      patchPreviewCircle.style.display = 'none';
      if (patchState === 'drag') {
        // Cancel operation
        patchState = 'select';
        patchSelection = null;
        patchSelectionCircle.style.display = 'none';
        imageContainer.style.cursor = 'crosshair';
      }
    }
  });
  
  // Mouse enter
  imageContainer.addEventListener('mouseenter', () => {
    if (currentTool === 'patch' && patchState === 'select') {
      patchPreviewCircle.style.display = 'block';
    }
  });
}

/**
 * Apply Photoshop-style patch
 * Copy from source area to destination area with blending
 */
function applyPhotoshopPatch(destX, destY, sourceX, sourceY, size) {
  const previewImage = document.getElementById('previewImage');
  if (!previewImage || !previewImage.src) return;
  
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  
  const img = new Image();
  img.crossOrigin = 'anonymous';
  
  img.onload = () => {
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
    
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    
    // Copy and blend from source to destination
    photoshopPatchBlend(imageData, destX, destY, sourceX, sourceY, size, patchBlend);
    
    ctx.putImageData(imageData, 0, 0);
    
    // Update preview image
    previewImage.src = canvas.toDataURL();
    
    // Save to history if available
    if (typeof saveToHistory === 'function') {
      saveToHistory('Patch Tool', { 
        from: { x: sourceX, y: sourceY },
        to: { x: destX, y: destY },
        size: size 
      });
    }
  };
  
  img.onerror = () => {
    console.error('Failed to apply patch');
  };
  
  img.src = previewImage.src;
}

/**
 * Photoshop-style patch blend
 * Copy pixels from source to destination with soft edge blending
 */
function photoshopPatchBlend(imageData, destX, destY, sourceX, sourceY, size, blendStrength) {
  const data = imageData.data;
  const width = imageData.width;
  const height = imageData.height;
  
  const radius = Math.floor(size / 2);
  
  // Create circular mask with soft edges
  for (let dy = -radius; dy <= radius; dy++) {
    for (let dx = -radius; dx <= radius; dx++) {
      const dist = Math.sqrt(dx * dx + dy * dy);
      
      if (dist <= radius) {
        const destPx = destX + dx;
        const destPy = destY + dy;
        const sourcePx = sourceX + dx;
        const sourcePy = sourceY + dy;
        
        // Check bounds
        if (destPx < 0 || destPx >= width || destPy < 0 || destPy >= height) continue;
        if (sourcePx < 0 || sourcePx >= width || sourcePy < 0 || sourcePy >= height) continue;
        
        const destIdx = (destPy * width + destPx) * 4;
        const sourceIdx = (sourcePy * width + sourcePx) * 4;
        
        // Calculate blend weight with soft edge (feathering)
        const edgeFalloff = (Math.cos(dist / radius * Math.PI) + 1) / 2;
        const blendFactor = edgeFalloff * (blendStrength / 100);
        
        // Get source and destination pixels
        const srcR = data[sourceIdx];
        const srcG = data[sourceIdx + 1];
        const srcB = data[sourceIdx + 2];
        
        const dstR = data[destIdx];
        const dstG = data[destIdx + 1];
        const dstB = data[destIdx + 2];
        
        // Blend source into destination
        data[destIdx] = Math.round(dstR * (1 - blendFactor) + srcR * blendFactor);
        data[destIdx + 1] = Math.round(dstG * (1 - blendFactor) + srcG * blendFactor);
        data[destIdx + 2] = Math.round(dstB * (1 - blendFactor) + srcB * blendFactor);
      }
    }
  }
}

/**
 * Show patch preview circle
 */
function showPatchPreviewCircle() {
  if (patchPreviewCircle) {
    patchPreviewCircle.style.display = 'block';
  }
}

/**
 * Hide patch preview circle
 */
function hidePatchPreviewCircle() {
  if (patchPreviewCircle) {
    patchPreviewCircle.style.display = 'none';
  }
}

/**
 * Update patch preview circle size
 */
function updatePatchPreviewCircle() {
  if (patchPreviewCircle) {
    patchPreviewCircle.style.width = patchSize + 'px';
    patchPreviewCircle.style.height = patchSize + 'px';
  }
}

/**
 * Initialize Brush Tool
 */
function initBrushTool() {
  const imageContainer = document.getElementById('imageContainer');
  const previewImage = document.getElementById('previewImage');
  
  if (!imageContainer || !previewImage) return;
  
  // Create brush canvas overlay
  brushCanvas = document.createElement('canvas');
  brushCanvas.id = 'brushCanvas';
  brushCanvas.style.position = 'absolute';
  brushCanvas.style.top = '0';
  brushCanvas.style.left = '0';
  brushCanvas.style.pointerEvents = 'none';
  brushCanvas.style.display = 'none';
  brushCanvas.style.zIndex = '10';
  imageContainer.appendChild(brushCanvas);
  
  brushCtx = brushCanvas.getContext('2d');
  
  // Create brush cursor
  brushCursor = document.createElement('div');
  brushCursor.className = 'brush-cursor-circle';
  brushCursor.style.display = 'none';
  document.body.appendChild(brushCursor);
  
  // Update canvas size and position to match image
  const updateBrushCanvasSize = () => {
    if (previewImage.complete && previewImage.naturalWidth > 0) {
      const rect = previewImage.getBoundingClientRect();
      const containerRect = imageContainer.getBoundingClientRect();
      
      // Only update canvas size if it changed (to avoid clearing)
      if (brushCanvas.width !== previewImage.naturalWidth || brushCanvas.height !== previewImage.naturalHeight) {
        brushCanvas.width = previewImage.naturalWidth;
        brushCanvas.height = previewImage.naturalHeight;
      }
      
      // Canvas display size = scaled image size (already includes zoom)
      brushCanvas.style.width = rect.width + 'px';
      brushCanvas.style.height = rect.height + 'px';
      
      // Position canvas to match image position (already includes zoom offset)
      brushCanvas.style.left = (rect.left - containerRect.left) + 'px';
      brushCanvas.style.top = (rect.top - containerRect.top) + 'px';
      
      // Don't copy transform - rect already includes the scaled size
      brushCanvas.style.transform = 'none';
    }
  };
  
  previewImage.addEventListener('load', updateBrushCanvasSize);
  
  // Update canvas position on zoom or transform changes
  const observer = new MutationObserver(() => {
    if (currentTool === 'brush') {
      updateBrushCanvasSize();
    }
  });
  
  observer.observe(previewImage, {
    attributes: true,
    attributeFilter: ['style']
  });
  
  // Also update on window resize
  window.addEventListener('resize', updateBrushCanvasSize);
  
  // Mouse events for drawing
  let isDrawing = false;
  
  imageContainer.addEventListener('mousedown', (e) => {
    if (currentTool !== 'brush') return;
    
    // Update canvas size/position before drawing
    updateBrushCanvasSize();
    
    const rect = previewImage.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    // Check if click is on image
    if (x >= 0 && x <= rect.width && y >= 0 && y <= rect.height) {
      isDrawing = true;
      
      // Convert to canvas coordinates
      const scaleX = brushCanvas.width / rect.width;
      const scaleY = brushCanvas.height / rect.height;
      
      lastX = x * scaleX;
      lastY = y * scaleY;
      
      // Draw single dot
      drawBrushStroke(lastX, lastY, lastX, lastY);
    }
  });
  
  imageContainer.addEventListener('mousemove', (e) => {
    if (currentTool === 'brush') {
      const rect = previewImage.getBoundingClientRect();
      const x = e.clientX;
      const y = e.clientY;
      const canvasX = e.clientX - rect.left;
      const canvasY = e.clientY - rect.top;
      
      // Check if mouse is within image bounds
      const isInBounds = canvasX >= 0 && canvasX <= rect.width && canvasY >= 0 && canvasY <= rect.height;
      
      // Show/hide cursor based on bounds
      if (isInBounds) {
        brushCursor.style.display = 'block';
        brushCursor.style.left = (x - brushSize / 2) + 'px';
        brushCursor.style.top = (y - brushSize / 2) + 'px';
        brushCursor.style.width = brushSize + 'px';
        brushCursor.style.height = brushSize + 'px';
      } else {
        brushCursor.style.display = 'none';
      }
      
      // Draw if mouse is down and in bounds
      if (isDrawing) {
        if (isInBounds) {
          const scaleX = brushCanvas.width / rect.width;
          const scaleY = brushCanvas.height / rect.height;
          
          const currentX = canvasX * scaleX;
          const currentY = canvasY * scaleY;
          
          drawBrushStroke(lastX, lastY, currentX, currentY);
          
          lastX = currentX;
          lastY = currentY;
        } else {
          // Mouse moved outside image bounds while drawing
          // Stop drawing and apply current strokes
          isDrawing = false;
          applyBrushToImage();
        }
      }
    }
  });
  
  imageContainer.addEventListener('mouseup', () => {
    if (currentTool === 'brush' && isDrawing) {
      isDrawing = false;
      applyBrushToImage();
    }
  });
  
  imageContainer.addEventListener('mouseleave', () => {
    if (currentTool === 'brush') {
      if (isDrawing) {
        isDrawing = false;
        applyBrushToImage();
      }
      brushCursor.style.display = 'none';
    }
  });
  
  imageContainer.addEventListener('mouseenter', () => {
    if (currentTool === 'brush') {
      brushCursor.style.display = 'block';
    }
  });
}

/**
 * Draw brush stroke
 */
function drawBrushStroke(x1, y1, x2, y2) {
  if (!brushCtx) return;
  
  brushCtx.strokeStyle = brushColor;
  brushCtx.lineWidth = brushSize;
  brushCtx.lineCap = 'round';
  brushCtx.lineJoin = 'round';
  brushCtx.globalAlpha = brushOpacity / 100;
  
  brushCtx.beginPath();
  brushCtx.moveTo(x1, y1);
  brushCtx.lineTo(x2, y2);
  brushCtx.stroke();
}

/**
 * Apply brush strokes to image
 */
function applyBrushToImage() {
  const previewImage = document.getElementById('previewImage');
  if (!previewImage || !previewImage.src || !brushCanvas) return;
  
  // Create temporary canvas
  const tempCanvas = document.createElement('canvas');
  const tempCtx = tempCanvas.getContext('2d');
  
  const img = new Image();
  img.crossOrigin = 'anonymous';
  
  img.onload = () => {
    tempCanvas.width = img.width;
    tempCanvas.height = img.height;
    
    // Draw original image
    tempCtx.drawImage(img, 0, 0);
    
    // Draw brush strokes on top
    tempCtx.drawImage(brushCanvas, 0, 0);
    
    // Update preview image
    previewImage.src = tempCanvas.toDataURL();
    
    // Clear brush canvas
    brushCtx.clearRect(0, 0, brushCanvas.width, brushCanvas.height);
    
    // Save to history if available
    if (typeof saveToHistory === 'function') {
      saveToHistory('Brush Tool', { color: brushColor, size: brushSize });
    }
  };
  
  img.onerror = () => {
    console.error('Failed to apply brush');
  };
  
  img.src = previewImage.src;
}

/**
 * Update brush canvas position (global function)
 */
function updateBrushCanvasPosition() {
  const previewImage = document.getElementById('previewImage');
  const imageContainer = document.getElementById('imageContainer');
  
  if (!brushCanvas || !previewImage || !imageContainer) return;
  
  if (previewImage.complete && previewImage.naturalWidth > 0) {
    const rect = previewImage.getBoundingClientRect();
    const containerRect = imageContainer.getBoundingClientRect();
    
    // Only update canvas size if it changed (to avoid clearing)
    if (brushCanvas.width !== previewImage.naturalWidth || brushCanvas.height !== previewImage.naturalHeight) {
      brushCanvas.width = previewImage.naturalWidth;
      brushCanvas.height = previewImage.naturalHeight;
    }
    
    // Canvas display size = scaled image size (already includes zoom)
    brushCanvas.style.width = rect.width + 'px';
    brushCanvas.style.height = rect.height + 'px';
    
    // Position canvas to match image position (already includes zoom offset)
    brushCanvas.style.left = (rect.left - containerRect.left) + 'px';
    brushCanvas.style.top = (rect.top - containerRect.top) + 'px';
    
    // Don't copy transform - rect already includes the scaled size
    brushCanvas.style.transform = 'none';
  }
}

/**
 * Show brush cursor
 */
function showBrushCursor() {
  if (brushCursor) {
    brushCursor.style.display = 'block';
  }
}

/**
 * Hide brush cursor
 */
function hideBrushCursor() {
  if (brushCursor) {
    brushCursor.style.display = 'none';
  }
}

// Export global function
window.updateBrushCanvasPosition = updateBrushCanvasPosition;
