@extends('layout.base')

@section('page_content')
    <div class="ui container">
        <h2 class="ui header">
            Facturación -
            <a href="{{$urls->base}}/proyecto/{{$venta->proyecto()->id}}">
                {{$venta->proyecto()->descripcion}}<span class="ui tiny text"><sub><i
                                class="search icon"></i></sub></span>
            </a>
            -
            <a href="{{$urls->base}}/venta/{{$venta->id}}">
                {{$venta->propiedad()->summary()}}
            </a>
        </h2>
        <span id="venta"></span>
        <div id="facturas"></div>
    </div>
@endsection

@push('page_scripts')
    <script>
        class BaseObject {
            props
            constructor(props) {
                this.props = props
            }
        }
        class Propietario extends BaseObject {
            update() {
                return {
                    proporcion: (valor) => {
                        this.props.proporcion = valor
                        facturas.draw().facturas()
                    },
                    rut: rut => {
                        this.props.rut = rut
                        facturas.draw().facturas()
                    },
                    nombre: nombre => {
                        this.props.nombre = nombre
                        facturas.draw().facturas()
                    },
                    direccion: direccion => {
                        this.props.direccion = direccion
                        facturas.draw().facturas()
                    },
                    comuna: comuna => {
                        this.props.comuna = comuna
                        facturas.draw().facturas()
                    },
                    fecha: fecha => {
                        this.props.fecha = fecha
                        this.update().uf(fecha).then(() => {
                            facturas.draw().facturas()
                        })
                    },
                    uf: fecha => {
                        const url = '{{$urls->api}}/money/uf'
                        const method = 'post'
                        const body = new FormData()
                        body.set('fecha', [fecha.getFullYear(), fecha.getMonth()+1, fecha.getDate()].join('-'))
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (typeof json.uf === 'undefined') {
                                    return
                                }
                                this.props.uf = parseFloat(json.uf)
                            })
                        })
                    }
                }
            }
            watch() {
                return {
                    propietario: () => {
                        this.watch().proporcion()
                        this.watch().rut()
                        this.watch().nombre()
                        this.watch().direccion()
                        this.watch().comuna()
                        this.watch().fecha()
                    },
                    proporcion: () => {
                        document.getElementById('proporcion'+this.props.index).addEventListener('input', inputEvent => {
                            const newValue = inputEvent.currentTarget.value / 100
                            if (newValue === this.props.proporcion) {
                                return
                            }
                            const saldo = facturas.venta.props.propietarios.reduce((sum, propietario) => sum + propietario.props.proporcion, 0) - this.props.proporcion
                            if (saldo + newValue > 1) {
                                return
                            }
                            this.update().proporcion(newValue)
                        })
                    },
                    rut: () => {},
                    nombre: () => {},
                    direccion: () => {},
                    comuna: () => {},
                    fecha: () => {
                        const cdo = structuredClone(calendar_date_options)
                        cdo['initialDate'] = this.props.fecha
                        cdo['onChange'] = (date, text, mode) => {
                            this.update().fecha(date)
                        }
                        $('#fecha_factura'+this.props.index).calendar(cdo)
                    }
                }
            }
            draw() {
                return {
                    propietario: () => {
                        const output = ['<div class="fields" data-index="'+this.props.index+'">']
                        output.push(this.draw().proporcion())
                        output.push(this.draw().rut())
                        output.push(this.draw().nombre())
                        //output.push(this.draw().fecha())
                        output.push('</div>')
                        output.push('<div class="fields" data-index="'+this.props.index+'">')
                        output.push('<div class="three wide field"></div>')
                        output.push(this.draw().direccion())
                        output.push(this.draw().comuna())
                        output.push('</div>')
                        return output.join("\n")
                    },
                    proporcion: () => {
                        return [
                            '<div class="two wide field">',
                            '<label for="proporcion'+this.props.index+'">Proporción Factura</label>',
                            '<div class="ui right labeled input">',
                            '<input type="number" name="proporcion'+this.props.index+'" id="proporcion'+this.props.index+'" value="'+(this.props.proporcion*100)+'" max="100" min="0" />',
                            '<div class="ui basic icon label">',
                            '<i class="percent icon"></i>',
                            '</div>',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    rut: () => {
                        return [
                            '<div class="three wide field">',
                            '<label for="rut'+this.props.index+'">RUT</label>',
                            '<div class="ui input">',
                            '<input type="text" name="rut'+this.props.index+'" id="rut'+this.props.index+'" value="'+this.props.rut.toUpperCase()+'" />',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    nombre: () => {
                        return [
                            '<div class="six wide field">',
                            '<label for="propietario'+this.props.index+'">Propietario</label>',
                            '<div class="ui input">',
                            '<input type="text" name="propietario'+this.props.index+'" id="propietario'+this.props.index+'" value="'+this.props.nombre+'" />',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    direccion: () => {
                        return [
                            '<div class="six wide field">',
                            '<label for="direccion_propietario'+this.props.index+'">Dirección</label>',
                            '<div class="ui input">',
                            '<input type="text" name="direccion_propietario'+this.props.index+'" id="direccion_propietario'+this.props.index+'" value="'+this.props.direccion+'" />',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    comuna: () => {
                        return [
                            '<div class="two wide field">',
                            '<label for="comuna_propietario'+this.props.index+'">Comuna</label>',
                            '<input type="text" name="comuna_propietario'+this.props.index+'" id="comuna_propietario'+this.props.index+'" value="'+this.props.comuna+'" />',
                            '</div>',
                        ].join("\n")
                    },
                    fecha: () => {
                        return [
                            '<div class="three wide field">' +
                            '<label for="fecha_factura'+this.props.index+'">Fecha Factura</label>'+
                            '<div class="ui calendar" id="fecha_factura'+this.props.index+'">' +
                            '<div class="ui right icon input">' +
                            '<input type="text" name="fecha_factura'+this.props.index+'" />' +
                            '<i class="calendar icon"></i>' +
                            '</div>' +
                            '</div>' +
                            '</div>'
                        ].join("\n")
                    }
                }
            }
        }
        class Unidad extends BaseObject {
            update() {
                return {
                    precio: newValue => {
                        const url = '{{$urls->api}}/ventas/propiedades/unidad/' + this.props.propiedad_unidad_id + '/edit'
                        const method = 'post'
                        const body = new FormData()
                        body.set('valor', newValue)
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (!json.edited) {
                                    return
                                }
                                this.props.valor = parseFloat(json.input.valor)
                                //document.getElementById('precio' + this.props.propiedad_unidad_id).value = json.input.valor
                            })
                        })
                    },
                    prorrateo: newValue => {
                        const url = '{{$urls->api}}/ventas/unidad/' + this.props.id + '/prorrateo'
                        const method = 'post'
                        const body = new FormData()
                        body.set('prorrateo', newValue)
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (!json.edited) {
                                    return
                                }
                                this.props.prorrateo = json.input.prorrateo
                                document.getElementById('prorrateo'+this.props.id).parentElement.parentElement.innerHTML = ''
                            })
                        })
                    }
                }
            }
            watch() {
                return {
                    unidad: () => {
                        this.watch().precio()
                        this.watch().prorrateo()
                    },
                    precio: () => {
                        document.getElementById('precio'+this.props.propiedad_unidad_id).addEventListener('change', changeEvent => {
                            const newValue = changeEvent.currentTarget.value
                            if (newValue === this.props.valor) {
                                return
                            }
                            this.update().precio(newValue).then(() => {
                                facturas.venta.update().totalUnidades()
                                facturas.draw().facturas()
                            })
                        })
                    },
                    prorrateo: () => {
                        const input = document.getElementById('prorrateo'+this.props.id)
                        if (input === null) {
                            return
                        }
                        input.addEventListener('change', changeEvent => {
                            const newValue = changeEvent.currentTarget.value
                            if (newValue === this.props.prorrateo) {
                                return
                            }
                            this.update().prorrateo(newValue)
                            facturas.draw().facturas()
                        })
                    }
                }
            }
            draw() {
                return {
                    precio: () => {
                        return [
                            '<div class="three wide field">',
                                '<label for="precio'+this.props.propiedad_unidad_id+'">Precio<br /> '+this.props.tipo+' '+this.props.descripcion+'</label>',
                                '<div class="ui left labeled input" id="input'+this.props.propiedad_unidad_id+'">',
                                    '<div class="ui basic label">UF</div>',
                                    '<input class="price" type="text" name="precio'+this.props.propiedad_unidad_id+'" id="precio'+this.props.propiedad_unidad_id+'" data-id="'+this.props.propiedad_unidad_id+'" value="'+this.props.valor+'" />',
                                '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    prorrateo: () => {
                        const output = []
                        output.push('<div class="three wide field">')
                        if (this.props.prorrateo === 0) {
                            output.push(...[
                                '<label for="prorrateo'+this.props.id+'">Prorrateo<br /> '+this.props.tipo+' '+this.props.descripcion+'</label>',
                                '<div class="ui right labeled input">',
                                '<input class="prorrateo" type="text" id="prorrateo'+this.props.id+'" value="'+this.props.prorrateo+'" />',
                                '<div class="ui basic label">%</div>',
                                '</div>'
                            ])
                        }
                        output.push('</div>')
                        return output.join("\n")
                    }
                }
            }
        }
        class Venta extends BaseObject {
            update() {
                return {
                    propietarios: count => {
                        const diff = count - this.props.propietarios.length
                        if (diff > 0) {
                            const m = this.props.propietarios.length / count
                            let p = 1
                            this.props.propietarios.forEach((propietario, index) => {
                                this.props.propietarios[index].props.proporcion = parseFloat((this.props.propietarios[index].props.proporcion * m * 100).toFixed(0)) / 100
                                p -= this.props.propietarios[index].props.proporcion
                            })
                            p /= diff
                            const watch = []
                            for (let i = 0; i < diff; i ++) {
                                const propietario = this.add().propietario({
                                    rut: '',
                                    nombre: '',
                                    proporcion: (p*100).toFixed(0)/100,
                                    direccion: '',
                                    comuna: '',
                                    fecha: this.props.estado.fecha,
                                    uf: this.props.uf
                                })
                                watch.push(propietario)
                            }
                            document.getElementById('propietarios').innerHTML = this.draw().propietarios()
                            this.watch().propietarios()
                            return
                        }
                        for (let i = this.props.propietarios.length - 1; i >= count; i --) {
                            this.remove().propietario(i)
                        }
                    },
                    fecha: date => {
                        this.props.uf.fecha = date
                        const url = '{{$urls->api}}/money/uf'
                        const method = 'post'
                        const body = new FormData()
                        body.set('fecha', [date.getFullYear(), date.getMonth()+1, date.getDate()].join('-'))
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (typeof json.uf === 'undefined') {
                                    return
                                }
                                this.props.uf.valor = json.uf

                                return this.update().ipc()
                            })
                        })
                    },
                    fechaFacturas: date => {
                        if (this.props.fechaFactura === date) {
                            return
                        }
                        this.props.fechaFactura = date
                        this.props.propietarios.forEach((propietario, index) => {
                            this.props.propietarios[index].props.fecha = date
                        })
                        return new Promise(resolve => resolve())
                    },
                    totalUnidades: () => {
                        const unidades = this.props.unidades.reduce((sum, unidad) => sum + unidad.props.valor, 0)
                        const diff = parseFloat((this.props.valor - unidades).toFixed(4))
                        const $total = $('#total_unidades')
                        if (diff === 0) {
                            $total.html('')
                            return
                        }
                        $total.html('<div class="ui error compact message">' +
                            '<div class="header">' +
                            '<i class="exclamation triangle icon"></i>' +
                            'Diferencia Promesa - Precio Unidades</div>' +
                            'UF ' + facturas.formatters.ufs.format(diff) +
                            '</div>')
                        $total.find('.ui.message').css('display', 'inline-block')
                    },
                    terreno: newValue => {
                        const date = this.props.last.dicember

                        const url = '{{$urls->api}}/proyecto/{{$venta->proyecto()->id}}/terreno/edit'
                        const method = 'post'
                        const body = new FormData()
                        body.set('valor', newValue)
                        body.set('fecha', [date.getFullYear(), date.getMonth()+1, date.getDate()].join('-'))
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (!json.edited) {
                                    return
                                }
                                this.props.terreno.fecha = this.props.last.dicember
                                this.props.terreno.valor = parseInt(json.input.valor)

                                document.getElementById('terreno').parentElement.parentElement.remove()

                                this.update().ipc()
                            })
                        })
                    },
                    ipc: () => {
                        const mesAnterior = new Date([this.props.fechaFactura.getFullYear(), this.props.fechaFactura.getMonth()-1, '1'].join('-'))
                        const url = '{{$urls->api}}/money/ipc'
                        const method = 'post'
                        const body = new FormData()
                        body.set('start', [this.props.last.november.getFullYear(), this.props.last.november.getMonth()+1, this.props.last.november.getDate()].join('-'))
                        body.set('end', [mesAnterior.getFullYear(), mesAnterior.getMonth()+1, mesAnterior.getDate()].join('-'))
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                this.props.terreno.reajustado = this.props.terreno.valor * (1 + parseFloat(json.ipc))
                            })
                        })
                    },
                    form: () => {
                        // fecha
                        // unidades
                        // valor total unidades
                        // terreno
                        // propietarios
                        // ipc no disponible
                    }
                }
            }
            watch() {
                return {
                    venta: () => {
                        this.watch().fecha()
                        this.watch().fechaFacturas()
                        this.watch().unidades()
                        this.watch().terreno()
                        this.watch().cantidad()
                        this.watch().propietarios()
                        this.update().totalUnidades()
                    },
                    fecha: () => {
                        const cdo = structuredClone(calendar_date_options)
                        cdo['initialDate'] = this.props.estado.fecha
                        cdo['onChange'] = (date, text, mode) => {
                            this.update().fecha(date).then(() => {
                                facturas.draw().facturas()
                            })
                        }
                        $('#fecha_uf').calendar(cdo)
                    },
                    fechaFacturas: () => {
                        const cdo = structuredClone(calendar_date_options)
                        cdo['initialDate'] = this.props.estado.fecha
                        cdo['onChange'] = (date, text, mode) => {
                            this.update().fechaFacturas(date).then(() => {
                                facturas.draw().facturas()
                            })
                        }
                        $('#fecha_facturas').calendar(cdo)
                    },
                    unidades: () => {
                        this.props.unidades.forEach(unidad => {
                            unidad.watch().unidad()
                        })
                    },
                    terreno: () => {
                        const terreno = document.getElementById('terreno')
                        if (typeof terreno === 'undefined' || terreno === null) {
                            return
                        }
                        terreno.addEventListener('change', changeEvent => {
                            const newValue = changeEvent.currentTarget.value
                            if (newValue === this.props.terreno.valor) {
                                return
                            }
                            this.update().terreno(newValue)
                        })
                    },
                    cantidad: () => {
                        document.getElementById('cantidad_propietarios').addEventListener('change', changeEvent => {
                            const count = changeEvent.currentTarget.value
                            const diff = count - this.props.propietarios.length
                            if (diff === 0) {
                                return
                            }
                            this.update().propietarios(count)
                            facturas.draw().facturas()
                        })
                    },
                    propietarios: () => {
                        this.props.propietarios.forEach(propietario => {
                            propietario.watch().propietario()
                        })
                    }
                }
            }
            draw() {
                return {
                    venta: ufFormatter => {
                        return [
                            this.draw().value(ufFormatter),
                            this.draw().form(),
                            this.draw().ipc()
                        ].join("\n")
                    },
                    value: ufFormatter => {
                        return [
                            '<div class="ui grid">',
                            '<div class="three wide column">',
                            '<div class="ui very segment">',
                            'Valor Venta: UF ' + ufFormatter.format(this.props.valor),
                            '</div>',
                            '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    form: () => {
                        const output = []
                        output.push('<form id="venta_form" class="ui form">')
                        output.push(this.draw().fecha())
                        output.push(this.draw().fechaFactura())
                        output.push(this.draw().precios())
                        output.push(this.draw().prorrateos())
                        output.push('<div class="ui very basic segment" id="total_unidades"></div>')
                        output.push(this.draw().terreno())
                        output.push(...[
                            '<div class="two wide field">',
                                '<label for="propietarios">Propietarios</label>',
                                '<input type="number" name="cantidad_propietarios" id="cantidad_propietarios" min="1" value="1" />',
                            '</div>',
                        ])
                        output.push('<div id="propietarios">')
                        output.push(this.draw().propietarios())
                        output.push('</div>')
                        output.push('</form>')
                        return output.join("\n")
                    },
                    fecha: () => {
                        return [
                            '<div class="three wide field">',
                            '<label for="fecha_uf">Fecha UF</label>',
                            '<div class="ui calendar" id="fecha_uf">',
                            '<div class="ui right icon input">',
                            '<input type="text" name="fecha_uf" />',
                            '<i class="calendar icon"></i>',
                            '</div>',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    fechaFactura: () => {
                        return [
                            '<div class="three wide field">',
                            '<label for="fecha_uf">Fecha Facturas</label>',
                            '<div class="ui calendar" id="fecha_facturas">',
                            '<div class="ui right icon input">',
                            '<input type="text" name="fecha_facturas" />',
                            '<i class="calendar icon"></i>',
                            '</div>',
                            '</div>',
                            '</div>',
                        ].join("\n")
                    },
                    precios: () => {
                        const output = []
                        output.push('<div class="fields">')
                        this.props.unidades.forEach(unidad => {
                            output.push(unidad.draw().precio())
                        })
                        output.push('</div>')
                        return output.join("\n")
                    },
                    prorrateos: () => {
                        const output = []
                        output.push('<div class="fields">')
                        this.props.unidades.forEach(unidad => {
                            output.push(unidad.draw().prorrateo())
                        })
                        output.push('</div>')
                        return output.join("\n")
                    },
                    terreno: () => {
                        const output = []
                        if (typeof this.props.terreno.fecha === 'undefined' || this.props.terreno.fecha === null || this.props.terreno.fecha.getTime() < 0 || this.props.terreno.fecha < this.props.last.dicember) {
                            output.push(...[
                                '<div class="four wide field">',
                                '<label for="terreno">Valor Terreno al '+this.props.last.dicember.toString()+'</label>',
                                '<div class="ui left labeled input">',
                                '<div class="ui basic label">$</div>',
                                '<input type="number" id="terreno" />',
                                '</div>',
                                '</div>'
                            ])
                        }
                        return output.join("\n")
                    },
                    propietarios: () => {
                        const output = []
                        this.props.propietarios.forEach(propietario => {
                            output.push(propietario.draw().propietario())
                        })
                        return output.join("\n")
                    },
                    ipc: () => {
                        if (!(this.props.fecha > this.props.terreno.fecha && this.props.terreno.valor === 0)) {
                            return ''
                        }
                        return [
                            '<div class="ui compact icon error message">',
                                '<i class="exclamation triangle icon"></i>',
                                '<div class="content">',
                                    'IPC no disponible para este mes.',
                                '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    facturas: formatters => {
                        const output = []
                        this.props.facturas.forEach((factura, index) => {
                            output.push(factura.draw().factura({
                                proyecto: this.props.proyecto,
                                propietario: this.props.propietarios[index],
                                unidades: this.props.unidades,
                                terreno: this.props.terreno,
                                venta: this.valores(this.props.uf.valor),
                                uf: this.props.uf,
                                formatters
                            }))
                        })
                        return output.join("\n")
                    }
                }
            }
            valores(uf) {
                const total = this.props.valor * uf
                const prorrateo = this.props.unidades.reduce((sum, unidad) => sum + unidad.props.prorrateo, 0)
                const exento = this.props.terreno.reajustado * prorrateo
                const bruto = total - exento
                const neto = bruto / 1.19
                const iva = neto * .19
                const base  = neto + exento
                return {
                    base,
                    exento,
                    neto,
                    iva,
                    bruto,
                    descuento: prorrateo,
                    total,
                    totalUF: total / uf,
                }
            }
            add() {
                return {
                    propietario: ({rut, nombre, proporcion, direccion, comuna, fecha}) => {
                        const index = this.props.propietarios.length + 1
                        const propietario = new Propietario({index, proporcion, rut, nombre, direccion, comuna, fecha})
                        this.props.propietarios.push(propietario)
                        this.add().factura(propietario)
                        return propietario
                    },
                    factura: propietario => {
                        const factura = new Factura({index: propietario.props.index})
                        this.props.facturas.push(factura)
                    }
                }
            }
            remove() {
                return {
                    propietario: index => {
                        if (index <= 0) {
                            return
                        }
                        const P1 = this.props.propietarios.reduce((sum, propietario) => sum + propietario.props.proporcion, 0)
                        const propietario = this.props.propietarios.splice(index, 1)[0]
                        const P2 = this.props.propietarios.reduce((sum, propietario) => sum + propietario.props.proporcion, 0)
                        document.querySelectorAll("[data-index='"+propietario.props.index+"']").forEach(field => {
                            field.remove()
                        })
                        this.remove().factura(index)
                    },
                    factura: index => {
                        this.props.facturas.splice(index, 1)
                        document.getElementById('facturas').querySelectorAll("[data-index='"+(index+1)+"']").forEach(factura => {
                            factura.remove()
                        })
                    }
                }
            }
            save() {
                return {
                    factura: ({index}) => {
                        const factura = this.props.facturas[index]
                        if (factura.props.saved) {
                            return
                        }
                        const url = '{{$urls->api}}/ventas/facturas/add'
                        const method = 'post'
                        const body = new FormData()
                        body.set('venta_id', this.props.id)
                        body.set('index', (index+1).toString())
                        const data = structuredClone(factura.props)
                        delete data.index
                        data.detalle.base = data.detalle.base.toFixed(0)
                        data.detalle.terreno = data.detalle.terreno.toFixed(0)
                        data.detalle.neto = data.detalle.neto.toFixed(0)
                        data.detalle.iva = data.detalle.iva.toFixed(0)
                        data.detalle.bruto = data.detalle.bruto.toFixed(0)
                        data.detalle.total = data.detalle.total.toFixed(0)
                        data.total.neto = data.total.neto.toFixed(0)
                        data.total.exento = data.total.exento.toFixed(0)
                        data.total.iva = data.total.iva.toFixed(0)
                        data.total.total = data.total.total.toFixed(0)
                        data.fecha = [data.fecha.getFullYear(), data.fecha.getMonth()+1, data.fecha.getDate()].join('-')
                        data.uf.fecha = [data.uf.fecha.getFullYear(), data.uf.fecha.getMonth()+1, data.uf.fecha.getDate()].join('-')
                        body.set('data', JSON.stringify(data))
                        return fetchAPI(url, {method, body}).then(response => {
                            if (!response) {
                                return
                            }
                            return response.json().then(json => {
                                if (!json.saved) {
                                    return
                                }
                                this.props.facturas[json.factura.index-1].props.saved = true
                            })
                        })
                    }
                }
            }
        }
        class Factura extends BaseObject {
            draw() {
                return {
                    divider: index => {
                        return '<div class="ui divider" data-index="'+index+'"></div>'
                    },
                    factura: ({proyecto, propietario, unidades, terreno, venta, uf, formatters = {date, pesos, ufs, percent}}) => {
                        this.props.proporcion = propietario.props.proporcion
                        this.props.emisor = {
                            nombre: proyecto.inmobiliaria.nombre,
                            rut: proyecto.inmobiliaria.rut,
                            direccion: proyecto.direccion
                        }
                        this.props.receptor = {
                            nombre: propietario.props.nombre,
                            rut: propietario.props.rut,
                            direccion: propietario.props.direccion,
                            comuna: propietario.props.comuna
                        }
                        this.props.fecha = propietario.props.fecha
                        this.props.unidades = []
                        this.props.detalle = {
                            base: venta.base * propietario.props.proporcion,
                            terreno: venta.exento * propietario.props.proporcion,
                            neto: venta.neto * propietario.props.proporcion,
                            iva: venta.iva * propietario.props.proporcion,
                            bruto: venta.bruto * propietario.props.proporcion,
                            descuento: venta.descuento * propietario.props.proporcion,
                            total: venta.total * propietario.props.proporcion
                        }
                        this.props.total = {
                            neto: venta.neto * propietario.props.proporcion,
                            exento: venta.exento * propietario.props.proporcion,
                            iva: venta.iva * propietario.props.proporcion,
                            total: venta.total * propietario.props.proporcion,
                        }
                        this.props.uf = uf
                        unidades.forEach(unidad => {
                            const descuento = terreno.reajustado * unidad.props.prorrateo
                            const bruto = unidad.props.valor * uf.valor - descuento
                            const neto = bruto / 1.19
                            this.props.unidades.push({
                                descripcion: unidad.props.tipo + ' ' + unidad.props.descripcion + ' (UF ' + formatters.ufs.format(unidad.props.valor * propietario.props.proporcion) + ')',
                                precio: (neto * propietario.props.proporcion).toFixed(0)
                            })
                        })
                        return [
                            this.draw().divider(propietario.props.index),
                            '<div class="factura" data-index="'+propietario.props.index+'">',
                                '<div class="ui compact grid">',
                                    this.draw().cabecera(proyecto),
                                    this.draw().propietario({propietario, formatters}),
                                    this.draw().table({venta, unidades, propietario, terreno, uf, formatters}),
                                    this.draw().totales({propietario, venta, uf, formatters}),
                                    this.draw().guardar({index: propietario.props.index}),
                                '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    cabecera: proyecto => {
                        return [
                            '<div class="two columns row">',
                                this.draw().inmobiliaria(proyecto),
                                this.draw().rut(proyecto.inmobiliaria),
                            '</div>'
                        ].join("\n")
                    },
                    inmobiliaria: proyecto => {
                        return [
                            '<div class="twelve wide column">',
                            '<strong>'+proyecto.inmobiliaria.nombre.toUpperCase()+'</strong><br/>',
                            'GIRO: <br/>',
                            'Dirección: '+proyecto.direccion,
                            '</div>',
                        ].join("\n")
                    },
                    rut: inmobiliaria => {
                        return [
                            '<div class="four wide column">',
                                '<div class="ui center aligned red segment">',
                                    '<strong>',
                                        'RUT:'+inmobiliaria.rut.toUpperCase()+'<br/>',
                                        'FACTURA ELECTRÓNICA<br/>',
                                        'N° #',
                                    '</strong>',
                                '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    propietario: ({propietario, formatters}) => {
                        return [
                            '<div class="row">',
                                '<table class="ui table">',
                                    '<tr>'+
                                        '<td class="grey"><strong>Señor(es)</strong></td>',
                                        '<td>'+propietario.props.nombre+'</td>',
                                        '<td class="grey"><strong>RUT</strong></td>',
                                        '<td>'+propietario.props.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(propietario.props.fecha)+'</td>',
                                    '</tr>',
                                    '<tr>',
                                        '<td class="grey"><strong>Dirección</strong></td>',
                                        '<td>'+propietario.props.direccion+'</td>',
                                        '<td class="grey"><strong>Comuna</strong></td>',
                                        '<td>'+propietario.props.comuna.toUpperCase()+'</td>',
                                    '</tr>',
                                '</table>',
                            '</div>'
                        ].join("\n")
                    },
                    table: ({venta, unidades, propietario, terreno, uf, 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({venta, unidades, propietario, terreno, uf, formatters}),
                            '</tbody>',
                            '<tfoot>',
                            '<tr>',
                            '<td colspan="6">',
                            '<br />',
                            '<br />',
                            '<br />',
                            '<br />',
                            '</td>',
                            '</tr>',
                            '</tfoot>',
                            '</table>',
                            '</div>'
                        ].join("\n")
                    },
                    unidades: ({venta, unidades, propietario, terreno, uf, formatters}) => {
                        const unidadesData = []
                        let no = 1
                        const classes = [
                            '',
                            '',
                            'center aligned',
                            'right aligned',
                            'center aligned',
                            'right aligned'
                        ]
                        unidades.forEach(unidad => {
                            unidadesData.push(this.draw().unidad({
                                unidad,
                                propietario,
                                terreno,
                                uf,
                                no: no++,
                                classes,
                                formatters
                            }))
                        })
                        unidadesData.push(this.draw().resumen({
                            propietario,
                            venta,
                            uf,
                            no,
                            classes,
                            formatters
                        }))
                        return unidadesData.join("\n")
                    },
                    unidad: ({unidad, propietario, terreno, uf, no, classes, formatters}) => {
                        const descuento = terreno.reajustado * unidad.props.prorrateo
                        const bruto = unidad.props.valor * uf.valor - descuento
                        const neto = bruto / 1.19
                        const data = [
                            no,
                            unidad.props.tipo + ' ' + unidad.props.descripcion + ' (UF ' + formatters.ufs.format(unidad.props.valor * propietario.props.proporcion) + ')',
                            '1 UNID',
                            formatters.pesos.format(neto * propietario.props.proporcion),
                            'AF',
                            formatters.pesos.format(neto * propietario.props.proporcion)
                        ]

                        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: ({propietario, venta, uf, no, classes, formatters}) => {
                        const emptyTerreno = '<div class="ui tiny red horizontal circular label">0</div>'
                        const data = [
                            no,
                            'Valor con Terreno: $' + formatters.pesos.format(venta.base * propietario.props.proporcion) + ' - Menos valor terreno: $' + ((venta.exento > 0) ? formatters.pesos.format(-venta.exento * propietario.props.proporcion) : emptyTerreno) + '<br />' +
                            'Base imponible (Neto): $' + formatters.pesos.format(venta.neto * propietario.props.proporcion) + '<br />' +
                            'IVA: $' + formatters.pesos.format(venta.iva * propietario.props.proporcion) + '<br />' +
                            'SUBTOTAL (Bruto): $' + formatters.pesos.format((venta.neto + venta.iva) * propietario.props.proporcion) + '<br />' +
                            'Mas valor terreno: $' + ((venta.exento > 0) ? formatters.pesos.format(venta.exento * propietario.props.proporcion) : emptyTerreno) + '<br />' +
                            'TOTAL (Escritura): $' + formatters.pesos.format(venta.total * propietario.props.proporcion) + '; ' + formatters.ufs.format(venta.totalUF * propietario.props.proporcion) + ' UF<br /><br />' +
                            'Descuento Terreno: ' + ((venta.exento > 0) ? formatters.percent.format(venta.descuento * propietario.props.proporcion * 100) : emptyTerreno) + '%<br /><br />' +
                            'UF (' + formatters.date.format(uf.fecha) + '): $' + formatters.ufs.format(uf.valor),
                            '1 UNID',
                            formatters.pesos.format(venta.exento * propietario.props.proporcion),
                            'EX',
                            formatters.pesos.format(venta.exento * propietario.props.proporcion)
                        ]

                        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: ({propietario, venta, formatters}) => {
                        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" id="neto">'+formatters.pesos.format(venta.neto * propietario.props.proporcion)+'</td>',
                            '</tr>',
                            '<tr>',
                            '<td class="grey">Monto Exento</td>',
                            '<td class="right aligned" id="exento">'+formatters.pesos.format(venta.exento * propietario.props.proporcion)+'</td>',
                            '</tr>',
                            '<tr>',
                            '<td class="grey">19% IVA</td>',
                            '<td class="right aligned" id="iva">'+formatters.pesos.format(venta.iva * propietario.props.proporcion)+'</td>',
                            '</tr>',
                            '<tr>',
                            '<td class="grey">Monto Total</td>',
                            '<td class="right aligned"><strong id="total">'+formatters.pesos.format(venta.total * propietario.props.proporcion)+'</strong></td>',
                            '</tr>',
                            '</tbody>',
                            '</table>',
                            '</div>',
                            '</div>'
                        ].join("\n")
                    },
                    guardar: ({index}) => {
                        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">',
                                '<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="${index}">Guardar</button>`,
                            '</div>',
                            '</div>'
                        ].join("\n")
                    }
                }
            }
        }

        const facturas = {
            ids: {},
            venta: null,
            formatters: {
                date: new Intl.DateTimeFormat('es-CL', {year: 'numeric', month: '2-digit', day: '2-digit'}),
                pesos: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 0, maximumFractionDigits: 0}),
                ufs: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 2, maximumFractionDigits: 2}),
                percent: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 4, maximumFractionDigits: 4})
            },
            draw() {
                return {
                    venta: () => {
                        document.getElementById(this.ids.venta).innerHTML = this.venta.draw().venta(this.formatters.ufs)
                        this.venta.watch().venta()
                    },
                    facturas: () => {
                        document.getElementById(this.ids.facturas).innerHTML = this.venta.draw().facturas(this.formatters)
                        $('button.guardar').click(clickEvent => {
                            const index = clickEvent.currentTarget.getAttribute('data-index')
                            facturas.venta.save().factura({index: index-1})
                        })
                    }
                }
            },
            setup({ids}) {
                this.ids = ids
                this.venta = new Venta({
                    id: {{$venta->id}},
                    proyecto: {
                        id: {{$venta->proyecto()->id}},
                        inmobiliaria: {
                            rut: '{{$venta->proyecto()->inmobiliaria()->rut()}}',
                            nombre: '{{$venta->proyecto()->inmobiliaria()->nombreCompleto()}}'
                        },
                        direccion: '{{$venta->proyecto()->direccion()->simple()}}, {{$venta->proyecto()->direccion()->comuna->descripcion}}'
                    },
                    valor: {{$venta->valor}},
                    uf: {
                        fecha: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
                        valor: {{$uf}}
                    },
                    fechaFactura: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
                    estado: {
                        fecha: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}')
                    },
                    terreno: {
                        fecha: new Date('{{$terreno->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
                        valor: {{$terreno->valor}},
                        reajustado: {{$terreno->valor * (1+$ipc)}}
                    },
                    last: {
                        dicember: new Date('{{(new DateTimeImmutable())->sub(new DateInterval('P1Y'))->format('Y-11-31')}}'),
                        november: new Date('{{(new DateTimeImmutable())->sub(new DateInterval('P1Y'))->format('Y-11-30')}}')
                    },
                    unidades: [
                        @foreach ($venta->propiedad()->unidades as $unidad)
                        new Unidad({
                            id: {{$unidad->id}},
                            tipo: '{{ucwords($unidad->proyectoTipoUnidad->tipoUnidad->descripcion)}}',
                            descripcion: '{{$unidad->descripcion}}',
                            prorrateo: {{$unidad->prorrateo}},
                            propiedad_unidad_id: {{$unidad->pu_id}},
                            valor: {{($unidad->valor > 0) ? $unidad->valor : $unidad->precio($venta->currentEstado()->fecha)->valor}}
                        }),
                        @endforeach
                    ],
                    propietarios: [],
                    facturas: []
                })
                @if (count($facturas) > 0)
                    this.venta.props.uf = {
                        fecha: new Date('{{$facturas[0]->fechaUF->format('Y-m-d')}}'),
                        valor: {{$facturas[0]->valorUF}}
                    }
                    @foreach ($facturas as $factura)
                        this.venta.props.facturas[{{$factura->index-1}}] = new Factura(JSON.parse('{!! json_encode($factura) !!}'))
                        this.venta.props.facturas[{{$factura->index-1}}].props.saved = true
                        this.venta.props.propietarios[{{$factura->index-1}}] = new Propietario({
                            index: {{$factura->index}},
                            proporcion: {{$factura->proporcion}},
                            rut: '{{$factura->receptorRut}}',
                            nombre: '{{$factura->receptorNombre}}',
                            direccion: '{{$factura->receptorDireccion}}',
                            comuna: '{{$factura->receptorComuna}}',
                            fecha: new Date('{{$factura->fecha->format('Y-m-d')}}'),
                        })
                    @endforeach
                    @else
                    this.venta.add().propietario({
                        rut: '{{$venta->propietario()->rut()}}',
                        nombre: '{{$venta->propietario()->nombreCompleto()}}',
                        proporcion: 1,
                        direccion: '{{$venta->propietario()->datos->direccion->simple()}}',
                        comuna: '{{$venta->propietario()->datos->direccion->comuna->descripcion}}',
                        fecha: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
                        uf: {{$uf}}
                    })
                @endif
                this.draw().venta()
                this.draw().facturas()
            }
        }
        $(document).ready(() => {
            facturas.setup({
                ids: {
                    venta: 'venta',
                    facturas: 'facturas'
                }
            })
        })
    </script>
@endpush
