/*
|--------------------------------------------------------------------------
| Routes
|--------------------------------------------------------------------------
|
| This file is dedicated for defining HTTP routes. A single file is enough
| for majority of projects, however you can define routes in different
| files and just make sure to import them inside this file. For example
|
| Define routes in following two files
| ├── start/routes/cart.ts
| ├── start/routes/customer.ts
|
| and then import them inside `start/routes.ts` as follows
|
| import './routes/cart'
| import './routes/customer''
|
*/

import OaiController from '#controllers/Http/Oai/OaiController';
import router from '@adonisjs/core/services/router';
import type { HttpContext } from '@adonisjs/core/http';
import { authValidator } from '#validators/auth';
import User from '#models/user';
import AuthController from '#controllers/Http/Auth/AuthController';
import UserController from '#controllers/Http/Auth/UserController';
import AdminuserController from '#controllers/Http/Admin/AdminuserController';
import RoleController from '#controllers/Http/Admin/RoleController';
import LicenseController from '#controllers/Http/Admin/LicenseController';
import MimetypeController from '#controllers/Http/Admin/MimetypeController';
import MailSettingsController from '#controllers/Http/Admin/mailsettings_controller';
import DatasetController from '#app/Controllers/Http/Submitter/DatasetController';
import PersonController from '#app/Controllers/Http/Submitter/PersonController';
import EditorDatasetController from '#app/Controllers/Http/Editor/DatasetController';
import ReviewerDatasetController from '#app/Controllers/Http/Reviewer/DatasetController';
import './routes/api.js';
import { middleware } from './kernel.js';
import db from '@adonisjs/lucid/services/db'; // Import the DB service

router.get('/health', ({ response }: HttpContext) => response.noContent());

// OAI routes
router
    .group(() => {
        router.get('/oai', [OaiController, 'index']).as('get');
        router.post('/oai', [OaiController, 'index']).as('post');
    })
    .as('oai');

// Welcome route
router
    .get('/welcome', async ({ view }: HttpContext) => {
        return view.render('welcome');
    })
    .as('welcome');

// Dashboard route
router
    .get('/', async ({ response }: HttpContext) => {
        return response.redirect().toRoute('apps.dashboard');
    })
    .as('dashboard');

// Apps group
router
    .group(() => {
        router
            .get('/dashboard', async ({ inertia }: HttpContext) => {
                return inertia.render('Dashboard');
            })
            .as('dashboard');

        router
            .get('/map', async ({ inertia }: HttpContext) => {
                return inertia.render('Map');
            })
            .as('map');

        router
            .get('/', async ({ inertia }: HttpContext) => {
                const users = await User.query().orderBy('login');
                return inertia.render('App', {
                    testing: 'this is a test',
                    users: users,
                });
            })
            .as('index');

        router
            .get('/register', async ({ inertia }: HttpContext) => {
                return inertia.render('register-view/register-view-component');
            })
            .as('register.show');

        router
            .post('/register', async ({ request, response }: HttpContext) => {
                await request.validateUsing(authValidator);
                return response.redirect().toRoute('app.index');
            })
            .as('register.store');
    })
    .prefix('apps')
    .as('apps')
    .use(middleware.auth());

// Auth routes
router
    .get('/app/login', async({ inertia }: HttpContext) => {
        try {
            await db.connection().rawQuery('SELECT 1');
        } catch (error) {
            if (error.code === 'ECONNREFUSED') {
                throw error;
            }
        }
        return inertia.render('Auth/Login');
    })
    .as('app.login.show');

router.post('/app/login', [AuthController, 'login']).as('login.store');
router.post('/app/twoFactorChallenge', [AuthController, 'twoFactorChallenge']).as('login.twoFactorChallenge');
router.post('/signout', [AuthController, 'logout']).as('logout');

