/**
 * Crossroad characters for different line intersections
 */
const CROSSROAD_CHARS = {
  single: {
    cross: '┼',      // All 4 directions
    tTop: '┴',       // Left, Right, Up (T pointing up)
    tBottom: '┬',    // Left, Right, Down (T pointing down)
    tLeft: '┤',      // Up, Down, Left (T pointing left)
    tRight: '├',     // Up, Down, Right (T pointing right)
    horizontal: '─', // Left, Right only
    vertical: '│',   // Up, Down only
    cornerTL: '┌',   // Top-left corner (Down, Right)
    cornerTR: '┐',   // Top-right corner (Down, Left)
    cornerBL: '└',   // Bottom-left corner (Up, Right)
    cornerBR: '┘'    // Bottom-right corner (Up, Left)
  },
  double: {
    cross: '╬',
    tTop: '╩',
    tBottom: '╦',
    tLeft: '╣',
    tRight: '╠',
    horizontal: '═',
    vertical: '║',
    cornerTL: '╔',
    cornerTR: '╗',
    cornerBL: '╚',
    cornerBR: '╝'
  }
};

/**
 * Detect crossroads and return a map of positions to junction characters
 * @param {Array} elements - Array of report elements (text, frame, hline, vline)
 * @returns {Object} - Map of 'x,y' positions to junction characters
 */
export function detectCrossroads(elements) {
  // Build occupancy map: { 'x,y': { up, down, left, right, style } }
  const occupancyMap = {};

  // Process each element and mark occupied positions
  elements.forEach(element => {
    if (element.type === 'hline') {
      // Horizontal line occupies positions from x to x+length
      for (let i = 0; i < element.length; i++) {
        const x = element.x + i;
        const y = element.y;
        const key = `${x},${y}`;

        if (!occupancyMap[key]) {
          occupancyMap[key] = { up: false, down: false, left: false, right: false, styles: [] };
        }

        // Horizontal line means left and right connections
        if (i > 0) occupancyMap[key].left = true;
        if (i < element.length - 1) occupancyMap[key].right = true;

        occupancyMap[key].styles.push(element.lineStyle || 'single');
      }
    } else if (element.type === 'vline') {
      // Vertical line occupies positions from y to y+length
      for (let i = 0; i < element.length; i++) {
        const x = element.x;
        const y = element.y + i;
        const key = `${x},${y}`;

        if (!occupancyMap[key]) {
          occupancyMap[key] = { up: false, down: false, left: false, right: false, styles: [] };
        }

        // Vertical line means up and down connections
        if (i > 0) occupancyMap[key].up = true;
        if (i < element.length - 1) occupancyMap[key].down = true;

        occupancyMap[key].styles.push(element.lineStyle || 'single');
      }
    } else if (element.type === 'frame') {
      // Frame has borders on all edges
      const { x, y, width, height, borderStyle } = element;
      const style = borderStyle || 'single';

      for (let row = 0; row < height; row++) {
        for (let col = 0; col < width; col++) {
          const posX = x + col;
          const posY = y + row;
          const key = `${posX},${posY}`;

          // Only process border positions (edges of frame)
          const isTopEdge = row === 0;
          const isBottomEdge = row === height - 1;
          const isLeftEdge = col === 0;
          const isRightEdge = col === width - 1;

          if (isTopEdge || isBottomEdge || isLeftEdge || isRightEdge) {
            if (!occupancyMap[key]) {
              occupancyMap[key] = { up: false, down: false, left: false, right: false, styles: [] };
            }

            // Determine connections based on position in frame
            if (isTopEdge && col > 0 && col < width - 1) {
              occupancyMap[key].left = true;
              occupancyMap[key].right = true;
            }
            if (isBottomEdge && col > 0 && col < width - 1) {
              occupancyMap[key].left = true;
              occupancyMap[key].right = true;
            }
            if (isLeftEdge && row > 0 && row < height - 1) {
              occupancyMap[key].up = true;
              occupancyMap[key].down = true;
            }
            if (isRightEdge && row > 0 && row < height - 1) {
              occupancyMap[key].up = true;
              occupancyMap[key].down = true;
            }

            // Corners
            if (isTopEdge && isLeftEdge) {
              occupancyMap[key].right = true;
              occupancyMap[key].down = true;
            }
            if (isTopEdge && isRightEdge) {
              occupancyMap[key].left = true;
              occupancyMap[key].down = true;
            }
            if (isBottomEdge && isLeftEdge) {
              occupancyMap[key].right = true;
              occupancyMap[key].up = true;
            }
            if (isBottomEdge && isRightEdge) {
              occupancyMap[key].left = true;
              occupancyMap[key].up = true;
            }

            occupancyMap[key].styles.push(style);
          }
        }
      }
    }
  });

  // Build crossroad map by analyzing each occupied position
  const crossroadMap = {};

  Object.keys(occupancyMap).forEach(key => {
    const { up, down, left, right, styles } = occupancyMap[key];

    // Determine the predominant style (prefer double if any double exists)
    const style = styles.includes('double') ? 'double' : 'single';
    const chars = CROSSROAD_CHARS[style];

    // Count connections
    const connectionCount = (up ? 1 : 0) + (down ? 1 : 0) + (left ? 1 : 0) + (right ? 1 : 0);

    // Only create crossroad if there's an intersection (more than 2 connections)
    if (connectionCount >= 3) {
      // Determine the appropriate junction character
      if (up && down && left && right) {
        crossroadMap[key] = chars.cross;
      } else if (up && left && right) {
        crossroadMap[key] = chars.tTop;
      } else if (down && left && right) {
        crossroadMap[key] = chars.tBottom;
      } else if (up && down && left) {
        crossroadMap[key] = chars.tLeft;
      } else if (up && down && right) {
        crossroadMap[key] = chars.tRight;
      }
    }
  });

  return crossroadMap;
}

/**
 * Check if a position has a crossroad
 * @param {Object} crossroadMap - Map of crossroads
 * @param {number} x - Grid x position
 * @param {number} y - Grid y position
 * @returns {string|null} - Crossroad character or null
 */
export function getCrossroadChar(crossroadMap, x, y) {
  const key = `${x},${y}`;
  return crossroadMap[key] || null;
}
