import { Router } from 'express';
import { AppDataSource } from '../data-source';
import { Client } from '../entity/Client';
import { Address } from '../entity/Address';
import { TypeStudent } from '../entity/TypeStudent';
import { Student } from '../entity/Student';
import { isUndefined } from 'util';
import { authentificationToken } from '../middleware/auth';
import { ClientType } from '../entity/ClientType';

const router = Router();

router.get('/clients', authentificationToken, async (req, res) => {
  try {
    const repo = AppDataSource.getRepository(Client);
    const clients = await repo.find({
      relations: [
        'Students',
        'ClientType',
        'Addresses',
        'Students.TypeStudent',
        'Students.TitleStudent',
        'Classes',
        'Classes.ClassesDetails.Students',
        'Classes.ClassesDetails',
        'Classes.ClassesDetails.Course'
      ]
    });
    res.send(clients);
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
});

router.get('/client/:id', authentificationToken, async (req, res) => {
  try {
    const repo = AppDataSource.getRepository(Client);
    const client = await repo.findOne({
      where: { id: parseInt(req.params.id) },
      relations: [
        'Students',
        'ClientType',
        'Addresses',
        'Students.TypeStudent',
        'Students.TitleStudent',
        'Students.Client',
        'Classes',
        'Classes.User',
        'Classes.TeachingMode',
        'Classes.ClassesDetails',
        'Classes.ClassesDetails.Students',
        'Classes.ClassesDetails.Course'
      ]
    });
    res.send(client);
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
});

router.post('/addclient', authentificationToken, async (req, res) => {
  try {
    const clientRepo = AppDataSource.getRepository(Client);
    const studentRepo = AppDataSource.getRepository(Student);
    const addressRepo = AppDataSource.getRepository(Address);
    const typeStudentRepo = AppDataSource.getRepository(TypeStudent);

    const client = clientRepo.create(req.body)[0];
    const results = await clientRepo.save(client);

    const typeStudent = await typeStudentRepo.findOne({ where: { name: 'Provider' } });

    client.Students = results.Students;
    client.Students[0].Client = { id: results.id } as Client;
    client.Students[0].TypeStudent = { id: typeStudent?.id } as TypeStudent;

    client.Addresses = results.Addresses;
    client.Addresses[0].Client = { id: results.id } as Client;

    await studentRepo.save(client.Students);
    await addressRepo.save(client.Addresses);

    res.send(results);
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
});

router.put('/updateclient/:id', authentificationToken, async (req, res) => {
  try {
    const repo = AppDataSource.getRepository(Client);
    const addressRepo = AppDataSource.getRepository(Address);

    const client = await repo.findOne({
      where: { id: parseInt(req.params.id) },
      relations: ['Students', 'Students.TypeStudent', 'Students.TitleStudent']
    });
    repo.merge(client, req.body);
    const results = await repo.save(client);

    for (const a of req.body.Addresses) {
      if (isUndefined(a.id) || a.id === null) {
        const address = addressRepo.create(a)[0];
        address.Client = results;
        await addressRepo.save(address);
      } else {
        const address = await addressRepo.findOne({ where: { id: a.id } });
        addressRepo.merge(address, a);
        await addressRepo.save(address);
      }
    }
    res.send(results);
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
});

router.delete('/deleteclient/:id', authentificationToken, async (req, res) => {
  try {
    const repo = AppDataSource.getRepository(Client);
    const client = await repo.findOne({
      where: { id: parseInt(req.params.id) },
      relations: ['Students', 'Students.TypeStudent', 'Students.TitleStudent']
    });
    client.enable = false;
    const results = await repo.save(client);
    res.send(results);
  } catch (error) {
    console.error(error);
    res.sendStatus(500);
  }
});

router.post('/addaddress', authentificationToken, async (req, res) => {
    try {
         const addressRepo = AppDataSource.getRepository(Address);
         const address = addressRepo.create(req.body);
         const results = await addressRepo.save(address);
         res.send(results);
  } catch (error) {
      console.error(error);
     res.sendStatus(500);
  }
 

 });

 router.put('/updateaddresses', authentificationToken, function (req, res) { 
  
    try {
        const addressRepo = AppDataSource.getRepository(Address);
        let Addresses : Array<Address> = req.body;
        Addresses.forEach(async a => {
            const address = await addressRepo.findOne({
              where: { id: a.id },
            });
            addressRepo.merge(address, a);
            await addressRepo.save(address);
        })
        res.send(true);
  } catch (error) {
      console.error(error);
     res.sendStatus(500);
  }

 });

 
 router.get('/clienttypes', async function (req, res) {
    
  try {
         const clientTypeRepository = AppDataSource.getRepository(ClientType);
         let clientTypes = await clientTypeRepository.find();
         res.send(clientTypes);
  } catch (error) {
      console.error(error);
     res.sendStatus(500);
  }
 });

 router.post('/addclienttype', authentificationToken, async function (req, res) {
         const ClientTypeTypeRepository = AppDataSource.getRepository(ClientType);
         const clientType = await ClientTypeTypeRepository.create(req.body);
         const results = await ClientTypeTypeRepository.save(clientType);
         res.send(results);
 });

router.put('/updateclienttype/:id', authentificationToken, async function (req, res) {
    
         const ClientTypeTypeRepository = AppDataSource.getRepository(ClientType);
         const clientType = await ClientTypeTypeRepository.findOneBy({ id: parseInt(req.params.id) });
         ClientTypeTypeRepository.merge(clientType, req.body);
         const results = await ClientTypeTypeRepository.save(clientType);
         res.send(results);
 });

export default router;