import * as vscode from 'vscode';
import * as fs from 'fs';
import * as path from 'path';

const BETA_TOOLS_ENABLED_KEY = 'hplToolbox.betaTools.enabled';

interface ToolDefinition {
  id?: string;
  command: string;
  title: string;
  description: string;
  beta?: boolean;
}

const FALLBACK_TOOLS: ToolDefinition[] = [
  {
    command: 'hplToolbox.openPlecUpload',
    title: 'PLEC Upload',
    description: 'Upload HTML to internal PLEC server',
  },
  {
    command: 'hplToolbox.openApplovinUpload',
    title: 'AppLovin Playable Preview',
    description: 'Upload to p.applov.in (QR preview)',
  },
  {
    command: 'hplToolbox.openBase64Scanner',
    title: 'Base64 Scanner',
    description: 'Find non-base64 assets in HTML',
  },
  {
    command: 'hplToolbox.openSendToMobile',
    title: 'Send To Mobile',
    description: 'Share HTML to a phone via LAN + QR',
  },
  {
    command: 'hplToolbox.openMraidChecker',
    title: 'MRAID Checker',
    description: 'Check MRAID requirements and best practices',
  },
  {
    command: 'hplToolbox.openPlayworksConverter',
    title: 'Playworks Converter',
    description: 'Convert Playworks HTML to per-network variants',
    beta: true,
  },
];

export class LauncherViewProvider implements vscode.WebviewViewProvider {
  constructor(private readonly context: vscode.ExtensionContext) { }

  resolveWebviewView(view: vscode.WebviewView) {
    view.webview.options = { enableScripts: true };
    const version = this.context.extension.packageJSON.version as string;
    const tools = loadToolDefinitions(this.context.extensionPath);
    const betaToolsEnabled = this.context.globalState.get<boolean>(BETA_TOOLS_ENABLED_KEY, false);
    view.webview.html = getHtml(version, betaToolsEnabled, tools);
    view.webview.onDidReceiveMessage(async (msg) => {
      if (msg?.type === 'open' && typeof msg.command === 'string') {
        vscode.commands.executeCommand(msg.command);
      } else if (msg?.type === 'openChangelog') {
        vscode.commands.executeCommand('hplToolbox.openChangelog');
      } else if (msg?.type === 'setBetaToolsEnabled' && typeof msg.enabled === 'boolean') {
        await this.context.globalState.update(BETA_TOOLS_ENABLED_KEY, msg.enabled);
        view.webview.html = getHtml(version, msg.enabled, tools);
      }
    });
  }
}

function loadToolDefinitions(extensionPath: string): ToolDefinition[] {
  const toolsPath = path.join(extensionPath, 'tools.json');
  try {
    const raw = JSON.parse(fs.readFileSync(toolsPath, 'utf8'));
    if (!Array.isArray(raw)) return FALLBACK_TOOLS;
    const tools = raw
      .filter((tool: any) => tool && typeof tool.command === 'string' && typeof tool.title === 'string')
      .map((tool: any) => ({
        id: typeof tool.id === 'string' ? tool.id : undefined,
        command: tool.command,
        title: tool.title,
        description: typeof tool.description === 'string' ? tool.description : '',
        beta: Boolean(tool.beta),
      }));
    return tools.length ? tools : FALLBACK_TOOLS;
  } catch {
    return FALLBACK_TOOLS;
  }
}