// Administrator routes
router
    .group(() => {
        router
            .get('/settings', async ({ inertia }: HttpContext) => {
                const updatedConfigValue = await db
                    .from('appconfigs')
                    .select('configvalue')
                    .where('appid', 'backgroundjob')
                    .where('configkey', 'lastjob')
                    .first();
                return inertia.render('Admin/Settings', {
                    lastCron: updatedConfigValue?.configvalue || '',
                });
            })
            .as('overview');

        router
            .post('/mail/store', [MailSettingsController, 'setMailSettings'])
            .as('mail.store')
            .use(middleware.can(['user-create']));
        router
            .post('/mail/send', [MailSettingsController, 'sendTestMail'])
            .as('mail.send')
            .use(middleware.can(['user-create']));

        // User routes
        router
            .get('/user', [AdminuserController, 'index'])
            .as('user.index')
            .use(middleware.can(['user-list']));
        router
            .get('/user/create', [AdminuserController, 'create'])
            .as('user.create')
            .use(middleware.can(['user-create']));
        router
            .post('/user/store', [AdminuserController, 'store'])
            .as('user.store')
            .use(middleware.can(['user-create']));
        router.get('/user/:id', [AdminuserController, 'show']).as('user.show').where('id', router.matchers.number());
        router
            .get('/user/:id/edit', [AdminuserController, 'edit'])
            .as('user.edit')
            .where('id', router.matchers.number())
            .use(middleware.can(['user-edit']));
        router
            .put('/user/:id/update', [AdminuserController, 'update'])
            .as('user.update')
            .where('id', router.matchers.number())
            .use(middleware.can(['user-edit']));
        router
            .delete('/user/:id', [AdminuserController, 'destroy'])
            .as('user.destroy')
            .where('id', router.matchers.number())
            .use(middleware.can(['user-delete']));

        // Role routes
        router
            .get('/role', [RoleController, 'index'])
            .as('role.index')
            .use(middleware.can(['user-list']));
        router
            .get('/role/create', [RoleController, 'create'])
            .as('role.create')
            .use(middleware.can(['user-create']));
        router
            .post('/role/store', [RoleController, 'store'])
            .as('role.store')
            .use(middleware.can(['user-create']));
        router.get('/role/:id', [RoleController, 'show']).as('role.show').where('id', router.matchers.number());
        router
            .get('/role/:id/edit', [RoleController, 'edit'])
            .as('role.edit')
            .where('id', router.matchers.number())
            .use(middleware.can(['user-edit']));
        router
            .put('/role/:id/update', [RoleController, 'update'])
            .as('role.update')
            .where('id', router.matchers.number())
            .use(middleware.can(['user-edit']));

        // License routes
        router.get('/license', [LicenseController, 'index']).as('license.index');
        router
            .get('/license/:id/down', [LicenseController, 'down'])
            .as('license.down')
            .where('id', router.matchers.number())
            .use(middleware.can(['settings']));
        router
            .get('/license/:id/up', [LicenseController, 'up'])
            .as('license.up')
            .where('id', router.matchers.number())
            .use(middleware.can(['settings']));

        // Mimetype routes
        router.get('/mimetype', [MimetypeController, 'index']).as('mimetype.index');
        router
            .get('/mimetype/create', [MimetypeController, 'create'])
            .as('mimetype.create')
            .use(middleware.can(['settings']));
        router
            .post('/mimetype/store', [MimetypeController, 'store'])
            .as('mimetype.store')
            .use(middleware.can(['settings']));
        router
            .get('/mimetype/:id/down', [MimetypeController, 'down'])
            .as('mimetype.down')
            .where('id', router.matchers.number())
            .use(middleware.can(['settings']));
        router
            .get('/mimetype/:id/up', [MimetypeController, 'up'])
            .as('mimetype.up')
            .where('id', router.matchers.number())
            .use(middleware.can(['settings']));
        router
            .get('/mimetype/:id/delete', [MimetypeController, 'delete'])
            .as('mimetype.delete')
            .use([middleware.auth(), middleware.can(['dataset-delete'])]);
        router
            .delete('/mimetype/:id/deleteStore', [MimetypeController, 'deleteStore'])
            .as('mimetype.deleteStore')
            .use([middleware.auth(), middleware.can(['settings'])]);
    })
    .prefix('admin')
    .as('settings')
    .use([middleware.auth(), middleware.is(['administrator', 'moderator'])]);

router.get('/settings/user/security', [UserController, 'accountInfo']).as('settings.user').use(middleware.auth());
router.post('/settings/user/store', [UserController, 'accountInfoStore']).as('account.password.store').use(middleware.auth());
router.get('/settings/profile/edit', [UserController, 'profile']).as('settings.profile.edit').use(middleware.auth());
router
    .put('/settings/profile/:id/update', [UserController, 'profileUpdate'])
    .as('settings.profile.update')
    .where('id', router.matchers.number())
    .use(middleware.auth());
router.put('/settings/password/update', [UserController, 'passwordUpdate']).as('settings.password.update').use(middleware.auth());

