var SpotifyWebApi = require('spotify-web-api-node');
var _ = require('lodash')
var fs = require('fs')
var rpn = require('request-promise-native')

var myArgs = process.argv.slice(2);

var accessData = JSON.parse(fs.readFileSync('./data/accessData.json', 'utf8'));
var userDetails = JSON.parse(fs.readFileSync('./data/userDetails.json', 'utf8'));

let spotify = new SpotifyWebApi({
    clientId: userDetails.clientId,
    clientSecret: userDetails.clientSecret,
    redirectUri: userDetails.redirectUri,
})

const Device = userDetails.device

async function initialize() {
    const token = await getToken()
    spotify.setAccessToken(token)
}

async function refreshToken() {
    spotify.setRefreshToken(accessData.refresh_token);
    const token = await getRefreshToken()
    spotify.setAccessToken(token)
}

async function getToken() {
    const result = await spotify.clientCredentialsGrant()
    return result.body.access_token
}

async function getRefreshToken() {
    const result = await spotify.refreshAccessToken()
    return result.body.access_token
}

async function getDevice() {
    await initialize()
    await refreshToken()

    let response;
    try {
        response = await rpn({
            method: 'GET',
            url: 'https://api.spotify.com/v1/me/player/devices',
            simple: false,
            // body,
            resolveWithFullResponse: true,
            json: true,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${spotify._credentials.accessToken}`
            },
        });
    } catch (e) {
        throw Error(`Request error: ${e}`);
    }
    this.response = response;
    this.response.body = response.body
    this.response.devices = response.body.devices
    const DiskPlayer = _.find(this.response.devices, ['name', Device])
    if (DiskPlayer != undefined) {
        DiskPlayerId = DiskPlayer.id
        return DiskPlayerId
    } else {
        console.log(`${Device} Not found in device list`)
    }
}

async function playFile() {
    await initialize()
    await refreshToken()
    const DiskPlayerId = await getDevice()
    const album = fs.readFileSync(`${userDetails.path}/diskplayer.contents`, 'utf8');

    const body = {
        "context_uri": album,
        "offset": {
            "position": 0
        },
        "position_ms": 0
    }

    let response;
    try {
        response = await rpn({
            method: 'PUT',
            url: '	https://api.spotify.com/v1/me/player/play',
            qs: {
                device_id: DiskPlayerId
            },
            simple: false,
            body,
            resolveWithFullResponse: true,
            json: true,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${spotify._credentials.accessToken}`
            },
        });
    } catch (e) {
        throw Error(`Request error: ${e}`);
    }
    this.response = response;
    this.response.body = response.body
}

async function playURL() {
    await initialize()
    await refreshToken()
    const DiskPlayerId = await getDevice()
    let album = myArgs[1]
    const i = album.lastIndexOf('/')
    album = album.substring(i + 1)
    album = 'spotify:album:' + album
    const body = {
        "context_uri": album,
        "offset": {
            "position": 0
        },
        "position_ms": 0
    }

    let response;
    try {
        response = await rpn({
            method: 'PUT',
            url: '	https://api.spotify.com/v1/me/player/play',
            qs: {
                device_id: DiskPlayerId
            },
            simple: false,
            body,
            resolveWithFullResponse: true,
            json: true,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${spotify._credentials.accessToken}`
            },
        });
    } catch (e) {
        throw Error(`Request error: ${e}`);
    }
    this.response = response;
    this.response.body = response.body
}

async function playPlaylist() {
    await initialize()
    await refreshToken()
    const DiskPlayerId = await getDevice()
    let playlist = myArgs[1]
    const i = playlist.lastIndexOf('/')
    playlist = playlist.substring(i + 1)
    playlist = 'spotify:playlist:' + playlist
    const body = {
        "context_uri": playlist,
        "offset": {
            "position": 0
        },
        "position_ms": 0
    }

    let response;
    try {
        response = await rpn({
            method: 'PUT',
            url: '	https://api.spotify.com/v1/me/player/play',
            qs: {
                device_id: DiskPlayerId
            },
            simple: false,
            body,
            resolveWithFullResponse: true,
            json: true,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${spotify._credentials.accessToken}`
            },
        });
    } catch (e) {
        throw Error(`Request error: ${e}`);
    }
    this.response = response;
    this.response.body = response.body
}

async function pausePlayer() {
    await initialize()
    await refreshToken()
    const DiskPlayerId = await getDevice()

    let response;
    try {
        response = await rpn({
            method: 'PUT',
            url: '	https://api.spotify.com/v1/me/player/pause',
            qs: {
                device_id: DiskPlayerId
            },
            simple: false,
            resolveWithFullResponse: true,
            json: true,
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${spotify._credentials.accessToken}`
            },
        });
    } catch (e) {
        throw Error(`Request error: ${e}`);
    }
    this.response = response;
    this.response.body = response.body
}


switch (myArgs[0]) {
    case 'file':
        playFile()
        break;
    case 'url':
        playURL()
        break;
    case 'playlist':
        playPlaylist()
        break;
    case 'pause':
        pausePlayer()
        break;
    default:
        // code block
}