import APIParseError from './APIParseError.js'
import { session } from '../service/Session.service.js'

export default class CRUDBase {
    constructor() {
        this.endpoint = '/api/v1'
        this.required_fields = []
        this.permission_base = ''

        this.listing_definition = {}
        this.form_definition = {}

        this.item = ''
        this.plural = ''
    }

    async can(action) {
        return session.check_permissions(`${this.permission_base}:${action}`)
    }

    async list(other_params = {}) {
        const results = await axios.get(this._endpoint(), { params: other_params })
        if ( results && results.data && Array.isArray(results.data.data) ) return results.data.data
        else throw new APIParseError()
    }

    async get(id, other_params = {}) {
        const results = await axios.get(this._endpoint(id), { params: other_params })
        if ( results && results.data && results.data.data ) return results.data.data
        else throw new APIParseError()
    }

    async create(properties) {
        for ( const field of this.required_fields ) {
            if ( !(field in properties) ) throw new Error(`Missing required field: ${field}`)
        }

        const results = await axios.post(this._endpoint(), properties)
        if ( results && results.data && results.data.data ) return results.data.data
        else throw new APIParseError()
    }

    async update(id, properties) {
        for ( const field of this.required_fields ) {
            if ( !(field in properties) ) throw new Error(`Missing required field: ${field}`)
        }

        await axios.patch(this._endpoint(id), properties)
    }

    async delete(id, other_params = {}) {
        await axios.delete(this._endpoint(id), { params: other_params })
    }

    _endpoint(sub = '/') {
        let first = this.endpoint
        if ( !first.startsWith('/') ) first = `/${first}`
        if ( first.endsWith('/') ) first = first.slice(0, -1)

        if ( !sub.startsWith('/') ) sub = `/${sub}`
        return `${first}${sub}`
    }
}
