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 ${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
