const express = require('express');
const cors = require('cors');
const app = express();
const passport = require('passport');
const path = require('path');
const fs = require('fs');
const bodyParser = require('body-parser');
const db = require('./db/models');
const config = require('./config');
const swaggerUI = require('swagger-ui-express');
const swaggerJsDoc = require('swagger-jsdoc');

const authRoutes = require('./routes/auth');
const fileRoutes = require('./routes/file');
const searchRoutes = require('./routes/search');
const pexelsRoutes = require('./routes/pexels');

const organizationForAuthRoutes = require('./routes/organizationLogin');

const openaiRoutes = require('./routes/openai');

const contactFormRoutes = require('./routes/contactForm');

const usersRoutes = require('./routes/users');

const cameras_ptzRoutes = require('./routes/cameras_ptz');

const epcsRoutes = require('./routes/epcs');

const episRoutes = require('./routes/epis');

const equipes_trabalhoRoutes = require('./routes/equipes_trabalho');

const estrutura_projetoRoutes = require('./routes/estrutura_projeto');

const etapas_ou_trechosRoutes = require('./routes/etapas_ou_trechos');

const frames_imagemRoutes = require('./routes/frames_imagem');

const gemeos_digitaisRoutes = require('./routes/gemeos_digitais');

const historico_alteracoes_projetoRoutes = require('./routes/historico_alteracoes_projeto');

const inspecao_aereaRoutes = require('./routes/inspecao_aerea');

const maquinas_atividadeRoutes = require('./routes/maquinas_atividade');

const materiais_atividadeRoutes = require('./routes/materiais_atividade');

const membros_equipeRoutes = require('./routes/membros_equipe');

const memoriais_descritivos_asbuiltRoutes = require('./routes/memoriais_descritivos_asbuilt');

const modelos_bim_asbuiltRoutes = require('./routes/modelos_bim_asbuilt');

const obrasRoutes = require('./routes/obras');

const permissoes_moduloRoutes = require('./routes/permissoes_modulo');

const pessoas_atividadeRoutes = require('./routes/pessoas_atividade');

const pessoas_frameRoutes = require('./routes/pessoas_frame');

const plantas_asbuilt_2dRoutes = require('./routes/plantas_asbuilt_2d');

const relatorio_andamento_atualRoutes = require('./routes/relatorio_andamento_atual');

const relatorios_analiticos_videoRoutes = require('./routes/relatorios_analiticos_video');

const relatorios_diariosRoutes = require('./routes/relatorios_diarios');

const relatorios_mensaisRoutes = require('./routes/relatorios_mensais');

const relatorios_semanaisRoutes = require('./routes/relatorios_semanais');

const subcontratadasRoutes = require('./routes/subcontratadas');

const usuariosRoutes = require('./routes/usuarios');

const rolesRoutes = require('./routes/roles');

const permissionsRoutes = require('./routes/permissions');

const clientesRoutes = require('./routes/clientes');

const getBaseUrl = (url) => {
  if (!url) return '';
  return url.endsWith('/api') ? url.slice(0, -4) : url;
};

const options = {
  definition: {
    openapi: '3.0.0',
    info: {
      version: '1.0.0',
      title: 'Gerenciador e Fiscalizador de Obras Copasa',
      description:
        'Gerenciador e Fiscalizador de Obras Copasa Online REST API for Testing and Prototyping application. You can perform all major operations with your entities - create, delete and etc.',
    },
    servers: [
      {
        url: getBaseUrl(process.env.NEXT_PUBLIC_BACK_API) || config.swaggerUrl,
        description: 'Development server',
      },
    ],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT',
        },
      },
      responses: {
        UnauthorizedError: {
          description: 'Access token is missing or invalid',
        },
      },
    },
    security: [
      {
        bearerAuth: [],
      },
    ],
  },
  apis: ['./src/routes/*.js'],
};

const specs = swaggerJsDoc(options);
app.use(
  '/api-docs',
  function (req, res, next) {
    swaggerUI.host =
      getBaseUrl(process.env.NEXT_PUBLIC_BACK_API) || req.get('host');
    next();
  },
  swaggerUI.serve,
  swaggerUI.setup(specs),
);

app.use(cors({ origin: true }));
require('./auth/auth');

app.use(bodyParser.json());

app.use('/api/auth', authRoutes);
app.use('/api/file', fileRoutes);
app.use('/api/pexels', pexelsRoutes);
app.enable('trust proxy');

app.use(
  '/api/users',
  passport.authenticate('jwt', { session: false }),
  usersRoutes,
);

app.use(
  '/api/cameras_ptz',
  passport.authenticate('jwt', { session: false }),
  cameras_ptzRoutes,
);

app.use(
  '/api/epcs',
  passport.authenticate('jwt', { session: false }),
  epcsRoutes,
);

