import CustosService from "./index";
import config from "../../../config";

export default class CustosTenants {
    /**
     * @type {CustosService}
     */
    _custosService = null;

    constructor(custosService) {
        this._custosService = custosService;
    }

    get custosService() {
        return this._custosService;
    }

    fetchTenants({limit, offset, status, parentTenantId, parentClientId, parentClientSecret, requesterEmail}) {
        let url = `${CustosService.ENDPOINTS.TENANTS}/tenants`
        const params = {
            limit: limit,
            offset: offset,
            // status: status,
            // requester_email: requesterEmail
        };

        // TODO fix.
        if (parentClientId !== config.value('superClientId')) {
            url = `${CustosService.ENDPOINTS.TENANTS}/child/tenants`;
            params["parent_client_id"] = parentClientId;
        } else {
            params["type"] = "ADMIN";
        }

        if (requesterEmail) {
            params["requester_email"] = requesterEmail;
        }

        return this.custosService.axiosInstanceWithTokenAuthorization.get(
            url, {params: params}
        ).then(({data}) => data)


    }

    /**
     * Create tenant role
     * @param {string} name
     * @param {string} description
     * @param {boolean} composite
     * @return {Promise<AxiosResponse<any>>}
     */
    createTenantRole({clientId, name, description, composite = false, clientLevel = false}) {
        return this.custosService.axiosInstanceWithTokenAuthorization.post(
            `${CustosService.ENDPOINTS.TENANTS}/roles`,
            {
                "roles": [{name, description}],
                "client_level": clientLevel,
                "client_id": clientId,
                "composite": composite
            }
        ).then(({data}) => data);
    }

    deleteTenantRole({clientId, name, clientLevel = false}) {
        return this.custosService.axiosInstanceWithTokenAuthorization.delete(
            `${CustosService.ENDPOINTS.TENANTS}/role`,
            {
                data: {
                    "role": {"id": name},
                    "client_level": clientLevel,
                    "client_id": clientId
                }
            }
        ).then(({data}) => data);
    }

    /**
     * Fetch tenant roles
     * @return {Promise<AxiosResponse<any>>}
     */
    async fetchTenantRoles({clientId, clientLevel = false}) {
        const axiosInstance = await this.custosService.axiosInstanceWithTokenAuthorization;
        return axiosInstance.get(
            `${CustosService.ENDPOINTS.TENANTS}/roles`,
            {
                params: {
                    "client_id": clientId,
                    "client_level": clientLevel
                }
            }
        );
    }

    async createTenant({username, firstName, lastName, email, password, tenantName, redirectUris, scope, domain, clientUri, logoUri, comment, applicationType, parentClientId, parentClientSecret}) {
        let axiosInstance;
        if (parentClientId !== config.value('superClientId')) {
            axiosInstance = await this.custosService.getAxiosInstanceWithClientAuthorization({
                clientId: parentClientId,
                clientSecret: parentClientSecret
            });
        } else {
            axiosInstance = this.custosService.axiosInstance;
        }

        return axiosInstance.post(
            `${CustosService.ENDPOINTS.TENANTS}/oauth2/tenant`,
            {
                "client_name": tenantName,
                "requester_email": email,
                "admin_username": username,
                "admin_first_name": firstName,
                "admin_last_name": lastName,
                "admin_email": email,
                "contacts": [email],
                "redirect_uris": redirectUris,
                "scope": scope.join(" ").trim(),
                "domain": domain,
                "admin_password": password,
                "client_uri": clientUri,
                "logo_uri": logoUri,
                "application_type": applicationType,
                "comment": comment
            }
        );
    }

    updateTenant({username, firstName, lastName, email, tenantId, clientId, tenantName, redirectUris, scope, domain, clientUri, logoUri, comment, applicationType, requesterEmail}) {
        let axiosInstance = this.custosService.axiosInstanceWithTokenAuthorization;

        return axiosInstance.put(
            `${CustosService.ENDPOINTS.TENANTS}/oauth2/tenant`,
            {
                "id": tenantId,
                "client_id": clientId,
                "client_name": tenantName,
                "requesterEmail": requesterEmail,
                "admin_username": username,
                "admin_first_name": firstName,
                "admin_last_name": lastName,
                "admin_email": email,
                "contacts": [email],
                "redirect_uris": redirectUris,
                "scope": scope.join(" ").trim(),
                "domain": domain,
                "client_uri": clientUri,
                "logo_uri": logoUri,
                "application_type": applicationType,
                "comment": comment
            }
        );
    }

    fetchTenant({clientId}) {
        return this.custosService.axiosInstanceWithTokenAuthorization.get(
            `${CustosService.ENDPOINTS.TENANTS}/oauth2/tenant`,
            {
                params: {
                    client_id: clientId
                }
            }
        ).then(({data}) => data)
    }

    updateTenantStatus({clientId, status}) {
        return this.custosService.axiosInstanceWithTokenAuthorization.post(
            `${CustosService.ENDPOINTS.TENANTS}/status`,
            {
                client_id: clientId,
                status: status
            }
        ).then(({data}) => data)
    }

}
