import { pick, merge, bindAll } from 'lodash';
import { action } from 'mobx';

import {
    BaseModel, identifiedBy, field, identifier, computed,
} from './models/base';

import Config from './config';

@identifiedBy('lanes/user-session')
class Session extends BaseModel {
    @identifier id;
    @field login;
    @field password;
    setFromSync(data) {
        this.data = data;
    }
}


@identifiedBy('lanes/user')
export class UserModel extends BaseModel {

    @identifier({ type: 'number' }) id;
    @field login;
    @field name;
    @field email;
    @field password;
    @field password_confirm;

    @field access;

    @computed get isLoggedIn() { return !!Config.access_token; }

    constructor(attrs = {}) {
        super(attrs);
        bindAll(this, 'setFromSessionRequest');
    }

    @action logout() {
        const req = new Session({ id: this.id });
        return req.destroy().then(() => {
            this.reset();
            Config.access_token = '';
            return this;
        });
    }

    @action attemptLogin(login, password) {
        const req = new Session({ login, password });
        return req.save().then(this.setFromSessionRequest);
    }

    @action checkAccess() {
        const req = new Session({ id: 'test' });
        return req.fetch().then(this.setFromSessionRequest);
    }

    setFromSessionRequest(req) {
        merge(this, pick(req, 'errors', 'lastServerMessage'));
        if (req.isValid) {
            this.set(req.data.user);
            this.access = req.data.access;
            this.errors = {};
        }
        return this;
    }
}

const current_user = new UserModel();

export default current_user;


    //     static initClass() {

    //         this.prototype.derived = {
    //             roles: {
    //                 fn() { return []; }
    //             },
    //             isLoggedIn: {
    //                 fn() { return false; }
    //             },
    //             allRoles: {
    //                 fn() { return new Lanes.Models.Role.Collection; }
    //             }
    //         };

    //         this.prototype.session = {
    //             access_data: 'object',
    //             id:          'integer',
    //             login:       'string',
    //             name:        'string',
    //             email:       'string',
    //             role_names:  'array',
    //             options:     'object',
    //             password:    'string'
    //         };
    //     }

    //     constructor(attributes, access) {
    //         super(...arguments);
    //         this.access_data = access;
    //     }

    //     api_path() { return '/users'; }
    //     hasAccess() { return true; }
    //     canRead(model, field) { return true; }
    //     canWrite(model, field) { return true; }
    //     canDelete(model)        { return true; }
    // };
    // undefined.initClass();


// let CURRENT_USER = null;

// Object.defineProperty(Lanes, 'current_user', {

//     set(user) {
//         let events = null;
//         if (CURRENT_USER) {
//             events = CURRENT_USER._events;
//         }
//         if (_.some(events)) {
//             for (let key in events) {
//                 const callbacks = events[key];
//                 if (user._events[key]) {
//                     user._events[key] = user._events[key].concat(callbacks);
//                 } else {
//                     user._events[key] = callbacks;
//                 }
//             }
//         }
//         return CURRENT_USER = user;
//     },

//     get() {
//         return CURRENT_USER;
//     }
// });

@@ -336,16 +336,17 @@
  set
-FromSync
+ syncData
 (dat
@@ -382,16 +382,90 @@
 ;%0A    %7D%0A
+    @computed%0A    get syncData() %7B%0A        return this.serialize();%0A    %7D%0A
 %7D%0A%0A%0A@ide
@@ -766,115 +766,8 @@
  %7D%0A%0A
-    constructor(attrs = %7B%7D) %7B%0A        super(attrs);%0A        bindAll(this, 'setFromSessionRequest');%0A    %7D%0A%0A
     
@@ -1291,24 +1291,42 @@
 st);%0A    %7D%0A%0A
+    @action.bound%0A
     setFromS
@@ -1625,16 +1625,16 @@
 del();%0A%0A
+
 export d
@@ -1658,1956 +1658,4 @@
 er;%0A
-%0A%0A    //     static initClass() %7B%0A%0A    //         this.prototype.derived = %7B%0A    //             roles: %7B%0A    //                 fn() %7B return %5B%5D; %7D%0A    //             %7D,%0A    //             isLoggedIn: %7B%0A    //                 fn() %7B return false; %7D%0A    //             %7D,%0A    //             allRoles: %7B%0A    //                 fn() %7B return new Lanes.Models.Role.Collection; %7D%0A    //             %7D%0A    //         %7D;%0A%0A    //         this.prototype.session = %7B%0A    //             access_data: 'object',%0A    //             id:          'integer',%0A    //             login:       'string',%0A    //             name:        'string',%0A    //             email:       'string',%0A    //             role_names:  'array',%0A    //             options:     'object',%0A    //             password:    'string'%0A    //         %7D;%0A    //     %7D%0A%0A    //     constructor(attributes, access) %7B%0A    //         super(...arguments);%0A    //         this.access_data = access;%0A    //     %7D%0A%0A    //     api_path() %7B return '/users'; %7D%0A    //     hasAccess() %7B return true; %7D%0A    //     canRead(model, field) %7B return true; %7D%0A    //     canWrite(model, field) %7B return true; %7D%0A    //     canDelete(model)        %7B return true; %7D%0A    // %7D;%0A    // undefined.initClass();%0A%0A%0A// let CURRENT_USER = null;%0A%0A// Object.defineProperty(Lanes, 'current_user', %7B%0A%0A//     set(user) %7B%0A//         let events = null;%0A//         if (CURRENT_USER) %7B%0A//             events = CURRENT_USER._events;%0A//         %7D%0A//         if (_.some(events)) %7B%0A//             for (let key in events) %7B%0A//                 const callbacks = events%5Bkey%5D;%0A//                 if (user._events%5Bkey%5D) %7B%0A//                     user._events%5Bkey%5D = user._events%5Bkey%5D.concat(callbacks);%0A//                 %7D else %7B%0A//                     user._events%5Bkey%5D = callbacks;%0A//                 %7D%0A//             %7D%0A//         %7D%0A//         return CURRENT_USER = user;%0A//     %7D,%0A%0A//     get() %7B%0A//         return CURRENT_USER;%0A//     %7D%0A// %7D);%0A

use get/setters