/**
 * Interactive compass component for setting floor plan rotation.
 * Allows users to visually set which direction is "North" for their home.
 *
 * @param {number} floor_plan_id The floor plan ID
 */
beestat.component.compass = function(floor_plan_id) {
  this.floor_plan_id_ = floor_plan_id;
  beestat.component.apply(this, arguments);
};
beestat.extend(beestat.component.compass, beestat.component);

/**
 * Render the compass.
 *
 * @param {HTMLElement} parent
 *
 * @return {beestat.component.compass} This
 */
beestat.component.compass.prototype.render = function(parent) {
  const self = this;

  // Container for the compass
  this.container_ = document.createElement('div');
  Object.assign(this.container_.style, {
    'position': 'absolute',
    'bottom': `${beestat.style.size.gutter}px`,
    'right': `${beestat.style.size.gutter}px`,
    'width': '80px',
    'height': '80px',
    'user-select': 'none',
    'cursor': 'grab',
    'z-index': '10'
  });

  // Create SVG
  this.svg_ = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  this.svg_.setAttribute('width', '80');
  this.svg_.setAttribute('height', '80');
  this.svg_.setAttribute('viewBox', '0 0 80 80');
  this.container_.appendChild(this.svg_);

  // Background circle
  const bg_circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  bg_circle.setAttribute('cx', '40');
  bg_circle.setAttribute('cy', '40');
  bg_circle.setAttribute('r', '38');
  bg_circle.setAttribute('fill', beestat.style.color.bluegray.base);
  bg_circle.setAttribute('stroke', '#fff');
  bg_circle.setAttribute('stroke-width', '2');
  bg_circle.setAttribute('opacity', '0.9');
  this.svg_.appendChild(bg_circle);

  // Create rotating group for compass rose
  this.compass_group_ = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  this.compass_group_.setAttribute('transform', 'translate(40, 40)');
  this.svg_.appendChild(this.compass_group_);

  // Cardinal direction markers
  const directions = [
    {label: 'N', angle: 0, color: beestat.style.color.red.base, size: 14},
    {label: 'E', angle: 90, color: '#fff', size: 10},
    {label: 'S', angle: 180, color: '#fff', size: 10},
    {label: 'W', angle: 270, color: '#fff', size: 10}
  ];

  directions.forEach(function(dir) {
    const angle_rad = (dir.angle - 90) * Math.PI / 180; // -90 to start at top
    const radius = 28;
    const x = radius * Math.cos(angle_rad);
    const y = radius * Math.sin(angle_rad);

    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    text.setAttribute('x', x);
    text.setAttribute('y', y);
    text.setAttribute('text-anchor', 'middle');
    text.setAttribute('dominant-baseline', 'middle');
    text.setAttribute('fill', dir.color);
    text.setAttribute('font-size', dir.size);
    text.setAttribute('font-weight', dir.label === 'N' ? 'bold' : 'normal');
    text.setAttribute('pointer-events', 'none');
    text.textContent = dir.label;
    self.compass_group_.appendChild(text);
  });

  // North arrow indicator
  const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  arrow.setAttribute('d', 'M 0,-22 L 4,-10 L 0,-12 L -4,-10 Z');
  arrow.setAttribute('fill', beestat.style.color.red.base);
  arrow.setAttribute('stroke', '#fff');
  arrow.setAttribute('stroke-width', '1');
  arrow.setAttribute('pointer-events', 'none');
  this.compass_group_.appendChild(arrow);

  // Center dot
  const center_dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  center_dot.setAttribute('cx', '0');
  center_dot.setAttribute('cy', '0');
  center_dot.setAttribute('r', '3');
  center_dot.setAttribute('fill', '#fff');
  center_dot.setAttribute('pointer-events', 'none');
  this.compass_group_.appendChild(center_dot);

  // Set initial rotation
  this.update_rotation_(this.get_rotation_());

  // Make it draggable
  this.set_draggable_();

  parent.appendChild(this.container_);
  this.rendered_ = true;

  return this;
};

