import React, { FC, useState } from 'react'
import {
  MybringCustomerAndServices,
  Order,
  OrderItem,
  ServiceDetails,
  ValidationError,
} from '../model/models'
import ShippingOptionSelector from './ShippingOptionSelector'
import bringTruck from '../../../assets/img/bring-truck.png'
import { useI18n } from '@wordpress/react-i18n'
import apiFetch from '@wordpress/api-fetch'

export declare interface OrdersProps {
  orders: Array<Order>
  onSave: (_orderId: string, _?: Order) => void
  mapServiceId: (_: string | undefined) => string | undefined | React.ReactNode
  customerNumber?: string
  customers: Array<MybringCustomerAndServices>
  bookingStatus: Record<string, string>
  driving: Set<string>
}

const Orders: FC<OrdersProps> = ({
  orders,
  onSave,
  mapServiceId,
  customerNumber,
  customers,
  bookingStatus,
  driving,
}) => {
  const [visibleOrderIds, setVisibleOrderIds] = useState<string[]>([])
  const [editedOrder, setEditedOrder] = useState<Order>()
  const [editingOrderId, setEditingOrderId] = useState<string | null>(null)
  const [availableServicesForOrder, setAvailableServicesForOrder] = useState<
    Array<ServiceDetails>
  >([])
  const { __ } = useI18n()

  const toggleOrderDetails = (orderId: string) => {
    setVisibleOrderIds(prevState =>
      prevState.includes(orderId)
        ? prevState.filter(id => id !== orderId)
        : [...prevState, orderId]
    )
  }

  const onEdit = async (order: Order) => {
    setAvailableServicesForOrder(
      await apiFetch({ path: '/posten-bring-checkout/services' })
    )
    setEditingOrderId(order.order_id)
    setEditedOrder({ ...order })
  }

  const onChange = (value: number, field: string) => {
    if (editedOrder) {
      setEditedOrder({
        ...editedOrder,
        [field]: value,
      })
    }
  }

  const handleSave = (orderId: string) => {
    onSave(orderId, editedOrder)
    setEditingOrderId(null)
    setEditedOrder(undefined)
  }

  return orders.map((order, index) => (
    <React.Fragment key={order.order_id}>
      <tr className={`order-row ${index % 2 === 0 ? 'even' : 'odd'}`}>
        <td>
          {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
          <a
            href="#"
            onClick={e => {
              e.preventDefault()
              toggleOrderDetails(order.order_id)
            }}
          >
            #{order.order_id}
          </a>
        </td>
        <td className={'order-list-shipping-options'}>
          {editingOrderId === order.order_id ? (
            <ShippingOptionSelector
              selectedShippingOption={
                editedOrder?.order_shipping_option ||
                order.order_shipping_option
              }
              setSelectedShippingOption={selected => {
                onChange(selected, 'order_shipping_option')
              }}
              availableServices={availableServicesForOrder}
              selectedCustomer={customerNumber || customers[0].customerNumber}
              customersAndServices={customers}
              preSelectedShippingOption={undefined}
              label={undefined}
            />
          ) : (
            mapServiceId(order.order_shipping_option)
          )}
        </td>
        <td className={'order-list-weight'}>
          {editingOrderId === order.order_id ? (
            <input
              className="weight-input"
              type="number"
              value={
                editedOrder?.total_weight
                  ? editedOrder.total_weight / 1000
                  : editedOrder?.total_weight
              }
              step={0.1}
              onChange={e =>
                onChange(e.target.valueAsNumber * 1000, 'total_weight')
              }
            />
          ) : (
            `${order.total_weight / 1000} kg`
          )}
        </td>
        <td className="action-cell">
          {!bookingStatus[order.order_id] &&
          editingOrderId === order.order_id ? (
            // eslint-disable-next-line jsx-a11y/anchor-is-valid
            <a
              href="#"
              onClick={e => {
                e.preventDefault()
                handleSave(order.order_id)
              }}
            >
              {__('Save', 'posten-bring-checkout')}
            </a>
          ) : (
            !bookingStatus[order.order_id] &&
            !order.order_validation_errors.some(
              value => value.bookingDisabled
            ) && (
              // eslint-disable-next-line jsx-a11y/anchor-is-valid
              <a
                href="#"
                onClick={e => {
                  e.preventDefault()
                  onEdit(order)
                }}
              >
                {__('Edit', 'posten-bring-checkout')}
              </a>
            )
          )}
          <div
            className={`truck ${
              bookingStatus[order.order_id] ? 'truck__visible' : 'truck__hidden'
            } ${driving.has(order.order_id) ? 'truck__driving' : ''}`}
          >
            <div className="flex align-ic gas flex-dir-row flex-nowrap">
              <div className="result-container">
                {bookingStatus[order.order_id] === 'error' ? (
                  <span>❌</span>
                ) : (
                  <span className="success">OK</span>
                )}
              </div>
              <div className="truck-container flex flex-dir-col justify-cc">
                <img
                  className="bring-truck-icon"
                  src={bringTruck}
                  alt={'ok!'}
                />
              </div>
            </div>
          </div>
          {!bookingStatus[order.order_id] && (
            <span className="warning-icon">
              {order.order_validation_errors.some(
                value => value.bookingDisabled
              )
                ? '⚠️'
                : ''}
            </span>
          )}
          &nbsp;
        </td>
      </tr>
      <tr
        className={`order-row ${index % 2 === 0 ? 'even' : 'odd'}`}
        style={{
          display: `${
            visibleOrderIds.includes(order.order_id) ? 'table-row' : 'none'
          }`,
        }}
      >
        <td colSpan={4}>
          {order.recipientName}
          <br />
          {order.recipientAddressLine}
          <br />
          {order.recipientPostalCode} {order.recipientCity}
          <br />
          <ul>
            {order.items &&
              order.items.map((item: OrderItem, orderIndex: number) => (
                <li key={orderIndex}>
                  <i>{item.name}</i> x {item.quantity}
                </li>
              ))}
          </ul>
          <ul>
            {order.order_validation_errors.map(
              (error: ValidationError, validationIndex: number) => (
                <li key={validationIndex}>
                  ⚠️ <i>{error.message}</i>
                </li>
              )
            )}
          </ul>
        </td>
      </tr>
    </React.Fragment>
  ))
}

export default Orders
