/**
 * Cloud routes — /api/cloud/*, /api/settings, /api/cookie, /api/cli-status
 */
import fs from 'fs';
import path from 'path';
import os from 'os';
import { execSync } from 'child_process';
import { normalizeCoreDocIds, normalizeDocIdOverrides } from '../../data/doc-paths.js';
import { APP_VERSION } from '../../utils/config.js';
import { resolveProviderName } from '../../core/llm-provider.js';
import { VL_CODE_HOME, getCookie, clearCookie, saveCookie, ensureVLCodeHome, mergeProjectProfile } from '../helpers.js';

// Cache CLI detection (only check once per process)
let _cliStatusCache = null;

function detectClaudeCliStatus() {
  if (_cliStatusCache !== null) return _cliStatusCache;
  try {
    const version = execSync('claude --version 2>/dev/null', { timeout: 5000, encoding: 'utf-8' }).trim();
    _cliStatusCache = { available: true, version };
  } catch {
    _cliStatusCache = { available: false, version: null };
  }
  return _cliStatusCache;
}

function cookieHeader(cookie) {
  if (!cookie) return '';
  return cookie.includes('=') ? cookie : `ih5bearer=${cookie}`;
}

export function buildCloudStatusPayload(user, error = null) {
  const connected = !!user;
  const payload = {
    connected,
    loggedIn: connected,
    user: connected ? user : null,
  };
  if (error) payload.error = error;
  return payload;
}

function buildCloudStatusEvent(connected, user = null) {
  return {
    type: 'cloud_status',
    status: connected ? 'connected' : 'disconnected',
    connected,
    loggedIn: connected,
    user: connected ? user : null,
  };
}

