import { Router } from 'express';
import * as controller from '../controllers/tenantAdmin.controller.js';
import validate from '../middlewares/validate.js';
import verifyFirebaseToken from '../middlewares/verifyFirebaseToken.js';
import tenantAccess from '../middlewares/tenantAccess.js';
import methodNotAllowed from '../middlewares/methodNotAllowed.js';
import { imageUpload } from '../middlewares/upload.js';
import { decodeId } from '../utils/idCodec.js';
import { errorResponse } from '../utils/response.js';
import {
  createDepartmentSchema, createTeamSchema, setupSchema, subscriptionRequestSchema, updateDepartmentSchema,
  updateTeamSchema, updateTenantOrganizationSchema, updateTenantUserSchema, userStatusSchema, roleSchema, moduleAccessSchema, inviteUsersSchema, projectMembersSchema, updateProjectMemberSchema,
  projectSetupSchema,
} from '../validators/tenantAdmin.validator.js';

// The tenant app's Administration module. Every route runs as the signed-in
// user's organization and checks module + permission like the app does
// (same rules as the tenant app's API contract table).
const router = Router();
router.use(verifyFirebaseToken);

// Ids in the URL are base64url-encoded.
for (const param of ['id', 'projectId', 'userId']) {
  router.param(param, (req, res, next, value: string) => {
    const decoded = decodeId(value);
    if (decoded === null) return void errorResponse(res, 'Invalid id', 400);
    req.params[param] = String(decoded);
    next();
  });
}

const ADMIN = 'tenant_admin' as const;
const anyAdmin = tenantAccess({ module: ADMIN });
const orgManage = tenantAccess({ module: ADMIN, permission: 'admin.organization.manage' });
const usersView = tenantAccess({ module: ADMIN, permission: 'admin.users.view' });
const usersManage = tenantAccess({ module: ADMIN, permission: 'admin.users.manage' });
const rolesView = tenantAccess({ module: ADMIN, permission: 'admin.roles.view' });
const rolesManage = tenantAccess({ module: ADMIN, permission: 'admin.roles.manage' });
const membersManage = tenantAccess({ module: 'project_core', permission: 'project.members.manage' });
const projectsManage = tenantAccess({ module: 'project_core', permission: 'project.projects.manage' });

router.get('/organization', orgManage, controller.getOrganization);
router.patch('/organization', orgManage, validate(updateTenantOrganizationSchema), controller.updateOrganization);
router.all('/organization', methodNotAllowed('GET', 'PATCH'));
// Logo upload (multipart `file`: JPG, PNG, WebP or SVG up to 5 MB), stored in S3.
router.post('/organization/logo', orgManage, imageUpload, controller.uploadLogo);
router.delete('/organization/logo', orgManage, controller.removeLogo);
router.all('/organization/logo', methodNotAllowed('POST', 'DELETE'));

router.get('/subscription', anyAdmin, controller.getSubscription);
router.all('/subscription', methodNotAllowed('GET'));
router.post('/subscription/requests', orgManage, validate(subscriptionRequestSchema), controller.createSubscriptionRequest);
router.all('/subscription/requests', methodNotAllowed('POST'));

router.get('/setup', orgManage, controller.getSetup);
router.patch('/setup', orgManage, validate(setupSchema), controller.updateSetup);
router.all('/setup', methodNotAllowed('GET', 'PATCH'));

router.get('/departments', anyAdmin, controller.getDepartments);
router.post('/departments', orgManage, validate(createDepartmentSchema), controller.createDepartment);
router.all('/departments', methodNotAllowed('GET', 'POST'));
router.patch('/departments/:id', orgManage, validate(updateDepartmentSchema), controller.updateDepartment);
router.delete('/departments/:id', orgManage, controller.deleteDepartment);
router.all('/departments/:id', methodNotAllowed('PATCH', 'DELETE'));

router.post('/teams', orgManage, validate(createTeamSchema), controller.createTeam);
router.all('/teams', methodNotAllowed('POST'));
router.patch('/teams/:id', orgManage, validate(updateTeamSchema), controller.updateTeam);
router.delete('/teams/:id', orgManage, controller.deleteTeam);
router.all('/teams/:id', methodNotAllowed('PATCH', 'DELETE'));

router.get('/users', usersView, controller.getUsers);
router.all('/users', methodNotAllowed('GET'));
// Everyone, lightly (pickers, duplicate checks); registered before /users/:id.
router.get('/users/options', usersView, controller.getUserOptions);
router.all('/users/options', methodNotAllowed('GET'));
router.get('/users/:id', usersView, controller.getUser);
router.patch('/users/:id', usersManage, validate(updateTenantUserSchema), controller.updateUser);
router.all('/users/:id', methodNotAllowed('GET', 'PATCH'));
router.patch('/users/:id/status', usersManage, validate(userStatusSchema), controller.setUserStatus);
router.all('/users/:id/status', methodNotAllowed('PATCH'));
router.post('/users/:id/invite', usersManage, controller.resendInvite);
router.all('/users/:id/invite', methodNotAllowed('POST'));
router.post('/users/:id/reset-password', usersManage, controller.resetPassword);
router.all('/users/:id/reset-password', methodNotAllowed('POST'));

router.post('/invites', usersManage, validate(inviteUsersSchema), controller.inviteUsers);
router.all('/invites', methodNotAllowed('POST'));

router.get('/roles', rolesView, controller.getRoles);
router.post('/roles', rolesManage, validate(roleSchema), controller.createRole);
router.all('/roles', methodNotAllowed('GET', 'POST'));
router.get('/roles/:id', rolesView, controller.getRole);
router.patch('/roles/:id', rolesManage, validate(roleSchema), controller.updateRole);
router.delete('/roles/:id', rolesManage, controller.deleteRole);
router.all('/roles/:id', methodNotAllowed('GET', 'PATCH', 'DELETE'));

router.put('/module-access', rolesManage, validate(moduleAccessSchema), controller.setModuleAccess);
router.all('/module-access', methodNotAllowed('PUT'));

// Projects & sites setup (the minimal Project Core master; the full project flow is Phase 3).
router.get('/projects', projectsManage, controller.getSetupProjects);
router.post('/projects', projectsManage, validate(projectSetupSchema), controller.createSetupProject);
router.all('/projects', methodNotAllowed('GET', 'POST'));
router.put('/projects/:projectId', projectsManage, validate(projectSetupSchema), controller.updateSetupProject);
router.delete('/projects/:projectId', projectsManage, controller.deleteSetupProject);
router.all('/projects/:projectId', methodNotAllowed('PUT', 'DELETE'));

router.get('/project-access', membersManage, controller.getProjectAccess);
router.all('/project-access', methodNotAllowed('GET'));
router.post('/project-access/:projectId/members', membersManage, validate(projectMembersSchema), controller.addProjectMembers);
router.all('/project-access/:projectId/members', methodNotAllowed('POST'));
router.patch('/project-access/:projectId/members/:userId', membersManage, validate(updateProjectMemberSchema), controller.updateProjectMember);
router.delete('/project-access/:projectId/members/:userId', membersManage, controller.removeProjectMember);
router.all('/project-access/:projectId/members/:userId', methodNotAllowed('PATCH', 'DELETE'));

export default router;
