'use strict'
const {validate, rule} = use('Validator');
const User = use('App/Models/User');
const Child = use('App/Models/Child')
const Link = use('App/Models/Link');
const Call = use('App/Models/Call');
const Book = use('App/Models/Book');

const FileUtils = use('App/Utils/FileUtils');
const UserChildUtils = use('App/Utils/UserChildUtils');
const {v4: uuidv4} = require('uuid');
class ClientApiController {
  async getUser({auth}) {
    const user = auth.user.toJSON();
    const connections = await UserChildUtils.getUserConnections(user.id);
    const booksResponse = await Book.query()
                              .where({user_id: null})
                              .orWhere({user_id: user.id})
                              .fetch();
    let books = [];
    if (booksResponse.rows.length) books = booksResponse.rows;
    return {
      ...user, connections: {...connections}, books
    }
  }

  async createChild({auth, request, response}) {
    const rules = {
      name: 'required|string',
      dob: 'required|date',
      avatar: [rule('regex', /^(data:image\/\w+;base64).+/)]
    };
    const validation = await validate(request.all(), rules);
    if (validation.fails()) {
      response.status(400);
      response.send({code: 400, message: validation.messages()});
      return false;
    }
    const body = request.body;
    if (body.avatar) {
      const file = await FileUtils.saveBase64File(body.avatar);
      body.avatar = `/u/images/${file.fileName}`;
    } else {
      body.avatar = `/images/default-child-avatar.png`;
    }
    const child = await Child.create(body);
    const link = await Link.create(
        {user_id: auth.user.id, child_id: child.id, is_parent: true});
    response.status(201);
    return {code: 201, child};
  }

  async getBooks() {}

  async getCallBooks() {}

  async createCall({auth, request, response}) {
    try {
      const user = auth.user;
      const rules = {
        connection_id: 'number|required',
        child_id: 'number|required',
      };
      const validation = await validate(request.all(), rules);
      if (validation.fails()) {
        response.status(400);
        response.send(validation.messages());
        return false;
      }
      const body = request.body;
      if (!(await UserChildUtils.isParentOf(user.id, body.child_id))) {
        response.status(403);
        response.send({code: 403, message: 'Unauthorized'});
        return false;
      }
      if (!(await UserChildUtils.isUserConnectedToChild(
              body.connection_id, body.child_id))) {
        response.status(403);
        response.send({code: 403, message: 'Unauthorized'});
        return false;
      }
      const call = await Call.create({
        state: 'NEW',
        parent_id: user.id,
        guest_id: body.connection_id,
        child_id: body.child_id
      });
      return {
        code: 0, data: call
      }
    } catch (error) {
      console.error(error);
      return error;
    }
  }

  async getChild({auth, request, response}) {
    const userId = auth.user.id;
    const childId = request.params.id;
    console.log(`${userId} -> ${childId}`);
    const hasPermission =
        await UserChildUtils.isUserConnectedToChild(userId, childId);
    if (!hasPermission) {
      response.status(403);
      response.send(
          {code: 403, message: `You have no permission to connect with child`});
      return false;
    }
    const child = await Child.find(childId);
    const parents = await UserChildUtils.getChildParents(childId);
    const connections = await UserChildUtils.getChildConnections(childId);
    return {
      code: 0, data: {...child.toJSON(), parents, connections}
    }
  }

  async createConnection({request, auth, response}) {
    try {
      const user = auth.user;
      const rules = {
        email: 'string|email|required',
        is_parent: 'boolean|required',
        child_id: 'number|required'
      };
      const validation = await validate(request.all(), rules);
      if (validation.fails()) {
        response.status(400);
        response.send(validation.messages());
        return false;
      }
      const body = request.body;
      if (!await UserChildUtils.isParentOf(user.id, body.child_id)) {
        response.status(403);
        response.send({
          code: 403,
          message: `You have no permission to add connection to child`
        });
        return false;
      }
      const usersWithEmail =
          (await User.query().where({email: body.email}).fetch()).rows;
      if (!usersWithEmail.length) {
        return {code: 404, message: 'No user with that Email...'};
      }
      const targetUser = usersWithEmail[0];
      if (await UserChildUtils.isUserConnectedToChild(
              targetUser.id, body.child_id)) {
        return {code: 409, message: 'User already connected'};
      }
      return {
        code: 0,
        data: await UserChildUtils.addConnection(
            body.child_id, targetUser.id, body.is_parent)
      };
    } catch (error) {
      console.error(error);
      return error;
    }
    //
  }

  async updateChild({request, auth, response}) {
    const childId = request.params.id;
    const userId = auth.user.id;
    const {name, dob, profile_cover, avatar} = request.body;
    const isParent = await UserChildUtils.isParentOf(userId, childId);
    if (!isParent) {
      response.status(403);
      response.send(
          {code: 403, message: `You have no permission to edit this child`});
      return false;
    }
    // TODO: Add validation;
    const child = await Child.find(childId);
    child.dob = dob || child.dob;
    if (profile_cover) {
      const file = await FileUtils.saveBase64File(profile_cover);
      child.profile_cover = `/u/images/${file.fileName}`;
    }
    if (avatar) {
      const file = await FileUtils.saveBase64File(body.avatar);
      child.avatar = `/u/images/${file.fileName}`;
    }
    await child.save();
    return {code: 0, data: {child}};
  }

  async setChildProfileCover({request, auth, response}) {
    try {
      const rules = {
        profile_cover: [rule('regex', /^(data:image\/\w+;base64).+/)]
      };
      const validation = await validate(request.all(), rules);
      if (validation.fails()) {
        response.status(400);
        response.send(validation.messages());
        return false;
      }
      const body = request.body;
      const userId = auth.user.id;
      const childId = request.params.id;
      const isParent = await UserChildUtils.isParentOf(userId, childId);
      if (!isParent) {
        response.status(403);
        response.send(
            {code: 403, message: `You have no permission to edit this child`});
        return false;
      }
      const child = await Child.find(childId);
      const file = await FileUtils.saveBase64File(body.profile_cover);
      console.log(file);
      child.profile_cover = `/u/images/${file.fileName}`;
      await child.save();
      return child.profile_cover;

    } catch (error) {
      console.error(error);
      return error;
    }
  }
}

module.exports = ClientApiController
