<?php

namespace BitApps\PiPro\src\Integrations\ZohoProject;

use BitApps\PiPro\Deps\BitApps\WPKit\Helpers\JSON;
use BitApps\PiPro\Deps\BitApps\WPKit\Http\Client\HttpClient;

if (!\defined('ABSPATH')) {
    exit;
}

class ZohoProjectService
{
    private HttpClient $http;

    private array $headers;

    private string $baseUrl;

    /**
     * ZohoProjectService constructor.
     *
     * @param array  $headers
     * @param string $domain
     */
    public function __construct($headers = [], $domain = 'com')
    {
        $this->http = new HttpClient();
        $this->headers = $headers;
        $this->baseUrl = 'https://projectsapi.zoho.' . $domain . '/api/v3';
    }

    /**
     * Create a new project in Zoho Projects.
     *
     * @param array $fieldMapData
     * @param string $portalId
     *
     * @return array
     */
    public function createProject($fieldMapData, $portalId)
    {
        if ($fieldMapData['budget_info']['budget_type'] !== 'based_on_project') {
            unset($fieldMapData['budget_info']['hourly_budget_threshold'], $fieldMapData['budget_info']['hourly_budget']);
        }

        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects';
        $response = $this->http->request($endPoint, 'POST', JSON::encode($fieldMapData), $this->headers);

        return [
            'response'    => $response,
            'payload'     => $fieldMapData,
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Get list of projects for a portal.
     *
     * @param string $portalId
     *
     * @return array
     */
    public function listProjects($portalId)
    {
        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects';
        $response = $this->http->request($endPoint, 'GET', null, $this->headers);

        return [
            'response'    => $response,
            'payload'     => ['portalId' => $portalId],
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Update an existing project in Zoho Projects.
     *
     * @param array $fieldMapData
     * @param string $portalId
     * @param string $projectId
     *
     * @return array
     */
    public function updateProject($fieldMapData, $portalId, $projectId)
    {
        if ($fieldMapData['budget_info']['budget_type'] !== 'based_on_project') {
            unset($fieldMapData['budget_info']['hourly_budget_threshold'], $fieldMapData['budget_info']['hourly_budget']);
        }

        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects/' . urlencode($projectId);
        $response = $this->http->request($endPoint, 'PATCH', JSON::encode($fieldMapData), $this->headers);


        return [
            'response'    => $response,
            'payload'     => $fieldMapData,
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Move a project to trash in Zoho Projects.
     *
     * @param string $portalId
     * @param string $projectId
     *
     * @return array
     */
    public function deleteProject($portalId, $projectId)
    {
        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects/' . urlencode($projectId) . '/trash';
        $response = $this->http->request($endPoint, 'POST', null, $this->headers);

        return [
            'response'    => $response ?: ['success' => true],
            'payload'     => ['portalId' => $portalId, 'projectId' => $projectId],
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Create a new tasklist in Zoho Projects.
     *
     * @param array $fieldMapData
     * @param string $portalId
     * @param string $projectId
     * @param mixed $milestoneId
     *
     * @return array
     */
    public function createTasklist($fieldMapData, $portalId, $projectId, $milestoneId)
    {
        $endPoint = $this->baseUrl . '/portal/' . urlencode((string) $portalId) . '/projects/' . urlencode((string) $projectId) . '/tasklists';

        if ($milestoneId !== null) {
            $fieldMapData['milestone_id'] = $milestoneId;
        }

        $response = $this->http->request($endPoint, 'POST', JSON::encode($fieldMapData), $this->headers);

        return [
            'response'    => $response,
            'payload'     => $fieldMapData,
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Create a new milestone in Zoho Projects.
     *
     * @param array $fieldMapData
     * @param string $portalId
     * @param string $projectId
     *
     * @return array
     */
    public function createMilestone($fieldMapData, $portalId, $projectId)
    {
        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects/' . urlencode($projectId) . '/milestones';
        $response = $this->http->request($endPoint, 'POST', JSON::encode($fieldMapData), $this->headers);

        return [
            'response'    => $response,
            'payload'     => $fieldMapData,
            'status_code' => $this->http->getResponseCode()
        ];
    }

    /**
     * Create a new task in Zoho Projects.
     *
     * @param array $fieldMapData
     * @param string $portalId
     * @param string $projectId
     *
     * @return array
     */
    public function createTask($fieldMapData, $portalId, $projectId)
    {
        $endPoint = $this->baseUrl . '/portal/' . urlencode($portalId) . '/projects/' . urlencode($projectId) . '/tasks';

        if (isset($fieldMapData['owners_and_work']['owners']['add']['zpuid'])) {
            $zpuid = $fieldMapData['owners_and_work']['owners']['add']['zpuid'];

            $fieldMapData['owners_and_work'] = [
                'owners' => [
                    [
                        'add' => [
                            [
                                'zpuid' => $zpuid,
                            ],
                        ],
                    ],
                ]
            ];
        }

        $response = $this->http->request($endPoint, 'POST', JSON::encode($fieldMapData), $this->headers);

        return [
            'response'    => $response,
            'payload'     => $fieldMapData,
            'status_code' => $this->http->getResponseCode()
        ];
    }
}
