const { v4: uuidv4 } = require('uuid');
const DashboardPlatformsRepository = require('../../repositories/settings/DashboardPlatformsRepository');

const repo = new DashboardPlatformsRepository();

function toBool(value, fallback) {
  if (value === undefined) return fallback;
  if (value === true || value === false) return value;
  if (value === 'true') return true;
  if (value === 'false') return false;
  return fallback;
}

function toNullableString(value) {
  if (value === undefined) return undefined;
  if (value === null) return null;
  const s = String(value);
  return s;
}

function requireNonEmptyString(value, field) {
  const s = typeof value === 'string' ? value.trim() : '';
  if (!s) {
    const err = new Error(`${field} is required`);
    err.status = 400;
    throw err;
  }
  return s;
}

class DashboardPlatformsController {
  // Public endpoint (no auth): only returns active platforms (state=true)
  static async listPublic(req, res) {
    const list = await repo.listPublic();
    return res.json(list);
  }

  static async list(req, res) {
    const list = await repo.list();
    return res.json(list);
  }

  static async create(req, res) {
    try {
      const title = requireNonEmptyString(req.body.title, 'title');
      const href = requireNonEmptyString(req.body.href, 'href');

      const platform = {
        id: uuidv4(),
        title,
        description: toNullableString(req.body.description) ?? '',
        href,
        icon: toNullableString(req.body.icon) ?? '',
        color: toNullableString(req.body.color) ?? '',
        state: toBool(req.body.state, true),
        disabled: toBool(req.body.disabled, false),
        disabledText: toNullableString(req.body.disabledText) ?? null,
        sortOrder: Number.isFinite(Number(req.body.sortOrder)) ? Number(req.body.sortOrder) : 0,
      };

      const created = await repo.create(platform);
      return res.status(201).json(created || platform);
    } catch (err) {
      const status = err?.status || 500;
      return res.status(status).json({ error: err.message || 'Failed to create dashboard platform' });
    }
  }

  static async update(req, res) {
    try {
      const id = String(req.params.id || '').trim();
      if (!id) return res.status(400).json({ error: 'id is required' });

      const existing = await repo.getById(id);
      if (!existing) return res.status(404).json({ error: 'Not found' });

      const next = {
        ...existing,
        title: req.body.title === undefined ? existing.title : String(req.body.title),
        description: req.body.description === undefined ? existing.description : String(req.body.description || ''),
        href: req.body.href === undefined ? existing.href : String(req.body.href),
        icon: req.body.icon === undefined ? existing.icon : String(req.body.icon || ''),
        color: req.body.color === undefined ? existing.color : String(req.body.color || ''),
        disabled: req.body.disabled === undefined ? existing.disabled : toBool(req.body.disabled, existing.disabled),
        disabledText: req.body.disabledText === undefined ? existing.disabledText : (req.body.disabledText === null ? null : String(req.body.disabledText)),
        sortOrder: req.body.sortOrder === undefined ? existing.sortOrder : (Number.isFinite(Number(req.body.sortOrder)) ? Number(req.body.sortOrder) : existing.sortOrder),
      };

      // If title/href were provided, require non-empty
      if (req.body.title !== undefined) requireNonEmptyString(next.title, 'title');
      if (req.body.href !== undefined) requireNonEmptyString(next.href, 'href');

      const updated = await repo.update(id, next);
      if (!updated) return res.status(404).json({ error: 'Not found' });
      return res.json(updated);
    } catch (err) {
      const status = err?.status || 500;
      return res.status(status).json({ error: err.message || 'Failed to update dashboard platform' });
    }
  }

  static async setState(req, res) {
    try {
      const id = String(req.params.id || '').trim();
      if (!id) return res.status(400).json({ error: 'id is required' });

      const state = toBool(req.body.state, undefined);
      if (state === undefined) return res.status(400).json({ error: 'state must be boolean' });

      const updated = await repo.setState(id, state);
      if (!updated) return res.status(404).json({ error: 'Not found' });
      return res.json(updated);
    } catch (err) {
      const status = err?.status || 500;
      return res.status(status).json({ error: err.message || 'Failed to update state' });
    }
  }
}

module.exports = DashboardPlatformsController;
