import Message from './EmailMessage';

const PRIVATE = Symbol();

export default class Folder {
  static Inbox() {
    return new Folder('inbox', { type: 'distinguished' });
  }
  static Sent() {
    return new Folder('sentitems', { type: 'distinguished' });
  }
  constructor(name, { type } = {}) {
    this[PRIVATE] = {};
    this[PRIVATE].name = name;
    this[PRIVATE].type = type;
  }

  get list() {
    const folder = this;
    return function ({
      maxEntries = 30,
      offset = 0,
      basePoint = 'Beginning',
      allDetails = false,
    } = {}) {
      return new Promise((resolve, reject) => {
        this.client.FindItem({
          attributes: {Traversal: 'Shallow'},
          ItemShape: {
            BaseShape: allDetails ? 'AllProperties' : 'Default',
          },
          IndexedPageItemView: {
            attributes: {
              MaxEntriesReturned: maxEntries,
              BasePoint: basePoint,
              Offset: offset,
            },
          },
          ParentFolderIds: folder.asEws(),
        }, (err, resp) => {
          if (err) {
            const err2 = new Error(`Network error fetching folder '${folder[PRIVATE].name}'`);
            err2.original = err;
            return reject(err2);
          }
          const {
            ResponseMessages: {
              FindItemResponseMessage: {
                RootFolder: {
                  Items: items
                }
              }
            }
          } = resp;
          const {
            Message: messages,
          } = items;
          resolve({
            messages: messages.map(Message.fromResponse),
          });
        });

      });
    }
  }

  asEws() {
    if (this[PRIVATE].type === 'distinguished') {
      return {
        DistinguishedFolderId: {
          attributes: {
            Id: this[PRIVATE].name,
          },
        },
      };
    }
    throw new Error(`Unrecognized folder type ${this[PRIVATE].type}`);
  }
}

@@ -282,16 +282,20 @@
 , %7B type
+, id
  %7D = %7B%7D)
@@ -322,71 +322,19 @@
  = %7B
-%7D;%0A    this%5BPRIVATE%5D.name = name;%0A    this%5BPRIVATE%5D.type = type
+ type, id %7D
 ;%0A  
@@ -1740,32 +1740,52 @@
      attributes:
+ this%5BPRIVATE%5D.id %7C%7C
  %7B%0A            I
@@ -1854,77 +1854,979 @@
     
-throw new Error(%60Unrecognized folder type $%7Bthis%5BPRIVATE%5D.type%7D%60);%0A  %7D%0A%7D
+return %7B%0A      FolderId: %7B%0A        attributes: this%5BPRIVATE%5D.id,%0A      %7D,%0A    %7D;%0A  %7D%0A%0A  static fromResponse(r) %7B%0A    const %7B%0A      FolderId: id,%0A      DisplayName: name,%0A      TotalCount: count,%0A      ChildFolderCount: childFolderCount,%0A      UnreadCount: unreadCount,%0A    %7D = r;%0A    const folder = new Folder(name, %7B id %7D);%0A    Object.assign(folder%5BPRIVATE%5D, %7B count, childFolderCount, unreadCount %7D);%0A    return folder;%0A  %7D%0A%7D%0A%0Aconst SPECIAL_FOLDERS = %7B%0A  Inbox: 'inbox',%0A  Sent: 'sentitems',%0A  Calendar: 'calendar',%0A  Outbox: 'outbox',%0A  Root: 'root',%0A  InstantMessageContacts: 'imcontactlist',%0A  Favorites: 'favorites',%0A  Junk: 'junkemail',%0A  Contacts: 'contacts',%0A  Drafts: 'drafts',%0A  Tasks: 'tasks',%0A  Trash: 'recoverableitemsroot',%0A  Archive: 'archiveroot',%0A  ArchiveInbox: 'archiveinbox',%0A%7D%0A%0AObject.keys(SPECIAL_FOLDERS).forEach(k =%3E %7B%0A  const f = function () %7B%0A    return new Folder(SPECIAL_FOLDERS%5Bk%5D, %7B type: 'distinguished' %7D);%0A  %7D;%0A  f.name = k;%0A  return f;%0A%7D);
 %0A

Handle non-special folders and add more special ones