<script>
    class Factura {
        props = {
            id: 0,
            venta: null,
            index: 0,
            proporcion: 0,
            terreno: {
                fecha: null,
                valor: 0
            },
            emisor: {
                rut: '',
                nombre: '',
                direccion: '',
                comuna: ''
            },
            receptor: {
                rut: '',
                nombre: '',
                direccion: '',
                comuna: ''
            },
            fecha: null,
            unidades: {
                unidad: null,
                descripcion: '',
                precio: 0,
                prorrateo: 0
            },
            detalle: {
                base: 0,
                terreno: 0,
                neto: 0,
                iva: 0,
                bruto: 0,
                descuento: 0,
                total: 0
            },
            total: {
                neto: 0,
                exento: 0,
                iva: 0,
                total: 0
            },
            uf: {
                fecha: null,
                valor: 0
            }
        }
        constructor(props) {
            this.props = props
        }
        get saved() {
            return this.props.id > 0
        }
        get prorrateo() {
            return this.props.unidades.reduce((sum, unidad) => sum + unidad.prorrateo, 0)
        }
        draw() {
            return {
                divider: () => {
                    return '<div class="ui divider" data-index="'+this.props.index+'"></div>'
                },
                factura: ({formatters = {date, pesos, ufs, percent}}) => {
                    return [
                        this.draw().divider(this.props.index),
                        `<div class="factura" data-index="${this.props.index}">`,
                        '<div class="ui compact grid">',
                        this.draw().cabecera(),
                        this.draw().propietario({formatters}),
                        this.draw().table({formatters}),
                        this.draw().totales({formatters}),
                        this.draw().guardar(),
                        '</div>',
                        '</div>'
                    ].join("\n")
                },
                cabecera: () => {
                    return [
                        '<div class="two columns row">',
                        this.draw().inmobiliaria(),
                        this.draw().rut(),
                        '</div>'
                    ].join("\n")
                },
                inmobiliaria: () => {
                    return [
                        '<div class="twelve wide column">',
                        '<strong>'+this.props.emisor.nombre.toUpperCase()+'</strong><br/>',
                        'GIRO: <br/>',
                        `Dirección: ${this.props.emisor.direccion}, ${this.props.emisor.comuna}`,
                        '</div>',
                    ].join("\n")
                },
                rut: () => {
                    return [
                        '<div class="four wide column">',
                        '<div class="ui center aligned orange segment">',
                        '<strong>',
                        `RUT:${this.props.emisor.rut.toUpperCase()}<br/>`,
                        'FACTURA ELECTRÓNICA<br/>',
                        `<span class="ui red text">N° ${this.props.venta.id}${this.props.index}</span>`,
                        '</strong>',
                        '</div>',
                        '</div>'
                    ].join("\n")
                },
                propietario: ({formatters}) => {
                    return [
                        '<div class="row">',
                        '<table class="ui table">',
                        '<tr>'+
                        '<td class="grey"><strong>Señor(es)</strong></td>',
                        '<td>'+this.props.receptor.nombre+'</td>',
                        '<td class="grey"><strong>RUT</strong></td>',
                        '<td>'+this.props.receptor.rut.toUpperCase()+'</td>',
                        '</tr>',
                        '<tr>',
                        '<td class="grey"><strong>Giro</strong></td>',
                        '<td>Otras Actividades Profesionales</td>',
                        '<td class="grey"><strong>Fecha Emisión</strong></td>',
                        '<td>'+formatters.date.format(this.props.fecha)+'</td>',
                        '</tr>',
                        '<tr>',
                        '<td class="grey"><strong>Dirección</strong></td>',
                        '<td>'+this.props.receptor.direccion+'</td>',
                        '<td class="grey"><strong>Comuna</strong></td>',
                        '<td>'+this.props.receptor.comuna.toUpperCase()+'</td>',
                        '</tr>',
                        '</table>',
                        '</div>'
                    ].join("\n")
                },
                table: ({formatters}) => {
                    return [
                        '<div class="row">',
                            '<table class="ui celled table">',
                                '<thead>',
                                    '<tr class="grey">',
                                        '<th class="center aligned" colspan="6">DETALLES</th>',
                                    '</tr>',
                                    '<tr class="grey">',
                                        '<th>N°</th>',
                                        '<th class="center aligned">Descripción</th>',
                                        '<th class="center aligned">Cant/Unidad</th>',
                                        '<th class="center aligned">Prec. Unit.</th>',
                                        '<th class="center aligned">Ind</th>',
                                        '<th class="center aligned">Total</th>',
                                    '</tr>',
                                '</thead>',
                                '<tbody>',
                                    this.draw().unidades({formatters}),
                                '</tbody>',
                                '<tfoot>',
                                    '<tr>',
                                        '<td colspan="6">',
                                        '<br />',
                                        '<br />',
                                        '<br />',
                                        '<br />',
                                        '</td>',
                                    '</tr>',
                                '</tfoot>',
                            '</table>',
                        '</div>'
                    ].join("\n")
                },
                unidades: ({formatters}) => {
                    const unidadesData = []
                    let no = 1
                    const classes = [
                        '',
                        '',
                        'center aligned',
                        'right aligned',
                        'center aligned',
                        'right aligned'
                    ]
                    this.props.unidades.forEach(unidad => {
                        unidadesData.push(this.draw().unidad({
                            unidad,
                            no: no++,
                            classes,
                            formatters
                        }))
                    })
                    unidadesData.push(this.draw().resumen({
                        no,
                        classes,
                        formatters
                    }))
                    return unidadesData.join("\n")
                },
                unidad: ({unidad, no, classes, formatters}) => {
                    const descuento = this.props.terreno.valor * unidad.prorrateo * this.props.proporcion
                    const bruto = unidad.precio - descuento
                    const neto = bruto / 1.19
                    const data = [
                        no,
                        unidad.descripcion,
                        '1 UNID',
                        formatters.pesos.format(neto),
                        'AF',
                        formatters.pesos.format(neto)
                    ]

                    const row = ['<tr>']
                    data.forEach((value, i) => {
                        const cell = ['<td']
                        if (classes[i] !== '') {
                            cell.push(' class="' + classes[i] + '"')
                        }
                        cell.push('>'+value+'</td>')
                        row.push(cell.join(''))
                    })
                    row.push('</tr>')
                    return row.join('')
                },
                resumen: ({no, classes, formatters}) => {
                    const emptyTerreno = '<div class="ui tiny red horizontal circular label">0</div>'
                    const data = [
                        no,
                        'Valor con Terreno: $' + formatters.pesos.format(this.props.detalle.base) + ' - Menos valor terreno: $' + ((this.props.detalle.terreno > 0) ? formatters.pesos.format(-this.props.detalle.terreno) : emptyTerreno) + '<br />' +
                        'Base imponible (Neto): $' + formatters.pesos.format(this.props.detalle.neto) + '<br />' +
                        'IVA: $' + formatters.pesos.format(this.props.detalle.iva) + '<br />' +
                        'SUBTOTAL (Bruto): $' + formatters.pesos.format(this.props.detalle.bruto) + '<br />' +
                        'Mas valor terreno: $' + ((this.props.detalle.terreno > 0) ? formatters.pesos.format(this.props.detalle.terreno) : emptyTerreno) + '<br />' +
                        'TOTAL (Escritura): $' + formatters.pesos.format(this.props.detalle.total) + '; ' + formatters.ufs.format(this.props.venta.valor * this.props.proporcion) + ' UF<br /><br />' +
                        'Descuento Terreno: ' + ((this.props.detalle.terreno > 0) ? formatters.percent.format(this.props.detalle.descuento * 100) : emptyTerreno) + '%<br /><br />' +
                        'UF (' + formatters.date.format(this.props.uf.fecha) + '): $' + formatters.ufs.format(this.props.uf.valor),
                        '1 UNID',
                        formatters.pesos.format(this.props.detalle.terreno),
                        'EX',
                        formatters.pesos.format(this.props.detalle.terreno),
                    ]

                    const row = ['<tr class="top aligned">']
                    data.forEach((value, i) => {
                        const cell = ['<td']
                        if (classes[i] !== '') {
                            cell.push(' class="'+classes[i]+'"')
                        }
                        cell.push('>'+value+'</td>')
                        row.push(cell.join(''))
                    })
                    return row.join('')
                },
                totales: ({formatters}) => {
                    let tooltips = {
                        neto: null,
                        iva: null,
                        total: null
                    }
                    if (this.props.total.neto !== this.props.detalle.neto) {
                        tooltips.neto = ` data-tooltip="No coinciden netos! Promesa: ${formatters.pesos.format(this.props.detalle.neto)} - Unidades: ${formatters.pesos.format(this.props.total.neto)}"`
                    }
                    if (this.props.total.iva !== this.props.detalle.iva) {
                        tooltips.iva = ` data-tooltip="No coinciden ivas! Promesa: ${formatters.pesos.format(this.props.detalle.iva)} - Unidades: ${formatters.pesos.format(this.props.total.iva)}"`
                    }
                    if (this.props.total.total !== this.props.detalle.total) {
                        tooltips.total = ` data-tooltip="No coinciden totales! Promesa: ${formatters.pesos.format(this.props.detalle.total)} - Unidades: ${formatters.pesos.format(this.props.total.total)}"`
                    }
                    return [
                        '<div class="row">',
                        '<div class="ten wide column"></div>',
                        '<div class="six wide column">',
                        '<table class="ui celled very compact table">',
                        '<thead>',
                        '<tr>',
                        '<th class="center aligned grey" colspan="2">TOTALES</th>',
                        '</tr>',
                        '</thead>',
                        '<tbody>',
                        '<tr>',
                        '<td class="grey">Monto Neto</td>',
                        `<td class="right aligned${this.props.total.neto !== this.props.detalle.neto ? ' red' : ''}"${this.props.total.neto !== this.props.detalle.neto ? tooltips.neto : ''} id="neto">${formatters.pesos.format(this.props.total.neto)}</td>`,
                        '</tr>',
                        '<tr>',
                        '<td class="grey">Monto Exento</td>',
                        '<td class="right aligned" id="exento">'+formatters.pesos.format(this.props.total.exento)+'</td>',
                        '</tr>',
                        '<tr>',
                        '<td class="grey">19% IVA</td>',
                        `<td class="right aligned${this.props.total.iva !== this.props.detalle.iva ? ' red' : ''}"${this.props.total.iva !== this.props.detalle.iva ? tooltips.iva : ''} id="iva">${formatters.pesos.format(this.props.total.iva)}</td>`,
                        '</tr>',
                        '<tr>',
                        '<td class="grey">Monto Total</td>',
                        `<td class="right aligned${(this.props.total.total !== this.props.detalle.total) ? ' red' : ''}"${(this.props.total.total !== this.props.detalle.total) ? tooltips.total : ''}><strong id="total">${formatters.pesos.format(this.props.total.total)}</strong></td>`,
                        '</tr>',
                        '</tbody>',
                        '</table>',
                        '</div>',
                        '</div>'
                    ].join("\n")
                },
                guardar: () => {
                    if (this.props.saved) {
                        return [
                            '<div class="row">',
                            '<div class="fourteen wide column"></div>',
                            '<div class="two wide center aligned column">',
                            `<div class="ui green message guardar" data-index="${this.props.index}">`,
                            '<i class="check icon"></i>',
                            'Guardada',
                            '</div>',
                            '</div>',
                            '</div>'
                        ].join("\n")
                    }
                    return [
                        '<div class="row">',
                        '<div class="right aligned sixteen wide column">',
                        `<button class="ui primary button guardar" data-index="${this.props.index}">Guardar</button>`,
                        '</div>',
                        '</div>'
                    ].join("\n")
                }
            }
        }
        watch() {
            return {
                save: () => {
                    document.querySelector(`.guardar[data-index="${this.props.index}"]`).addEventListener('click', clickEvent => {
                        const index = clickEvent.currentTarget.getAttribute('data-index')
                        facturas.venta.save().factura({index: index - 1})
                    })
                }
            }
        }
        validate() {
            if (this.props.venta.id === null || typeof this.props.venta.id === 'undefined') {
                return false
            }
            if (this.props.index === null || typeof this.props.index === 'undefined') {
                return false
            }
            if (this.props.proporcion === null || typeof this.props.proporcion === 'undefined') {
                return false
            }
            return !(this.props.receptor.rut === '' || this.props.receptor.nombre === '' || this.props.receptor.direccion === '' || this.props.receptor.comuna === '');

        }
        save() {
            if (!this.validate()) {
                return
            }
            let url = '{{$urls->api}}/ventas/facturas/add'
            if (this.saved) {
                url = `{{$urls->api}}/ventas/facturas/${this.props.id}/edit`
            }
            const method = 'post'
            const body = new FormData()
            body.set('venta_id', this.props.venta.id)
            body.set('index', this.props.index)
            body.set('proporcion', this.props.proporcion)
            body.set('cliente', JSON.stringify(this.props.receptor))
            body.set('terreno', this.props.detalle.terreno)
            body.set('unidades', JSON.stringify(this.props.unidades.map(unidad => {
                return {unidad_id: unidad.unidad.props.id, precio: unidad.precio, prorrateo: unidad.prorrateo}
            })))
            body.set('fecha', [this.props.fecha.getFullYear(), this.props.fecha.getMonth()+1, this.props.fecha.getDate()].join('-'))
            body.set('detalle', JSON.stringify(this.props.detalle))
            body.set('total', JSON.stringify(this.props.total))
            body.set('uf', JSON.stringify({fecha: [this.props.uf.fecha.getFullYear(), this.props.uf.fecha.getMonth()+1, this.props.uf.fecha.getDate()].join('-'), valor: this.props.uf.valor}))

            return APIClient.fetch(url, {method, body}).then(response => {
                if (!response) {
                    return
                }
                return response.json().then(json => {
                    if (json.success) {
                        this.props.id = json.factura.id
                        facturas.draw().facturas()
                    }
                })
            })
        }
        update() {
            return {
                venta: venta => {
                    this.props.venta = venta.props
                    this.props.fecha = venta.props.facturas.fecha
                    this.props.uf.fecha = venta.props.uf.fecha
                    this.props.uf.valor = venta.props.uf.valor
                    this.update().propietario(venta.props.propietarios.find(propietario => propietario.props.index === this.props.index))
                    this.update().unidades(venta.props.unidades)
                    this.props.detalle.total = venta.props.valor * this.props.proporcion * venta.props.uf.valor
                    this.update().detalle(venta.props.facturas.terreno.valor * this.prorrateo)
                    this.props.detalle.descuento = venta.prorrateo * this.props.proporcion
                    this.update().total()
                },
                detalle: terreno => {
                    this.props.detalle.terreno = terreno * this.props.proporcion
                    this.props.detalle.bruto = this.props.detalle.total - this.props.detalle.terreno
                    this.props.detalle.neto = this.props.detalle.bruto / 1.19
                    this.props.detalle.iva = this.props.detalle.neto * 0.19
                    this.props.detalle.base = this.props.detalle.neto + this.props.detalle.terreno
                },
                total: () => {
                    this.props.total.exento = this.props.detalle.terreno
                    this.props.total.neto = (this.props.unidades.reduce((sum, unidad) => sum + unidad.precio, 0) - this.props.total.exento) / 1.19
                    this.props.total.iva = this.props.total.neto * 0.19
                    this.props.total.total = this.props.total.neto + this.props.total.iva + this.props.total.exento
                },
                unidades: unidades => {
                    this.props.unidades = []
                    unidades.forEach(unidad => {
                        this.props.unidades.push({
                            unidad: unidad,
                            descripcion: unidad.changeDescripcion(this.props.proporcion || 1),
                            precio: unidad.props.valor * this.props.uf.valor,
                            prorrateo: unidad.props.prorrateo
                        })
                    })
                },
                propietario: propietario => {
                    this.props.proporcion = propietario.props.proporcion

                    this.props.receptor = {
                        rut: propietario.props.rut ?? '',
                        nombre: propietario.props.nombre ?? '',
                        direccion: propietario.props.direccion ?? '',
                        comuna: propietario.comuna ?? ''
                    }
                }
            }
        }
    }
</script>
