import React from "react";
import { Table, Button, Alert } from "react-bootstrap";
import Fetcher from "./Fetcher";
import EditableCell from "./EditableCell";
import ProductAdder from "./ProductAdder";
import AuthContext from "./AuthContext";
import { printMoney, url } from "./util";

class ProductList extends React.Component {
  static contextType = AuthContext;

  constructor(props) {
    super(props);
    this.state = {
      products: [],
      error: null,
    };
  }

  update(row, key, value) {
    this.setState({ error: null });

    let products = this.state.products;
    const code = products[row].code;

    switch (key) {
      case "code":
      case "stock":
        value = parseInt(value);
        break;
      case "price":
        value = value * 100;
        break;
      default:
        break;
    }
    products[row][key] = value;
    this.setState({ products });

    const body = JSON.stringify(products[row]);

    fetch(url("/api/product/" + code), {
      headers: { "x-authentication": this.context.token },
      method: "PUT",
      body,
    }).then((response) => {
      if (!response.ok) {
        this.setState({
          error: response.status.toString() + " " + response.statusText,
        });
      }
    });
  }

  delProduct(code) {
    let products = this.state.products;
    const index = products.findIndex((p) => p.code === code);
    products.splice(index, 1);
    this.setState({ products });

    fetch(url("/api/product/" + code), {
      headers: { "x-authentication": this.context.token },
      method: "DELETE",
    }).then((response) => {
      if (!response.ok) {
        this.setState({
          error: response.status.toString() + " " + response.statusText,
        });
      }
    });
  }

  addProduct(product) {
    let products = this.state.products;
    products.push(product);
    this.setState({ products });

    const body = JSON.stringify(product);
    fetch(url("/api/product"), {
      headers: { "x-authentication": this.context.token },
      method: "POST",
      body,
    }).then((response) => {
      if (!response.ok) {
        this.setState({
          error: response.status.toString() + " " + response.statusText,
        });
      }
    });
  }

  render() {
    let alert = null;
    if (this.state.error !== null) {
      alert = (
        <Alert variant="danger">
          Ha ocurrido un error enviando cambios: {this.state.error}
        </Alert>
      );
    }

    const isAdmin = this.context.role === "admin";
    const entries = this.state.products.map((product, row) => {
      return (
        <tr key={product.code}>
          <EditableCell
            onChange={(v) => this.update(row, "code", v)}
            value={product.code}
            ro={!isAdmin}
          />
          <EditableCell
            onChange={(v) => this.update(row, "name", v)}
            value={product.name}
            ro={!isAdmin}
          />
          <EditableCell
            onChange={(v) => this.update(row, "price", v)}
            value={printMoney(product.price)}
            ro={!isAdmin}
          />
          <EditableCell
            onChange={(v) => this.update(row, "stock", v)}
            value={product.stock}
            ro={!isAdmin}
          />
          {isAdmin && (
            <td sm={1}>
              <Button
                variant="danger"
                onClick={() => this.delProduct(product.code)}
              >
                -
              </Button>
            </td>
          )}
        </tr>
      );
    });

    return (
      <Fetcher
        url="/api/product"
        onFetch={(products) => this.setState({ products })}
      >
        {alert}
        <Table striped bordered hover responsive>
          <thead>
            <tr>
              <th>codigo</th>
              <th>Nombre</th>
              <th>Precio</th>
              <th>Existencias</th>
              {isAdmin && <th sm={1}></th>}
            </tr>
          </thead>
          <tbody>{entries}</tbody>
        </Table>
        {isAdmin && (
          <div>
            <p>AƱadir producto:</p>
            <ProductAdder addProduct={(p) => this.addProduct(p)} />
          </div>
        )}
      </Fetcher>
    );
  }
}

export default ProductList;