// Submitter routes
router
    .group(() => {
        router
            .get('/dataset', [DatasetController, 'index'])
            .as('dataset.list')
            .use([middleware.auth(), middleware.can(['dataset-list'])]);
        router
            .get('/dataset/create', [DatasetController, 'create'])
            .as('dataset.create')
            .use([middleware.auth(), middleware.can(['dataset-submit'])]);
        router
            .post('/dataset/first/first-step', [DatasetController, 'firstStep'])
            .as('dataset.first.step')
            .use([middleware.auth(), middleware.can(['dataset-submit'])]);
        router
            .post('/dataset/second/second-step', [DatasetController, 'secondStep'])
            .as('dataset.second.step')
            .use([middleware.auth(), middleware.can(['dataset-submit'])]);
        router
            .post('/dataset/second/third-step', [DatasetController, 'thirdStep'])
            .as('dataset.third.step')
            .use([middleware.auth(), middleware.can(['dataset-submit'])]);
        router
            .post('/dataset/submit', [DatasetController, 'store'])
            .as('dataset.submit')
            .use([middleware.auth(), middleware.can(['dataset-submit'])]);
        router
            .get('/dataset/:id/release', [DatasetController, 'release'])
            .as('dataset.release')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
        router
            .put('/dataset/:id/releaseupdate', [DatasetController, 'releaseUpdate'])
            .as('dataset.releaseUpdate')
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
        router
            .get('/dataset/:id/edit', [DatasetController, 'edit'])
            .as('dataset.edit')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
        router
            .put('/dataset/:id/update', [DatasetController, 'update'])
            .as('dataset.update')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
        router
            .get('/dataset/:id/delete', [DatasetController, 'delete'])
            .as('dataset.delete')
            .use([middleware.auth(), middleware.can(['dataset-delete'])]);
        router
            .put('/dataset/:id/deleteupdate', [DatasetController, 'deleteUpdate'])
            .as('dataset.deleteUpdate')
            .use([middleware.auth(), middleware.can(['dataset-delete'])]);
        router.get('/person', [PersonController, 'index']).as('person.index').use([middleware.auth()]);
        router
            .get('/dataset/:id/categorize', [DatasetController, 'categorize'])
            .as('dataset.categorize')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
        router
            .put('/dataset/:id/categorizeUpdate', [DatasetController, 'categorizeUpdate'])
            .as('dataset.categorizeUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-edit'])]);
    })
    .prefix('submitter');

// Editor routes
router
    .group(() => {
        router
            .get('/dataset', [EditorDatasetController, 'index'])
            .as('editor.dataset.list')
            .use([middleware.auth(), middleware.can(['dataset-editor-list'])]);
        router
            .get('dataset/:id/receive', [EditorDatasetController, 'receive'])
            .as('editor.dataset.receive')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-receive'])]);
        router
            .put('dataset/:id/receive', [EditorDatasetController, 'receiveUpdate'])
            .as('editor.dataset.receiveUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-receive'])]);
        router
            .get('dataset/:id/approve', [EditorDatasetController, 'approve'])
            .as('editor.dataset.approve')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-approve'])]);
        router
            .put('dataset/:id/approve', [EditorDatasetController, 'approveUpdate'])
            .as('editor.dataset.approveUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-approve'])]);
        router
            .get('dataset/:id/reject', [EditorDatasetController, 'reject'])
            .as('editor.dataset.reject')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-editor-reject'])]);
        router
            .put('dataset/:id/reject', [EditorDatasetController, 'rejectUpdate'])
            .as('editor.dataset.rejectUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-editor-reject'])]);
        router
            .get('dataset/:id/publish', [EditorDatasetController, 'publish'])
            .as('editor.dataset.publish')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-publish'])]);
        router
            .put('dataset/:id/publish', [EditorDatasetController, 'publishUpdate'])
            .as('editor.dataset.publishUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-publish'])]);
        router
            .get('dataset/:id/doi', [EditorDatasetController, 'doiCreate'])
            .as('editor.dataset.doi')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-publish'])]);
        router
            .put('dataset/:publish_id/doi', [EditorDatasetController, 'doiStore'])
            .as('editor.dataset.doiStore')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-publish'])]);
        router
            .put('/dataset/:id/update', [EditorDatasetController, 'update'])
            .as('editor.dataset.update')
            .use([middleware.auth(), middleware.can(['dataset-editor-edit'])]);
    })
    .prefix('editor');

// Reviewer routes
router
    .group(() => {
        router
            .get('/dataset', [ReviewerDatasetController, 'index'])
            .as('reviewer.dataset.list')
            .use([middleware.auth(), middleware.can(['dataset-review-list'])]);
        router
            .get('dataset/:id/review', [ReviewerDatasetController, 'review'])
            .as('reviewer.dataset.review')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-review'])]);
        router
            .put('dataset/:id/review', [ReviewerDatasetController, 'reviewUpdate'])
            .as('reviewer.dataset.reviewUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-review'])]);
        router
            .get('dataset/:id/reject', [ReviewerDatasetController, 'reject'])
            .as('reviewer.dataset.reject')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-review-reject'])]);
        router
            .put('dataset/:id/reject', [ReviewerDatasetController, 'rejectUpdate'])
            .as('reviewer.dataset.rejectUpdate')
            .where('id', router.matchers.number())
            .use([middleware.auth(), middleware.can(['dataset-review-reject'])]);
    })
    .prefix('reviewer');