/**
 * Get the current rotation value from the floor plan data.
 *
 * @return {number} Rotation in degrees (0-359)
 */
beestat.component.compass.prototype.get_rotation_ = function() {
  const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
  return floor_plan.data.appearance?.rotation || 0;
};

/**
 * Set the rotation value in the floor plan data.
 *
 * @param {number} degrees Rotation in degrees (0-359)
 */
beestat.component.compass.prototype.set_rotation_ = function(degrees) {
  const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];

  if (floor_plan.data.appearance === undefined) {
    floor_plan.data.appearance = {};
  }

  // Normalize to 0-359 and store as integer
  const normalized = Math.round(((degrees % 360) + 360) % 360);
  floor_plan.data.appearance.rotation = normalized;

  this.update_rotation_(normalized);

  // Dispatch event so other components know rotation changed
  this.dispatchEvent('rotation_change', normalized);
};

/**
 * Update the visual rotation of the compass.
 *
 * @param {number} degrees Rotation in degrees
 */
beestat.component.compass.prototype.update_rotation_ = function(degrees) {
  if (this.compass_group_) {
    this.compass_group_.setAttribute(
      'transform',
      `translate(40, 40) rotate(${degrees})`
    );
  }
};

/**
 * Make the compass draggable to change rotation.
 */
beestat.component.compass.prototype.set_draggable_ = function() {
  const self = this;
  let is_dragging = false;

  const get_angle = function(e) {
    const rect = self.svg_.getBoundingClientRect();
    const center_x = rect.left + rect.width / 2;
    const center_y = rect.top + rect.height / 2;

    const client_x = e.clientX || (e.touches && e.touches[0].clientX);
    const client_y = e.clientY || (e.touches && e.touches[0].clientY);

    const dx = client_x - center_x;
    const dy = client_y - center_y;

    // Calculate angle in degrees (0° = North/up, clockwise)
    let angle = Math.atan2(dy, dx) * 180 / Math.PI + 90;
    if (angle < 0) {
      angle += 360;
    }

    return angle;
  };

  const handle_start = function(e) {
    is_dragging = true;
    self.container_.style.cursor = 'grabbing';
    e.preventDefault();
  };

  const handle_move = function(e) {
    if (!is_dragging) {
      return;
    }

    const angle = get_angle(e);
    self.set_rotation_(angle);
    e.preventDefault();
  };

  const handle_end = function(e) {
    if (is_dragging) {
      is_dragging = false;
      self.container_.style.cursor = 'grab';
      e.preventDefault();
    }
  };

  // Store handlers for cleanup
  this.handlers_ = {
    'mouse_start': handle_start,
    'mouse_move': handle_move,
    'mouse_end': handle_end,
    'touch_start': handle_start,
    'touch_move': handle_move,
    'touch_end': handle_end
  };

  // Mouse events
  this.container_.addEventListener('mousedown', this.handlers_.mouse_start);
  window.addEventListener('mousemove', this.handlers_.mouse_move);
  window.addEventListener('mouseup', this.handlers_.mouse_end);

  // Touch events
  this.container_.addEventListener('touchstart', this.handlers_.touch_start);
  window.addEventListener('touchmove', this.handlers_.touch_move);
  window.addEventListener('touchend', this.handlers_.touch_end);
};

/**
 * Dispose of the compass.
 */
beestat.component.compass.prototype.dispose = function() {
  // Remove event listeners
  if (this.handlers_) {
    if (this.container_) {
      this.container_.removeEventListener('mousedown', this.handlers_.mouse_start);
      this.container_.removeEventListener('touchstart', this.handlers_.touch_start);
    }
    window.removeEventListener('mousemove', this.handlers_.mouse_move);
    window.removeEventListener('mouseup', this.handlers_.mouse_end);
    window.removeEventListener('touchmove', this.handlers_.touch_move);
    window.removeEventListener('touchend', this.handlers_.touch_end);
  }

  // Remove from DOM
  if (this.container_ && this.container_.parentNode) {
    this.container_.parentNode.removeChild(this.container_);
  }

  // Mark as not rendered
  this.rendered_ = false;
};