export function setupCloudRoutes(app, server) {
  // --- CLI status detection ---
  app.get('/api/cli-status', (req, res) => {
    const status = detectClaudeCliStatus();
    res.json(status);
  });

  // --- Settings ---
  app.get('/api/settings', (req, res) => {
    const cliStatus = detectClaudeCliStatus();
    const hasApiKey = !!(server.config.apiKey || process.env.ANTHROPIC_API_KEY);
    const llmProvider = server.config.llmProvider || 'cli';
    let effectiveProvider = llmProvider;
    try {
      effectiveProvider = resolveProviderName({
        llmProvider,
        apiKey: server.config.apiKey,
        cliAvailable: cliStatus.available,
      });
    } catch {}

    res.json({
      model: server.config.model,
      maxOutputTokens: server.config.maxOutputTokens,
      llmMode: 'cli',
      hasCookie: !!server.config.cookie,
      llmProvider,
      effectiveProvider,
      cliAvailable: cliStatus.available,
      hasApiKey,
      workDir: server.config.workDir,
      autotest: server.config.autotest || {},
      docIdOverrides: normalizeDocIdOverrides(server.config.docIdOverrides, { includeDefaults: true }),
      coreDocIds: normalizeCoreDocIds(server.config.coreDocIds, { includeDefaults: true }),
      version: APP_VERSION,
    });
  });

  app.post('/api/settings', async (req, res) => {
    const { model, maxOutputTokens, cookie, apiKey, llmProvider, autotest, coreDocIds, docIdOverrides } = req.body;
    const changed = [];

    if (model && model !== server.config.model) {
      server.config.model = model;
      changed.push('model');
    }
    if (maxOutputTokens && maxOutputTokens !== server.config.maxOutputTokens) {
      server.config.maxOutputTokens = maxOutputTokens;
      changed.push('maxOutputTokens');
    }
    if (cookie !== undefined && cookie !== server.config.cookie) {
      if (cookie) saveCookie(server.config, cookie);
      else clearCookie(server.config);
      changed.push('cookie');
    }
    if (apiKey !== undefined) {
      server.config.apiKey = apiKey || undefined;
      changed.push('apiKey');
    }
    if (llmProvider && llmProvider !== server.config.llmProvider) {
      server.config.llmProvider = llmProvider;
      changed.push('llmProvider');
    }
    if (autotest && typeof autotest === 'object') {
      server.config.autotest = {
        ...(server.config.autotest || {}),
        ...autotest,
      };
      changed.push('autotest');
    }
    if (docIdOverrides && typeof docIdOverrides === 'object') {
      server.config.docIdOverrides = normalizeDocIdOverrides(docIdOverrides, { includeDefaults: true });
      if (server.hasSelectedWorkspace?.()) {
        mergeProjectProfile(server.config.workDir, { docIdOverrides: server.config.docIdOverrides });
      }
      changed.push('docIdOverrides');
    }
    if (coreDocIds && typeof coreDocIds === 'object') {
      server.config.coreDocIds = normalizeCoreDocIds(coreDocIds, { includeDefaults: true });
      if (server.hasSelectedWorkspace?.()) {
        mergeProjectProfile(server.config.workDir, { coreDocIds: server.config.coreDocIds });
      }
      changed.push('coreDocIds');
    }

    res.json({ ok: true, changed });
  });

  // --- Cookie refresh ---
  app.post('/api/cookie/refresh', (req, res) => {
    const { cookie } = req.body;
    if (cookie) {
      saveCookie(server.config, cookie);
      res.json({ ok: true });
    } else {
      const found = getCookie(server.config);
      res.json({ ok: !!found, cookie: found ? '[set]' : null });
    }
  });

  // --- Cloud login ---
  app.post('/api/cloud/login', async (req, res) => {
    try {
      const { username, password, companyName } = req.body;
      const result = await server.cloud.login(username, password, companyName);
      if (!result.ok) {
        return res.json({
          ok: false,
          connected: false,
          loggedIn: false,
          error: result.error || 'Login failed',
          code: result.code,
        });
      }

      if (result.cookie) saveCookie(server.config, result.cookie);
      const payload = buildCloudStatusPayload(result.user);
      server.broadcast(buildCloudStatusEvent(true, payload.user));
      server.broadcast({ type: 'auth_alert', status: 'logged_in', user: payload.user });
      res.json({ ok: true, ...payload });
    } catch (e) {
      res.status(500).json({ error: e.message });
    }
  });

  // --- Google OAuth login ---
  app.post('/api/cloud/google-login', async (req, res) => {
    try {
      const result = await server.cloud.googleLoginOrRegister(req.body);
      if (!result.ok) {
        return res.json({
          ok: false,
          connected: false,
          loggedIn: false,
          error: result.error || 'Google login failed',
        });
      }

      if (result.cookie) saveCookie(server.config, result.cookie);
      const payload = buildCloudStatusPayload(result.user);
      server.broadcast(buildCloudStatusEvent(true, payload.user));
      server.broadcast({ type: 'auth_alert', status: 'logged_in', user: payload.user });
      res.json({ ok: true, ...payload });
    } catch (e) {
      res.status(500).json({ error: e.message });
    }
  });

  // --- Cloud status ---
  app.get('/api/cloud/status', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.json(buildCloudStatusPayload(null));
      const userInfo = await server.cloud.getUserInfo(true);
      res.json(buildCloudStatusPayload(userInfo));
    } catch (e) {
      res.json(buildCloudStatusPayload(null, e.message));
    }
  });

  // --- Cloud logout ---
  app.post('/api/cloud/logout', (req, res) => {
    clearCookie(server.config);
    server.broadcast(buildCloudStatusEvent(false));
    server.broadcast({ type: 'auth_alert', status: 'logged_out' });
    res.json({ ok: true });
  });

  // --- Cloud apps ---
  app.get('/api/cloud/apps', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch('https://www.visuallogic.ai/api/12027022/SERVICE_User_listWorkgroupMap', {
        method: 'POST', headers: { 'Content-Type': 'application/json', 'Cookie': `ih5bearer=${cookie}` }, body: '{}',
      });
      const data = await resp.json();
      res.json(data);
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Create new cloud project ---
  app.post('/api/cloud/create-project', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const { name } = req.body;
      const resp = await fetch('https://www.visuallogic.ai/api/12027022/SERVICE_WorkgroupMap_createWorkgroupMap', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Cookie': `ih5bearer=${cookie}` },
        body: JSON.stringify({ name: name || 'VLCode-Project', type: 'vl' }),
      });
      const data = await resp.json();
      // Try common GID field names in platform response
      const gid = data.data?.gid || data.data?.nid || data.data?.id || data.gid || data.nid || data.id;
      if (!gid) return res.json({ error: 'Platform did not return a GID', raw: data });
      res.json({ ok: true, gid });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud workgroup ---
  app.get('/api/cloud/workgroup/:gid', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch(`https://editor.visuallogic.ai/ih5/editor/workspace/config?nid=${req.params.gid}`, {
        headers: { 'Cookie': cookieHeader(cookie) },
      });
      res.json(await resp.json());
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud files ---
  app.get('/api/cloud/files/:gid', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch(`https://editor.visuallogic.ai/ih5/editor/workspace/list?nid=${req.params.gid}`, {
        headers: { 'Cookie': cookieHeader(cookie) },
      });
      res.json(await resp.json());
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Sync push (local → cloud) ---
  app.post('/api/cloud/sync/push', async (req, res) => {
    try {
      const { gid } = req.body;
      if (!gid) return res.status(400).json({ error: 'gid required' });
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });

      const files = server.projectContext.getAllFiles();
      let pushed = 0;
      for (const f of files) {
        try {
          const content = fs.readFileSync(f.fullPath, 'utf-8');
          await fetch('https://editor.visuallogic.ai/ih5/editor/workspace/create', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'Cookie': cookieHeader(cookie) },
            body: JSON.stringify({ nid: Number(gid), path: f.path, content: JSON.stringify(content), shared: false }),
          });
          pushed++;
        } catch {}
      }
      res.json({ ok: true, pushed });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Sync pull (cloud → local) ---
  app.post('/api/cloud/sync/pull', async (req, res) => {
    try {
      const { gid } = req.body;
      if (!gid) return res.status(400).json({ error: 'gid required' });
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });

      const resp = await fetch(`https://editor.visuallogic.ai/ih5/editor/workspace/list?nid=${gid}`, {
        headers: { 'Cookie': cookieHeader(cookie) },
      });
      const data = await resp.json();
      let pulled = 0;
      const files = data.data || data.files || [];
      for (const f of files) {
        try {
          const readResp = await fetch(`https://editor.visuallogic.ai/ih5/editor/workspace/read?nid=${gid}&path=${encodeURIComponent(f.path)}`, {
            headers: { 'Cookie': cookieHeader(cookie) },
          });
          const fileData = await readResp.json();
          let content = fileData.content || fileData.data?.content || '';
          try { content = JSON.parse(content); } catch {}
          const fullPath = path.resolve(server.config.workDir, f.path);
          const dir = path.dirname(fullPath);
          if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
          fs.writeFileSync(fullPath, content, 'utf-8');
          pulled++;
        } catch {}
      }
      await server.projectContext.load();
      server.broadcast({ type: 'file_tree_updated' });
      res.json({ ok: true, pulled });
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud compile ---
  app.post('/api/cloud/compile', async (req, res) => {
    // Delegates to compile route internally
    try {
      const result = await server.toolRegistry.execute('VLCompile', req.body);
      res.json(result);
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud lint ---
  app.post('/api/cloud/lint', async (req, res) => {
    try {
      const result = await server.toolRegistry.execute('VLLint', req.body);
      res.json(result);
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud config ---
  app.get('/api/cloud/config/:nid', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch(`https://editor.visuallogic.ai/ih5/editor/workspace/config?nid=${req.params.nid}`, {
        headers: { 'Cookie': cookieHeader(cookie) },
      });
      res.json(await resp.json());
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud publish ---
  app.post('/api/cloud/publish', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch('https://www.visuallogic.ai/api/12027022/SERVICE_Publish_publishVersion', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Cookie': cookieHeader(cookie) },
        body: JSON.stringify(req.body),
      });
      res.json(await resp.json());
    } catch (e) { res.status(500).json({ error: e.message }); }
  });

  // --- Cloud balance ---
  app.get('/api/cloud/balance', async (req, res) => {
    try {
      const cookie = getCookie(server.config);
      if (!cookie) return res.status(401).json({ error: 'Not logged in' });
      const resp = await fetch('https://www.visuallogic.ai/api/12027022/SERVICE_User_getBalance', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Cookie': cookieHeader(cookie) },
        body: '{}',
      });
      res.json(await resp.json());
    } catch (e) { res.status(500).json({ error: e.message }); }
  });
}
