import { objectSchema } from '../../kernel/input-schema.mjs';
import { getUsersService } from './index.mjs';

const emailRule = { type: 'string', required: true, minLength: 3, maxLength: 254, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/ };
const roles = ['admin','manager','editor','publisher','viewer'];

export function registerUsersRoutes({ app, routes, deps }) {
  routes.register(app, {
    id: 'users.me.read', method: 'GET', path: '/api/me', owner: 'vendoo.users', policy: 'users.self', csrf: false, stability: 'stable',
    handler: async (req, res) => res.json(getUsersService().currentIdentity(req.user.id, req.cookies?.csrf_token)),
  });
  routes.register(app, {
    id: 'users.me.update', method: 'PUT', path: '/api/me', owner: 'vendoo.users', policy: 'users.self', csrf: true, stability: 'stable',
    input: objectSchema({ name: { type: 'string', required: true, minLength: 1, maxLength: 120 } }),
    handler: async (req, res) => {
      const user = getUsersService().updateProfile(req.user.id, req.validatedBody);
      deps.auditLog(req.user.id, req.user.email, 'user.profile_updated', 'user', String(req.user.id), null, deps.getClientIp(req));
      res.json(user);
    },
  });
  routes.register(app, {
    id: 'users.admin.list', method: 'GET', path: '/api/admin/users', owner: 'vendoo.users', policy: 'users.manage', csrf: false, stability: 'stable',
    handler: async (_req, res) => res.json(getUsersService().list()),
  });
  routes.register(app, {
    id: 'users.admin.invite', method: 'POST', path: '/api/admin/users/invite', owner: 'vendoo.users', policy: 'users.manage', csrf: true, stability: 'stable',
    input: objectSchema({ email: emailRule, name: { type: 'string', maxLength: 120 }, role: { type: 'string', enum: roles }, method: { type: 'string', enum: ['magic_link','auto_password'] } }),
    handler: async (req, res) => {
      const prepared = getUsersService().prepareInvite({ ...req.validatedBody, createdBy: req.user.id });
      const baseUrl = `${req.protocol}://${req.get('host')}`;
      if (prepared.mode === 'auto_password') {
        const mailResult = await deps.sendCredentials(prepared.user.email, prepared.password, prepared.user.name || '', baseUrl);
        deps.auditLog(req.user.id, req.user.email, 'user.invited', 'user', prepared.user.email, `Rolle: ${prepared.role}, Auto-Passwort`, deps.getClientIp(req));
        return res.json({ ok: true, emailSent: mailResult.sent, consoleFallback: mailResult.consoleFallback || false, password: prepared.password });
      }
      const result = await deps.sendMagicLink(prepared.email, prepared.invite.token, baseUrl, 'invite');
      deps.auditLog(req.user.id, req.user.email, 'user.invited', 'user', prepared.email, `Rolle: ${prepared.role}`, deps.getClientIp(req));
      res.json({ ok: true, emailSent: result.sent, consoleFallback: result.consoleFallback || false });
    },
  });
  routes.register(app, {
    id: 'users.admin.invite-resend', method: 'POST', path: '/api/admin/users/resend-invite', owner: 'vendoo.users', policy: 'users.manage', csrf: true, stability: 'stable',
    input: objectSchema({ user_id: { type: 'integer', required: true, min: 1 } }),
    handler: async (req, res) => {
      const prepared = getUsersService().resendInvite({ userId: req.validatedBody.user_id, createdBy: req.user.id });
      const result = await deps.sendMagicLink(prepared.user.email, prepared.invite.token, `${req.protocol}://${req.get('host')}`, 'invite');
      deps.auditLog(req.user.id, req.user.email, 'user.invite_resent', 'user', String(prepared.user.id), null, deps.getClientIp(req));
      res.json({ ok: true, emailSent: result.sent, consoleFallback: result.consoleFallback || false });
    },
  });
  routes.register(app, {
    id: 'users.admin.update', method: 'PUT', path: '/api/admin/users/:id', owner: 'vendoo.users', policy: 'users.manage', csrf: true, stability: 'stable',
    input: objectSchema({ name: { type: 'string', maxLength: 120 }, role: { type: 'string', enum: roles }, active: { type: 'integer', min: 0, max: 1 }, avatar_color: { type: 'string', maxLength: 32 } }),
    handler: async (req, res) => {
      const updated = getUsersService().updateManagedUser({ actor: req.user, userId: Number(req.params.id), patch: req.validatedBody });
      deps.auditLog(req.user.id, req.user.email, 'user.updated', 'user', String(req.params.id), JSON.stringify(req.validatedBody), deps.getClientIp(req));
      res.json(updated);
    },
  });
  routes.register(app, {
    id: 'users.admin.delete', method: 'DELETE', path: '/api/admin/users/:id', owner: 'vendoo.users', policy: 'users.manage', csrf: true, stability: 'stable',
    handler: async (req, res) => {
      const deleted = getUsersService().deleteManagedUser({ actor: req.user, userId: Number(req.params.id) });
      deps.auditLog(req.user.id, req.user.email, 'user.deleted', 'user', String(req.params.id), deleted.email, deps.getClientIp(req));
      res.json({ ok: true });
    },
  });
  routes.register(app, {
    id: 'users.admin.password-reset', method: 'POST', path: '/api/admin/users/:id/reset-password', owner: 'vendoo.users', policy: 'users.manage', csrf: true, stability: 'stable',
    input: objectSchema({ password: { type: 'string', required: true, maxLength: 512, trim: false } }),
    handler: async (req, res) => {
      const user = getUsersService().resetPassword({ userId: Number(req.params.id), password: req.validatedBody.password });
      deps.auditLog(req.user.id, req.user.email, 'user.password_reset', 'user', String(req.params.id), `für ${user.email}`, deps.getClientIp(req));
      res.json({ ok: true, message: `Passwort für ${user.email} zurückgesetzt` });
    },
  });
  routes.register(app, {
    id: 'users.admin.login-history', method: 'GET', path: '/api/admin/users/:id/login-history', owner: 'vendoo.users', policy: 'users.manage', csrf: false, stability: 'stable',
    handler: async (req, res) => res.json(getUsersService().loginHistory(Number(req.params.id), 30)),
  });
  routes.register(app, {
    id: 'users.admin.login-history-compat', method: 'GET', path: '/api/admin/login-history/:userId', owner: 'vendoo.users', policy: 'users.manage', csrf: false, stability: 'deprecated',
    handler: async (req, res) => res.json(getUsersService().loginHistory(Number(req.params.userId), 20)),
  });
}
