<?php

namespace App\Services\Slack;

/**
 * Class Slack
 * @package common\components
 */
class Slack
{
	/** Chanels */
	const DEV_ERRORS = 'general';

	/**
	 * Slack API URL
	 *
	 * @var string
	 */
	private $apiUrl = 'https://slack.com/api/';

	/**
	 * Slack API Token
	 *
	 * @var string
	 */
	private $apiKey = 'xoxp-402814418948-402342717504-402931310163-6f635e9acb23d163bad59dc355722ebc';

	/**
	 * Slack IMS List
	 *
	 * @var mixed
	 */
	private $ims = null;

	/**
	 * @param $user
	 * @param $message
	 *
	 * @param array $attachments
	 *
	 * @return bool
	 */
	public function send($user, $message, $attachments = [])
	{
		if ($this->ims === null) {
			$this->loadImChannels();
		}
		if (empty($this->ims[$user])) {
			$result = $this->call('im.open', [
				'user' => $user,
			]);
			if (!$result || !$result['ok'] || !$result['channel']) {
				return false;
			}
			$this->ims[$user] = $result['channel']['id'];
		}
		if (empty($this->ims[$user])) {
			return false;
		}

		return $this->sendToChannel($this->ims[$user], $message, $attachments);
	}

	/**
	 * Load all Slack channels
	 */
	private function loadImChannels()
	{
		$result = $this->call('im.list');
		if ($result && $result['ok'] && !empty($result['ims'])) {
			foreach ($result['ims'] as $ims) {
				$this->ims[$ims['user']] = $ims['id'];
			}
		} else {
			$this->ims = [];
		}
	}

	/**
	 * Call thought API slack
	 *
	 * @param $method
	 * @param array $data
	 * @param bool $async
	 *
	 * @return bool|mixed
	 */
	private function call($method, $data = [], $async = false)
	{
		$url = $this->apiUrl . $method;
		$data['token'] = $this->apiKey;
		$params = http_build_query($data);

		$ch = curl_init();
		curl_setopt_array($ch, [
			CURLOPT_URL => $url,
			CURLOPT_POST => true,
			CURLOPT_POSTFIELDS => $params,
			CURLOPT_RETURNTRANSFER => true,
		]);

		if ($async) {
			//Do not wait for response
			curl_setopt($ch, CURLOPT_TIMEOUT, 1);
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
		} else {
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		}

		$result = curl_exec($ch);

		curl_close($ch);

		return !empty($result) ? json_decode($result, true) : false;
	}

	/**
	 * @param $channel
	 * @param $message
	 * @param array $attachments
	 * @param bool $async
	 *
	 * @return mixed
	 */
	public function sendToChannel($channel, $message, $attachments = [], $async = false)
	{
//        if (DEV) {
//            $message = '!DEV! ' . $message;
//        } elseif (STAGING) {
//            $message = '!STAGING!' . $message;
//        }

		$result = $this->call('chat.postMessage', [
			'channel' => $channel,
			'text' => $message,
			//'attachments' => json_encode($attachments),
			'as_user' => false,
		], $async);

		return $result['ok'];
	}
}