const fs = require("fs");
const path = require("path");
const { resolveData } = require("./paths");

const LOG_FILE = "assistant-panel.log";

class AssistantPanelDiagnostics {
  constructor(templatePath) {
    this.templatePath = path.resolve(templatePath);
    this.state = {
      panel_endpoint_status: null,
      panel_html_length: 0,
      panel_html_error: null,
      panel_template_path: this.templatePath,
      missing_locals: [],
      mount_error: null,
      updated_at: null
    };
  }

  templateCheck(requiredLocals = [], locals = {}) {
    const missing = requiredLocals.filter((key) => locals[key] === undefined || locals[key] === null);
    let error = null;
    try {
      fs.accessSync(this.templatePath, fs.constants.R_OK);
    } catch {
      error = "Assistant panel template is missing or unreadable.";
    }
    this.update({ missing_locals: missing, panel_html_error: error });
    return { valid: !error && missing.length === 0, missing, error };
  }

  rendered(html) {
    const content = String(html || "");
    const marker = 'data-assistant-panel-id="lumi_ai"';
    const error = !content.trim()
      ? "Assistant panel rendered empty HTML."
      : !content.includes(marker)
        ? `Assistant panel HTML is missing ${marker}.`
        : null;
    this.update({
      panel_endpoint_status: error ? 500 : 200,
      panel_html_length: content.length,
      panel_html_error: error
    });
    return { valid: !error, error, length: content.length };
  }

  renderFailed(error) {
    this.update({
      panel_endpoint_status: 500,
      panel_html_length: 0,
      panel_html_error: error?.message || String(error)
    }, "render_failure");
  }

  frontend(report = {}) {
    this.update({
      panel_endpoint_status: numberOrNull(report.panel_endpoint_status) ?? this.state.panel_endpoint_status,
      panel_html_length: numberOrNull(report.panel_html_length) ?? this.state.panel_html_length,
      panel_html_error: report.panel_html_error || this.state.panel_html_error,
      mount_error: report.mount_error || null
    }, report.mount_error ? "mount_failure" : null);
  }

  snapshot() {
    return { ...this.state };
  }

  update(values, event = null) {
    this.state = { ...this.state, ...values, updated_at: new Date().toISOString() };
    if (event || values.panel_html_error || values.mount_error) {
      this.log(event || "diagnostic", values);
    }
  }

  log(event, details) {
    const target = resolveData("logs", LOG_FILE);
    const line = JSON.stringify({ at: new Date().toISOString(), event, ...details });
    fs.appendFileSync(target, `${line}\n`, "utf8");
  }
}

function numberOrNull(value) {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : null;
}

module.exports = { AssistantPanelDiagnostics, LOG_FILE };
