/**
 * BreakPilot H5P Service
 * Self-hosted H5P Interactive Content Server using @lumieducation/h5p-express
 */
import express from 'express';
import cors from 'cors';
import path from 'path';
import { fileURLToPath } from 'url';
import bodyParser from 'body-parser';

import {
  H5PEditor,
  H5PPlayer,
  fsImplementations,
  H5PConfig
} from '@lumieducation/h5p-server';

import {
  h5pAjaxExpressRouter,
  libraryAdministrationExpressRouter,
  contentTypeCacheExpressRouter
} from '@lumieducation/h5p-express';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
const PORT = process.env.PORT || 8080;

// Middleware
app.use(cors());
app.use(bodyParser.json({ limit: '500mb' }));
app.use(bodyParser.urlencoded({ extended: true, limit: '500mb' }));

// H5P Configuration
const config = new H5PConfig(
  new fsImplementations.InMemoryStorage(),
  {
    baseUrl: 'http://localhost:8003',
    contentFilesUrl: '/h5p/content',
    downloadUrl: '/h5p/download',
    coreUrl: '/h5p/core',
    librariesUrl: '/h5p/libraries',
    playUrl: '/h5p/play',
    ajaxUrl: '/h5p/ajax'
  }
);

// Storage implementations
const contentStorage = new fsImplementations.FileContentStorage(
  process.env.H5P_STORAGE_PATH || path.join(__dirname, 'h5p-content')
);

const libraryStorage = new fsImplementations.FileLibraryStorage(
  path.join(__dirname, 'h5p-libraries')
);

const temporaryStorage = new fsImplementations.DirectoryTemporaryFileStorage(
  path.join(__dirname, 'h5p-temp')
);

// Initialize H5P Editor and Player
let h5pEditor;
let h5pPlayer;

async function initH5P() {
  try {
    h5pEditor = new H5PEditor(
      contentStorage,
      config,
      libraryStorage,
      undefined,
      undefined,
      temporaryStorage
    );

    h5pPlayer = new H5PPlayer(
      libraryStorage,
      contentStorage,
      config
    );

    // Install H5P core files
    await h5pEditor.installLibraryFromHub('H5P.Column');

    console.log('✅ H5P Editor and Player initialized');
    return true;
  } catch (error) {
    console.error('⚠️  H5P initialization:', error.message);
    // Continue even if library install fails - editor will show library list
    return true;
  }
}

// User object for H5P (simplified)
const getUser = (req) => ({
  id: req.headers['x-user-id'] || 'anonymous',
  name: req.headers['x-user-name'] || 'Anonymous',
  email: req.headers['x-user-email'] || 'anonymous@breakpilot.app',
  canInstallRecommended: true,
  canUpdateAndInstallLibraries: true,
  canCreateRestricted: true,
  type: 'local'
});

// Function to register H5P routes (called after init)
function registerH5PRoutes() {
  // Serve H5P core static files (JS/CSS)
  app.use('/h5p/core', express.static(path.join(__dirname, 'h5p-core')));
  app.use('/h5p/editor', express.static(path.join(__dirname, 'h5p-core')));

  // Serve H5P libraries
  app.use('/h5p/libraries', express.static(path.join(__dirname, 'h5p-libraries')));

  // Serve H5P content files
  app.use('/h5p/content', express.static(path.join(__dirname, 'h5p-content')));

  // ============= H5P AJAX ROUTES (from h5p-express) =============

  app.use(
    '/h5p/ajax',
    h5pAjaxExpressRouter(
      h5pEditor,
      path.resolve('h5p-core'),
      path.resolve('h5p-libraries'),
      (req) => getUser(req)
    )
  );

  // ============= LIBRARY ADMINISTRATION =============

  app.use(
    '/h5p/libraries-admin',
    libraryAdministrationExpressRouter(
      h5pEditor,
      (req) => getUser(req)
    )
  );

  // ============= CONTENT TYPE CACHE =============

  app.use(
    '/h5p/content-type-cache',
    contentTypeCacheExpressRouter(
      h5pEditor,
      (req) => getUser(req)
    )
  );
}

// ============= EDITOR & PLAYER HTML PAGES =============

// Create new H5P content (Editor UI)
app.get('/h5p/editor/new', async (req, res) => {
  try {
    const editorModel = await h5pEditor.render(undefined, 'en', getUser(req));

    const html = `<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>H5P Editor - BreakPilot</title>
  ${editorModel.styles.map(style => `<link rel="stylesheet" href="${style}"/>`).join('\n  ')}
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      background: #f5f5f5;
      padding: 20px;
    }
    .h5p-editor-container {
      background: white;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
      padding: 20px;
      max-width: 1400px;
      margin: 0 auto;
    }
    h1 {
      color: #333;
      margin-bottom: 20px;
      font-size: 24px;
    }
    #h5p-editor-container {
      min-height: 500px;
    }
  </style>
</head>
<body>
  <div class="h5p-editor-container">
    <h1>🎓 H5P Content Creator</h1>
    ${editorModel.html}
  </div>

  <script>
    window.H5PIntegration = ${JSON.stringify(editorModel.integration, null, 2)};
  </script>
  ${editorModel.scripts.map(script => `<script src="${script}"></script>`).join('\n  ')}
</body>
</html>`;

    res.send(html);
  } catch (error) {
    console.error('Editor render error:', error);
    res.status(500).send(`
      <h1>Error loading H5P Editor</h1>
      <p>Error: ${error.message}</p>
      <p>Please check that H5P libraries are installed.</p>
    `);
  }
});

