const express = require('express');
const { APP_PORTS } = require('../../src/utilities/constants');
const { ok } = require('../../src/utils/responses');

/**
 * Plex routes factory
 * @param {Object} deps - Explicit dependencies
 * @param {Function} deps.fetchT - Timeout-wrapped fetch
 * @param {Function} deps.asyncHandler - Async route handler wrapper
 * @param {Function} deps.errorResponse - Error response helper
 * @param {Object} deps.log - Logger instance
 * @param {Object} deps.helpers - Arr helpers module
 * @param {Object} deps.credentialManager - Credential manager
 * @param {Object} deps.servicesStateManager - Services state manager
 * @returns {express.Router}
 */
module.exports = function({ fetchT, asyncHandler, errorResponse, log: _log, helpers, credentialManager, servicesStateManager }) {
  const router = express.Router();

  const ctx = {
    credentialManager,
    servicesStateManager
  };

  // Plex Libraries endpoint
  router.get('/plex/libraries', asyncHandler(async (req, res) => {
    // Get Plex token
    let plexToken = await helpers.getPlexToken('plex');
    if (!plexToken) {
      plexToken = await ctx.credentialManager.retrieve('arr.plex.token');
    }

    if (!plexToken) {
      return errorResponse(res, 400, 'No Plex token available. Claim your Plex server first.', {
        hint: 'Deploy Plex with a claim token or manually configure it.'
      });
    }

    // Get Plex URL
    let plexUrl = `http://localhost:${APP_PORTS.plex}`;
    try {
      const services = await ctx.servicesStateManager.read();
      const svcList = Array.isArray(services) ? services : services.services || [];
      const plexService = svcList.find(s => s.id === 'plex' || s.appTemplate === 'plex');
      if (plexService?.url) {
        plexUrl = plexService.url.replace('host.docker.internal', 'localhost');
      }
    } catch (e) { /* use default */ }

    // Fetch libraries
    const libRes = await fetchT(`${plexUrl}/library/sections`, {
      headers: { 'X-Plex-Token': plexToken, 'Accept': 'application/json' },
      signal: AbortSignal.timeout(10000)
    });

    if (!libRes.ok) {
      return errorResponse(res, 502, `Plex returned ${libRes.status}`);
    }

    const data = await libRes.json();
    const libraries = (data.MediaContainer?.Directory || []).map(dir => ({
      key: dir.key,
      title: dir.title,
      type: dir.type,
      count: parseInt(dir.count) || 0,
      scannedAt: dir.scannedAt
    }));

    // Get server name
    let serverName = 'Plex';
    let version = null;
    try {
      const identityRes = await fetchT(`${plexUrl}/identity`, {
        headers: { 'X-Plex-Token': plexToken, 'Accept': 'application/json' },
        signal: AbortSignal.timeout(5000)
      });
      if (identityRes.ok) {
        const identity = await identityRes.json();
        serverName = identity.MediaContainer?.friendlyName || 'Plex';
        version = identity.MediaContainer?.version;
      }
    } catch (e) { /* use default */ }

    // Store token for future use
    await ctx.credentialManager.store('arr.plex.token', plexToken, {
      service: 'plex', source: 'local', url: plexUrl,
      lastVerified: new Date().toISOString()
    });

    ok(res, { serverName, version, libraries });
  }, 'plex-libraries'));

  return router;
};
