import { Router } from 'express';

class JamiRestApi {
  constructor(jami) {
    this.jami = jami;
  }

  getRouter() {
    const router = Router({ mergeParams: true });
    //router.use(express.json())

    // Accounts
    router.get('/accounts', async (req, res) => {
      console.log('Get account list');
      let accounts = this.jami.getAccountList();
      if (req.user.accountFilter) accounts = accounts.filter((account) => req.user.accountFilter(account.getId()));
      res.json(await Promise.all(accounts.map(async (account) => await account.getSummary())));
    });

    const checkCanCreateAccounts = (req, res, next) => {
      console.log(`checkCanCreateAccounts ${req.params.accountId} for ${req.user.id}`);
      if (req.user && !req.user.accountFilter) {
        return next();
      }
      res.status(403).end();
    };

    router.post('/accounts', checkCanCreateAccounts, async (req, res) => {
      console.log('Create new account');
      console.log(req.body);
      try {
        const accountId = await this.jami.addAccount(req.body);
        if (req.body.registerName) {
          this.jami
            .registerName(accountId, '', req.body.registerName)
            .then((result) => console.log('Name registrtion result: ' + result));
        }
        res.json({ accountId });
      } catch (e) {
        res.status(400).json({ error: e });
      }
    });

    const checkAccount = (req, res, next) => {
      console.log(`checkAccount ${req.params.accountId} for ${req.user.id}`);
      if (req.user && (!req.user.accountFilter || req.user.accountFilter(req.params.accountId))) {
        return next();
      }
      res.status(403).end();
    };

    const accountRouter = Router({ mergeParams: true });
    router.use('/accounts/:accountId', checkAccount, accountRouter);

    accountRouter.get('/', async (req, res) => {
      console.log(`Get account ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        account.defaultModerators = this.jami.getDefaultModerators(account.getId());
        const obj = await account.getObject();
        obj.devices = this.jami.getDevices(req.params.accountId);
        res.json(obj);
      } else res.status(404).end();
    });

    accountRouter.post('/', async (req, res) => {
      console.log(`Set account details ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        const newDetails = account.updateDetails(req.body);
        this.jami.setAccountDetails(account.getId(), newDetails);
        res.status(200).end();
      } else res.status(404).end();
    });

    // Contacts
    accountRouter.get('/contacts', (req, res) => {
      console.log(`Get account ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        let rep = account.getContacts();
        res.json(rep);
      } else res.status(404).end();
    });

    accountRouter.get('/contacts/:contactId', (req, res) => {
      console.log(`Get account details fot ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      const uri = req.params.uri;
      if (account) {
        let rep = account.getContactDetails(uri);
        res.json(rep);
      } else res.status(404).end();
    });

    accountRouter.get('/contacts/details/:contactId', (req, res) => {
      console.log(`Get contact ${req.params.contactId} details for ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        let rep = this.jami.getContactDetails(req.params.accountId, req.params.contactId);

        console.log(rep);
        res.json(rep);
      } else res.status(404).end();
    });

    accountRouter.delete('/contacts/remove/:contactId', async (req, res) => {
      console.log('REMOVED CONTACT: ', req.params.contactId);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        let rep = this.jami.removeContact(req.params.accountId, req.params.contactId);
        res.json(rep);
      } else res.status(404).end();
      res.status(200).end();
    });

    accountRouter.delete('/contacts/block/:contactId/', async (req, res) => {
      console.log('REMOVED AND BLOCKED CONTACT: ', req.params.contactId);
      const account = this.jami.getAccount(req.params.accountId);
      if (account) {
        let rep = this.jami.blockContact(req.params.accountId, req.params.contactId);
        res.json(rep);
      } else res.status(404).end();
      res.status(200).end();
    });

    // Default modertors
    accountRouter.put('/defaultModerators/:contactId', async (req, res) => {
      console.log(`Adding default moderator ${req.params.contactId} to account ${req.params.accountId}`);
      this.jami.addDefaultModerator(req.params.accountId, req.params.contactId);
      res.status(200).end();
    });

    accountRouter.delete('/defaultModerators/:contactId', async (req, res) => {
      console.log(`Removing default moderator to account ${req.params.accountId}`);
      this.jami.removeDefaultModerator(req.params.accountId, req.params.contactId);
      res.status(200).end();
    });

    // Conversations
    accountRouter.get('/conversations', async (req, res, next) => {
      console.log(`Get conversations for account ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (!account) return res.sendStatus(404);
      const conversations = account.getConversations();
      res.json(
        await Promise.all(
          Object.keys(conversations).map(
            async (conversationId) =>
              await conversations[conversationId].getObject({
                memberFilter: (member) => member.contact.getUri() !== account.getUri(),
              })
          )
        )
      );
      //res.json(account.getConversations())
    });

    accountRouter.post('/conversations', (req, res) => {
      console.log(`Create conversations for account, contact ${req.params.accountId}`);
      // console.log(req.body)
      const account = this.jami.getAccount(req.params.accountId);
      if (!account) return res.sendStatus(404);
      if (req.body.members.length === 1) {
        const details = this.jami.addContact(req.params.accountId, req.body.members[0]);
        res.json(details);
      } else res.status(400).end();
    });

    accountRouter.post('/conversations/:conversationId', async (req, res) => {
      console.log(`Sending message to ${req.params.conversationId} for account ${req.params.accountId}`);
      this.jami.sendMessage(req.params.accountId, req.params.conversationId, req.body.message);
      res.status(200).end();
    });

    accountRouter.get('/conversations/:conversationId', async (req, res) => {
      console.log(`Get conversation ${req.params.conversationId} for account ${req.params.accountId}`);
      const account = this.jami.getAccount(req.params.accountId);
      if (!account) return res.sendStatus(404);
      const conversation = account.getConversation(req.params.conversationId);
      if (!conversation) res.status(404).end();
      else {
        res.json(
          await conversation.getObject({
            memberFilter: (member) => member.contact.getUri() !== account.getUri(),
          })
        );
      }
    });

    accountRouter.get('/conversations/:conversationId/messages', async (req, res) => {
      console.log(`Get messages for conversation ${req.params.conversationId} for account ${req.params.accountId}`);
      try {
        const messages = await this.jami.loadMessages(req.params.accountId, req.params.conversationId);
        res.json(messages).end();
      } catch (e) {
        res.status(400).json({ error: e.message });
      }
    });

    // Calls

    accountRouter.get('/calls', async (req, res) => {
      console.log(`Get calls for account ${req.params.accountId}`);
      try {
        const calls = await this.jami.getCalls(req.params.accountId);
        res.json(calls).end();
      } catch (e) {
        res.status(400).json({ error: e.message });
      }
    });

    accountRouter.get('/calls/:callId', async (req, res) => {
      console.log(`Get call ${req.params.callId} for account ${req.params.accountId}`);
      try {
        const messages = await this.jami.getCall(req.params.accountId, req.params.callId);
        res.json(messages).end();
      } catch (e) {
        res.status(400).json({ error: e.message });
      }
    });

    // Nameserver
    const nsRouter = Router({ mergeParams: true });
    accountRouter.use('/ns', nsRouter); // use account nameserver
    router.use('/ns', nsRouter); // use default nameserver

    nsRouter.get(['/name/:nameQuery'], (req, res, next) => {
      console.log(`Name lookup ${req.params.nameQuery}`);
      this.jami
        .lookupName(req.params.accountId || '', req.params.nameQuery)
        .then((result) => {
          if (result.state == 0) res.json(result);
          else if (result.state == 1) res.status(400).json({});
          else res.status(404).json({});
        })
        .catch((e) => {
          res.status(404).json({});
        });
    });

    nsRouter.get(['/addr/:addrQuery'], (req, res, next) => {
      console.log(`Address lookup ${req.params.addrQuery}`);
      this.jami
        .lookupAddress(req.params.accountId || '', req.params.addrQuery)
        .then((result) => {
          if (result.state == 0) res.json(result);
          else if (result.state == 1) res.status(400).json({});
          else res.status(404).json({});
        })
        .catch((e) => {
          res.status(404).json({});
        });
    });

    return router;
  }
}

export default JamiRestApi;
