import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';
import playoutManager from './playout-manager.js';

dotenv.config();

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

app.use(cors());
app.use(express.json());

app.get('/health', (req, res) => res.json({ status: 'ok' }));

// Start the channel's output consumer. Body: { outputType, outputConfig, videoFormat }
app.post('/channel/start', async (req, res) => {
  try {
    const out = await playoutManager.startChannel(req.body || {});
    res.json(out);
  } catch (err) {
    console.error('[playout] /channel/start error:', err.message);
    res.status(500).json({ error: err.message });
  }
});

app.post('/channel/stop', async (req, res) => {
  try { res.json(await playoutManager.stopChannel()); }
  catch (err) { res.status(500).json({ error: err.message }); }
});

// Load + start a playlist. Body: { items: [...], loop }
app.post('/playlist/load', async (req, res) => {
  try {
    const { items = [], loop = false } = req.body || {};
    res.json(await playoutManager.loadPlaylist({ items, loop }));
  } catch (err) {
    console.error('[playout] /playlist/load error:', err.message);
    res.status(500).json({ error: err.message });
  }
});

app.post('/transport/skip',   async (req, res) => { try { res.json(await playoutManager.skip()); }   catch (e) { res.status(500).json({ error: e.message }); } });
app.post('/transport/pause',  async (req, res) => { try { res.json(await playoutManager.pause()); }  catch (e) { res.status(500).json({ error: e.message }); } });
app.post('/transport/resume', async (req, res) => { try { res.json(await playoutManager.resume()); } catch (e) { res.status(500).json({ error: e.message }); } });

// Fire an SCTE-35 ad-break splice on the live output. Body:
//   { eventId, type: 'splice_insert'|'immediate'|'splice_out'|'splice_in', durationS }
// Returns the active-break descriptor (or the splice_in ack) so the mam-api can
// stamp the as-run log.
app.post('/scte/trigger', (req, res) => {
  try {
    const { eventId = 1, type = 'splice_insert', durationS = 30 } = req.body || {};
    res.json(playoutManager.triggerScte({ eventId, type, durationS }));
  } catch (err) {
    console.error('[playout] /scte/trigger error:', err.message);
    res.status(500).json({ error: err.message });
  }
});

app.get('/status', (req, res) => res.json(playoutManager.getStatus()));

// Auto-start: when the sidecar is spawned by mam-api with channel env, bring up
// the output consumer immediately so the container is "on air idle" (black/slate)
// the moment it boots, mirroring the capture sidecar's bootstrap pattern.
async function bootstrap() {
  const outputType = process.env.OUTPUT_TYPE;
  if (!outputType) {
    console.log('[bootstrap] no OUTPUT_TYPE — on-demand sidecar, waiting for /channel/start');
    return;
  }
  let outputConfig = {};
  try { outputConfig = JSON.parse(process.env.OUTPUT_CONFIG || '{}'); }
  catch (err) { console.error('[bootstrap] bad OUTPUT_CONFIG json:', err.message); }
  const videoFormat = process.env.VIDEO_FORMAT || '1080i5994';
  try {
    await playoutManager.startChannel({ outputType, outputConfig, videoFormat });
  } catch (err) {
    console.error('[bootstrap] channel start failed:', err.message);
  }
}

const server = app.listen(PORT, () => {
  console.log(`Wild Dragon Playout Service listening on port ${PORT}`);
  // Give CasparCG a moment to come up (started by the container entrypoint).
  playoutManager.amcp.connect();
  bootstrap();
});

function shutdown(sig) {
  console.log(`[playout] ${sig} — shutting down`);
  playoutManager.stopChannel().catch(() => {}).finally(() => {
    playoutManager.amcp.close();
    server.close(() => process.exit(0));
    setTimeout(() => process.exit(0), 5000);
  });
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
