import React, {Component} from 'react';
import {Button, ButtonGroup, Container, Table} from 'reactstrap';
import AppNavbar from './AppNavbar';
import {Link} from 'react-router-dom';
import {saveAs} from 'file-saver';

class ClientList extends Component {

    constructor(props) {
        super(props);
        this.state = {clients: []};
        this.remove = this.remove.bind(this);
    }

    componentDidMount() {
        fetch('/clients')
            .then(response => response.json())
            .then(data => this.setState({clients: data}));
    }

    async remove(id) {
        await fetch(`/clients/${id}`, {
            method: 'DELETE',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        }).then(() => {
            let updatedClients = [...this.state.clients].filter(i => i.id !== id);
            this.setState({clients: updatedClients});
        });
    }

    async generateInvoice(nip) {
        fetch(`/invoices`, {
            method: 'POST',
            body: JSON.stringify({nip: `${nip}`, monthOfInvoice: 'a1'}),
            headers: {
                'Accept': 'application/pdf',
                'Content-Type': 'application/json'
            }
        })
            .then(response => {
                if (response.status === 401 || response.status === 403) {
                    alert("Error " + response.status);
                    sessionStorage.clear();
                    return;
                }
                const filename = response.headers.get("Content-Disposition").split("filename=")[1];
                response.blob()
                    .then(blob => saveAs(new Blob([blob]), filename));
            });
    }

    render() {
        const {clients} = this.state;

        const clientList = clients.map(client => {
            return <tr key={client.nip}>
                <td style={{whiteSpace: 'nowrap'}}>{client.name}</td>
                <td>{client.nip}</td>
                <td>
                    <ButtonGroup>
                        <Button size="sm" color="primary" tag={Link} to={"/clients/" + client.nip}>Edit</Button>
                        <Button size="sm" color="danger" onClick={() => this.remove(client.nip)}>Delete</Button>
                        <Button size="sm" color="primary" onClick={() => this.generateInvoice(client.nip)}>Generate
                            invoice</Button>
                    </ButtonGroup>
                </td>
            </tr>
        });

        return (
            <div>
                <AppNavbar/>
                <Container fluid>
                    <div className="float-right">
                        <Button color="success" tag={Link} to="/clients/new">Add Client</Button>
                    </div>
                    <h3>Clients</h3>
                    <Table className="mt-4">
                        <thead>
                        <tr>
                            <th width="30%">Name</th>
                            <th width="30%">NIP</th>
                            <th width="40%">Actions</th>
                        </tr>
                        </thead>
                        <tbody>
                        {clientList}
                        </tbody>
                    </Table>
                </Container>
            </div>
        );
    }
}

export default ClientList;