// Edit existing H5P content
app.get('/h5p/editor/:contentId', async (req, res) => {
  try {
    const editorModel = await h5pEditor.render(req.params.contentId, 'en', getUser(req));

    const html = `<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <title>H5P Editor - ${req.params.contentId}</title>
  ${editorModel.styles.map(style => `<link rel="stylesheet" href="${style}"/>`).join('\n  ')}
</head>
<body>
  <h1>Edit H5P Content</h1>
  ${editorModel.html}
  <script>window.H5PIntegration = ${JSON.stringify(editorModel.integration)};</script>
  ${editorModel.scripts.map(script => `<script src="${script}"></script>`).join('\n  ')}
</body>
</html>`;

    res.send(html);
  } catch (error) {
    res.status(500).send(`Error: ${error.message}`);
  }
});

// Play H5P content
app.get('/h5p/play/:contentId', async (req, res) => {
  try {
    const playerModel = await h5pPlayer.render(req.params.contentId, getUser(req));

    res.send(`<!DOCTYPE html>
<html>
<head>
  <title>H5P Player</title>
  ${playerModel.styles.map(s => `<link rel="stylesheet" href="${s}"/>`).join('\n  ')}
</head>
<body>
  <div class="h5p-player">
    ${playerModel.html}
  </div>
  <script>window.H5PIntegration = ${JSON.stringify(playerModel.integration)};</script>
  ${playerModel.scripts.map(s => `<script src="${s}"></script>`).join('\n  ')}
</body>
</html>`);
  } catch (error) {
    res.status(500).send(`Error: ${error.message}`);
  }
});

// ============= CONTENT MANAGEMENT =============

// Save/Update content
app.post('/h5p/content/:contentId?', async (req, res) => {
  try {
    const contentId = req.params.contentId;
    const { library, params } = req.body;

    const savedId = await h5pEditor.saveOrUpdateContent(
      contentId || undefined,
      params,
      library,
      getUser(req)
    );

    res.json({
      success: true,
      contentId: savedId,
      message: 'Content saved successfully'
    });
  } catch (error) {
    console.error('Save content error:', error);
    res.status(500).json({
      success: false,
      error: error.message
    });
  }
});

// List all content
app.get('/h5p/content', async (req, res) => {
  try {
    const contentIds = await contentStorage.listContent();
    res.json({ contentIds });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Delete content
app.delete('/h5p/content/:contentId', async (req, res) => {
  try {
    await contentStorage.deleteContent(req.params.contentId, getUser(req));
    res.json({ success: true, message: 'Content deleted' });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// ============= INFO & HEALTH ENDPOINTS =============

app.get('/', (req, res) => {
  res.send(`
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>BreakPilot H5P Service</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .container {
      background: white;
      border-radius: 16px;
      box-shadow: 0 20px 60px rgba(0,0,0,0.3);
      padding: 40px;
      max-width: 600px;
      width: 100%;
    }
    h1 { color: #333; margin-bottom: 10px; font-size: 32px; }
    .status {
      display: inline-block;
      background: #10b981;
      color: white;
      padding: 6px 16px;
      border-radius: 20px;
      font-size: 14px;
      margin: 20px 0;
    }
    .btn {
      display: block;
      padding: 12px 24px;
      background: #667eea;
      color: white;
      text-decoration: none;
      border-radius: 8px;
      text-align: center;
      font-weight: 600;
      margin: 10px 0;
    }
    .btn:hover { background: #5568d3; }
  </style>
</head>
<body>
  <div class="container">
    <h1>🎓 H5P Service</h1>
    <div class="status">✅ Running</div>
    <a href="/h5p/editor/new" class="btn">Create New H5P Content</a>
    <a href="/health" class="btn" style="background: #e2e8f0; color: #4a5568;">Health Check</a>
  </div>
</body>
</html>
  `);
});

app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    service: 'h5p-service',
    version: '1.0.0'
  });
});

app.get('/info', (req, res) => {
  res.json({
    service: 'BreakPilot H5P Service',
    version: '1.0.0',
    endpoints: {
      root: '/',
      health: '/health',
      editorNew: '/h5p/editor/new',
      editorEdit: '/h5p/editor/:contentId',
      player: '/h5p/play/:contentId',
      contentList: '/h5p/content'
    }
  });
});

// Debug endpoint to see what render() returns
app.get('/debug/editor-model', async (req, res) => {
  try {
    const model = await h5pEditor.render(undefined, 'en', getUser(req));
    res.json({
      styles: model.styles,
      scripts: model.scripts,
      integration: model.integration
    });
  } catch (error) {
    res.status(500).json({ error: error.message, stack: error.stack });
  }
});

// Start server
async function start() {
  try {
    await initH5P();

    // Register H5P routes after initialization
    registerH5PRoutes();

    app.listen(PORT, () => {
      console.log(`
╔════════════════════════════════════════════════════╗
║  🎓 BreakPilot H5P Service                        ║
║  📍 http://localhost:${PORT}                       ║
║  ✅ Ready to create interactive content!          ║
╚════════════════════════════════════════════════════╝
      `);
    });
  } catch (error) {
    console.error('Failed to start H5P service:', error);
    process.exit(1);
  }
}

start();
