
Service = require '../../../browser/model'
Entry   = require '../../../browser/model/entry'

class FacebookService extends Service
	@initFB: ->
		new Promise (res, rej) ->
			window.fbAsyncInit = =>
				FB.init {
					status: true, cookie: true, xfbml: false
					appId: '126231267555748'
				}

				res()

			do (d = document, s = 'script', id = 'facebook-jssdk') ->
				fjs = d.getElementsByTagName(s)[0]
				return if d.getElementById id
				js = d.createElement(s); js.id = id;
				js.src = "//connect.facebook.net/en_US/all.js";
				fjs.parentNode.insertBefore js, fjs

	constructor: ->
		super
		@permissions = {}
		@authenticated = false

		@root.id = 'me'
		@root.album = true
		@apiReady = FacebookService.initFB()

	refresh: (@entry) ->
		@entry.children = []
		@pages = false
		@_requestFBPhotoSet @getEntryFetchPath(@entry), @_onFBRespond

	getEntryFetchPath: (entry) =>
		options = {}

		imageType = !!~@options.types.indexOf 'image'
		if imageType
			end = 'photos'
			options = {fields: 'id,images,name'}
		else
			end = 'videos/uploaded'
			options = {fields: 'id,source,picture,description,format'}

		if entry.album
			end = 'albums'
			options = {fields: 'id, name, count'}

		{path: entry.id + '/' + end, options}

	_requestFBPhotoSet: (path, _callback) =>
		options = {}
		if path.constructor is Object
			{path, options} = path
		FB.api path, 'GET', options, _callback

	_requestFBPages: =>
		FB.api 'me/accounts', @_onFBRespond

	_onFBRespond: (response) =>
		data = response.data or []

		# remove empty folders
		if @entry.root or @entry.album
			# TODO: eliminate empty folders for video type too
			data = data.filter (i) -> i.count > 0 or (i.perms and i.category and !i.count?)

		# map data response as entry items
		data = @mapEntries data

		# add the 'My Photos' or 'My Videos' folder to the root folder
		if (@entry.root or @entry.album) and !@entry.children?.filter((i) -> i.my_album).length
			data or= []
			# unless imageType = !!~@options.types.indexOf 'image'
			# 	data = []
			imageType = !!~@options.types.indexOf 'image'
			[name, path] = if imageType then ['Photos', @entry.path+'/photos'] else ['Videos', @entry.path+'/videos']
			name = 'My '+name if @entry.id is 'me'
			data.push new Entry {service: @, name, path, id: @entry.id, type: 'folder', my_album: true}

		if @entry.root and @permissions.manage_pages? and !@permissions.manage_pages and !@entry.children?.filter((i) -> i.pages).length
			data.push pagesEntry = new Entry {service: @, name:'Pages', path: 'accept_pages', type: 'button', pages: true}
			pagesEntry.bind 'select', @_auth.bind @, true

		@trigger 'refresh', data

		if (path = response.paging?.next)?
			@_requestFBPhotoSet path, @_onFBRespond
		# append the user's pages as folders
		else if @entry.root and not @pages
			@pages = true
			@_requestFBPages()

	mapEntries: (data) ->
		data.map (item) =>
			opts = images: item.images, id:item.id, name: item.name
			opts.type    = if item.images? then 'image' else (if item.format then 'video' else 'folder')
			opts.album   = !!(item.perms and item.category) if opts.type is 'folder'
			opts.path    = @entry.path+'/'+item.id
			opts.preview = if opts.type is 'image' then item.images[Math.max(0,item.images.length-4)].source else @entry.picture
			opts.source  = item.source if opts.type is 'video'
			new Entry opts

	preview: (i)-> i.preview

	getURL: (entry, callback) ->
		callback if entry.type is 'image' then entry.images[0].source else entry.source

	_auth: (interactive = true) ->

		callback = (response) =>
			if response.status is 'connected'
				@getPermissions()
			else
				@trigger 'auth', @authenticated = false

		unless interactive
			FB.getLoginStatus callback
		else
			FB.login callback, scope:'user_photos,user_videos,manage_pages'

	deauth: ->
		FB.logout => @trigger 'auth', false

	getPermissions: =>
		FB.api '/me/permissions', (resp)=>

			@permissions = {}
			resp.data.forEach (d) => @permissions[d.permission] = d.status is 'granted'

			photo = 'image' in @options.types or 'photo' in @options.types
			video = 'video' in @options.types

			if ((photo and @permissions.user_photos) or (video and @permissions.user_videos)) and @permissions.manage_pages?
				@trigger 'auth', @authenticated = true
			else
				# @auth true
				@trigger 'auth', @authenticated = false

module.exports = FacebookService