app.use(
  '/api/epis',
  passport.authenticate('jwt', { session: false }),
  episRoutes,
);

app.use(
  '/api/equipes_trabalho',
  passport.authenticate('jwt', { session: false }),
  equipes_trabalhoRoutes,
);

app.use(
  '/api/estrutura_projeto',
  passport.authenticate('jwt', { session: false }),
  estrutura_projetoRoutes,
);

app.use(
  '/api/etapas_ou_trechos',
  passport.authenticate('jwt', { session: false }),
  etapas_ou_trechosRoutes,
);

app.use(
  '/api/frames_imagem',
  passport.authenticate('jwt', { session: false }),
  frames_imagemRoutes,
);

app.use(
  '/api/gemeos_digitais',
  passport.authenticate('jwt', { session: false }),
  gemeos_digitaisRoutes,
);

app.use(
  '/api/historico_alteracoes_projeto',
  passport.authenticate('jwt', { session: false }),
  historico_alteracoes_projetoRoutes,
);

app.use(
  '/api/inspecao_aerea',
  passport.authenticate('jwt', { session: false }),
  inspecao_aereaRoutes,
);

app.use(
  '/api/maquinas_atividade',
  passport.authenticate('jwt', { session: false }),
  maquinas_atividadeRoutes,
);

app.use(
  '/api/materiais_atividade',
  passport.authenticate('jwt', { session: false }),
  materiais_atividadeRoutes,
);

app.use(
  '/api/membros_equipe',
  passport.authenticate('jwt', { session: false }),
  membros_equipeRoutes,
);

app.use(
  '/api/memoriais_descritivos_asbuilt',
  passport.authenticate('jwt', { session: false }),
  memoriais_descritivos_asbuiltRoutes,
);

app.use(
  '/api/modelos_bim_asbuilt',
  passport.authenticate('jwt', { session: false }),
  modelos_bim_asbuiltRoutes,
);

app.use(
  '/api/obras',
  passport.authenticate('jwt', { session: false }),
  obrasRoutes,
);

app.use(
  '/api/permissoes_modulo',
  passport.authenticate('jwt', { session: false }),
  permissoes_moduloRoutes,
);

app.use(
  '/api/pessoas_atividade',
  passport.authenticate('jwt', { session: false }),
  pessoas_atividadeRoutes,
);

app.use(
  '/api/pessoas_frame',
  passport.authenticate('jwt', { session: false }),
  pessoas_frameRoutes,
);

app.use(
  '/api/plantas_asbuilt_2d',
  passport.authenticate('jwt', { session: false }),
  plantas_asbuilt_2dRoutes,
);

app.use(
  '/api/relatorio_andamento_atual',
  passport.authenticate('jwt', { session: false }),
  relatorio_andamento_atualRoutes,
);

app.use(
  '/api/relatorios_analiticos_video',
  passport.authenticate('jwt', { session: false }),
  relatorios_analiticos_videoRoutes,
);

app.use(
  '/api/relatorios_diarios',
  passport.authenticate('jwt', { session: false }),
  relatorios_diariosRoutes,
);

app.use(
  '/api/relatorios_mensais',
  passport.authenticate('jwt', { session: false }),
  relatorios_mensaisRoutes,
);

app.use(
  '/api/relatorios_semanais',
  passport.authenticate('jwt', { session: false }),
  relatorios_semanaisRoutes,
);

app.use(
  '/api/subcontratadas',
  passport.authenticate('jwt', { session: false }),
  subcontratadasRoutes,
);

app.use(
  '/api/usuarios',
  passport.authenticate('jwt', { session: false }),
  usuariosRoutes,
);

app.use(
  '/api/roles',
  passport.authenticate('jwt', { session: false }),
  rolesRoutes,
);

app.use(
  '/api/permissions',
  passport.authenticate('jwt', { session: false }),
  permissionsRoutes,
);

app.use(
  '/api/clientes',
  passport.authenticate('jwt', { session: false }),
  clientesRoutes,
);

app.use(
  '/api/openai',
  passport.authenticate('jwt', { session: false }),
  openaiRoutes,
);

app.use('/api/contact-form', contactFormRoutes);

app.use(
  '/api/search',
  passport.authenticate('jwt', { session: false }),
  searchRoutes,
);

app.use('/api/org-for-auth', organizationForAuthRoutes);

const publicDir = path.join(__dirname, '../public');

if (fs.existsSync(publicDir)) {
  app.use('/', express.static(publicDir));

  app.get('*', function (request, response) {
    response.sendFile(path.resolve(publicDir, 'index.html'));
  });
}

const PORT = process.env.NODE_ENV === 'dev_stage' ? 3000 : 8080;

db.sequelize.sync().then(function () {
  app.listen(PORT, () => {
    console.log(`Listening on port ${PORT}`);
  });
});

module.exports = app;