function getHtml(version: string, betaToolsEnabled: boolean, tools: ToolDefinition[]): string {
  const visibleTools = sortToolsForDisplay(tools.filter(tool => betaToolsEnabled || !tool.beta));
  const toolButtons = visibleTools.map(renderToolButton).join('\n');
  return `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<style>
  * { box-sizing: border-box; }
  body {
    min-height: 100vh;
    margin: 0;
    padding: 10px 8px 8px;
    display: flex;
    flex-direction: column;
    font-family: var(--vscode-font-family);
    font-size: var(--vscode-font-size);
    background: var(--vscode-sideBar-background, var(--vscode-editor-background));
    color: var(--vscode-foreground);
  }
  .tools {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .tool-btn {
    display: block;
    width: 100%;
    min-height: 52px;
    padding: 8px 9px;
    text-align: left;
    background: var(--vscode-list-inactiveSelectionBackground, var(--vscode-button-secondaryBackground));
    color: var(--vscode-foreground);
    border: 1px solid var(--vscode-panel-border, transparent);
    border-radius: 5px;
    cursor: pointer;
    font: inherit;
  }
  .tool-btn:hover {
    background: var(--vscode-list-hoverBackground, var(--vscode-button-secondaryHoverBackground));
    border-color: var(--vscode-focusBorder, var(--vscode-panel-border));
  }
  .tool-btn:focus {
    outline: 1px solid var(--vscode-focusBorder);
    outline-offset: 1px;
  }
  .tool-btn:active {
    background: var(--vscode-list-activeSelectionBackground, var(--vscode-button-background));
    color: var(--vscode-list-activeSelectionForeground, var(--vscode-button-foreground));
  }
  .tool-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.25;
  }
  .tool-desc {
    display: block;
    margin-top: 4px;
    color: var(--vscode-descriptionForeground);
    font-size: 11px;
    line-height: 1.35;
  }
  .beta-badge {
    flex: 0 0 auto;
    padding: 1px 5px;
    border: 1px solid var(--vscode-panel-border);
    border-radius: 3px;
    color: var(--vscode-descriptionForeground);
    font-size: 10px;
    text-transform: uppercase;
  }
  .footer {
    margin-top: auto;
    padding-top: 8px;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 8px;
    color: var(--vscode-descriptionForeground);
    font-size: 8px;
    border-top: 1px solid var(--vscode-panel-border);
  }
  .footer-action {
    padding: 0;
    background: transparent;
    color: var(--vscode-descriptionForeground);
    border: 0;
    cursor: pointer;
    text-align: left;
    font: inherit;
    font-size: 10px;
    opacity: 0.72;
  }
  #betaToggle {
    justify-self: start;
  }
  .footer-action:hover {
    opacity: 1;
    text-decoration: underline;
  }
  .footer-version {
    opacity: 0.75;
    text-align: center;
    white-space: nowrap;
  }
  .changelog-link {
    justify-self: end;
    text-align: right;
  }
</style>
</head>
<body>
  <div class="tools">
${toolButtons}
  </div>
  <div class="footer">
    <button id="betaToggle" class="footer-action" data-enabled="${betaToolsEnabled ? 'true' : 'false'}">${betaToolsEnabled ? 'Hide beta' : 'Show beta'}</button>
    <span class="footer-version">${version} - JJGC 00784</span>
    <button id="changelogLink" class="footer-action changelog-link">Changelog</button>
  </div>
<script>
  const vscode = acquireVsCodeApi();
  document.querySelectorAll('.tool-btn').forEach((btn) => {
    btn.addEventListener('click', () => {
      vscode.postMessage({ type: 'open', command: btn.dataset.cmd });
    });
  });
  document.getElementById('betaToggle').addEventListener('click', (event) => {
    const enabled = event.currentTarget.dataset.enabled === 'true';
    vscode.postMessage({ type: 'setBetaToolsEnabled', enabled: !enabled });
  });
  document.getElementById('changelogLink').addEventListener('click', () => {
    vscode.postMessage({ type: 'openChangelog' });
  });
</script>
</body>
</html>`;
}

function sortToolsForDisplay(tools: ToolDefinition[]): ToolDefinition[] {
  return [...tools].sort((a, b) => Number(Boolean(a.beta)) - Number(Boolean(b.beta)));
}

function renderToolButton(tool: ToolDefinition): string {
  return `  <button class="tool-btn" data-cmd="${escapeHtml(tool.command)}">
    <span class="tool-title">${escapeHtml(tool.title)}${tool.beta ? ' <span class="beta-badge">Beta</span>' : ''}</span>
    <span class="tool-desc">${escapeHtml(tool.description)}</span>
  </button>`;
}

function escapeHtml(value: string): string {
  return value.replace(/[&<>"']/g, ch => ({
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;',
  }[ch] ?? ch));
}
