import requestPromise, { Options, RequestPromiseAPI } from 'request-promise';
import cheerio from 'cheerio';
import { URL } from './http.url';
import { IHttp } from './http.interface';
import { RespuestaRequest } from './respuestaRequest';

export class Http implements IHttp
{
    /**
     * @property RequestPromiseAPI
     */
    protected client: RequestPromiseAPI;

    constructor(){
        this.client = requestPromise.defaults({
            jar         : true,
            timeout     : 10000,
            encoding    : 'binary',
            gzip        : true
        });
    }

    /**
     * @return Promise<RespuestaRequest>
     * 
     */ 
    async getCaptcha(): Promise<RespuestaRequest>{
        const respuestaRequest = new RespuestaRequest();
        try {
            const captcha: any =  await this.client.post(URL.captcha, {form: {accion: 'random'}});
            if(captcha.error){
                throw captcha;
            }
            respuestaRequest.Estado     = 'OK';
            respuestaRequest.Respuesta  = captcha.toString();
            return respuestaRequest;
       } catch (error) {
            respuestaRequest.Estado     = 'ERROR';
            respuestaRequest.Respuesta  = error.statusCode === undefined?error.message:`${error.statusCode} - ${error.name}`
            throw respuestaRequest;
       }
    }

    /**
     * 
     * @param string NroDoc 
     * @param string Captcha
     * @returns Promise
     * 
     */
    async getHtml(NroDoc: string, Captcha: string): Promise<RespuestaRequest>{
        const respuestaRequest = new RespuestaRequest();
        try {
            const opciones: Options = {
                method: 'POST',
                uri: URL.consulta,
                form: {
                    accion  : "consPorRuc",
                    nroRuc  : NroDoc,
                    numRnd  : Captcha
                },
                transform: function(body: any){
                    return cheerio.load(body);
                }
            }
            const pagina = await this.client(opciones);
            if(pagina.error){
                throw pagina;
            }
            respuestaRequest.Estado     = 'OK';
            respuestaRequest.Respuesta  = pagina.html()
            return respuestaRequest;
        } catch (error) {
            respuestaRequest.Estado     = 'ERROR';
            respuestaRequest.Respuesta  = error.statusCode === undefined?error.message:`${error.statusCode} - ${error.name}`
            throw respuestaRequest;
        }
    }

    /**
     * 
     * @param string NroDoc 
     * @returns Promise
     * 
     */
    async get(NroDoc: string): Promise<RespuestaRequest> {
        try {
            const captcha: RespuestaRequest = await this.getCaptcha();
            if(captcha.Estado === 'ERROR'){
                throw captcha;
            }
           return await this.getHtml(NroDoc, captcha.Respuesta.toString());
        } catch (error) {
            throw error;
        }
    } 
}