import {useEffect, useState} from "react";

function TrainsTable({stop, date, time, tableType}) {
  let tableClass = tableType === "departures" ? "table-departures" : "table-arrivals"
  tableClass = `table table-striped ${tableClass}`
  return <>
    <table className={tableClass}>
      <TrainsTableHeader />
      <TrainsTableBody stop={stop} date={date} time={time} tableType={tableType} />
    </table>
  </>
}

function TrainsTableHeader() {
  return <thead>
    <tr>
      <th className="px-3 py-1" scope="col" colSpan="2">Train</th>
      <th className="px-3 py-1" scope="col">Heure</th>
      <th className="px-3 py-1" scope="col">Destination</th>
    </tr>
  </thead>
}

function TrainsTableBody({stop, date, time, tableType}) {
  const [trains, setTrains] = useState([])

  useEffect(() => {
    if (stop.id !== undefined) {
      fetch(`http://localhost:8000/api/station/next_${tableType}/?stop_id=${stop.id}&date=${date}&time=${time}&format=json`)
        .then(response => response.json())
        .then(data => data.results)
        .then(data => {
          setTrains(data)
        })
    }
  }, [stop, tableType, date, time])

  let table_rows = trains.map((train) => <TrainRow train={train} tableType={tableType} />)

  return <tbody>
    {table_rows}
  </tbody>
}

function TrainRow({train, tableType}) {
  const [trip, setTrip] = useState({})
  const [route, setRoute] = useState({})
  const [stopTimes, setStopTimes] = useState([])
  const [trainType, setTrainType] = useState("")

  useEffect(() => {
    if (train.trip !== undefined) {
      fetch(`http://localhost:8000/api/gtfs/trip/${train.trip}/`)
        .then(response => response.json())
        .then(t => {
          t.stop_times = []
          setTrip(t)
        })
    }
  }, [train.trip])

  useEffect(() => {
    if (trip.route !== undefined) {
      fetch(`http://localhost:8000/api/gtfs/route/${trip.route}/`)
        .then(response => response.json())
        .then(data => {
          setRoute(data)
        })
    }
  }, [trip.route])

  useEffect(() => {
    if (route !== undefined) {
      setTrainType(getTrainType(train, route))
    }
  }, [train, route]);

  useEffect(() => {
    if (trip.route !== undefined) {
      fetch(`http://localhost:8000/api/gtfs/stop_time/?trip=${trip.id}&order=stop_sequence&limit=1000`)
        .then(response => response.json())
        .then(data => data.results)
        .then(stop_times => {
          Promise.all(stop_times.map(stop_time =>
            fetch(`http://localhost:8000/api/gtfs/stop/${stop_time.stop}/`).then(response => response.json())
          )).then(stops => {
            setStopTimes(stop_times.map((stop_time, index) => {
              stop_time.stop = stops[index]
              return stop_time
            }))
          })
        })
    }
  }, [trip.route])

  let headline = stopTimes[tableType === "departures" ? stopTimes.length - 1 : 0]?.stop ?? {name: "Chargement…"}
  let stops_names = stopTimes.filter(stop_time => tableType === "departures" ? stop_time.stop_sequence > train.stop_sequence : stop_time.stop_sequence < train.stop_sequence)
    .map(stop_time => stop_time?.stop.name ?? "").join(", ")

  let style = {
    width: "4em",
    height: "4em",
    borderRadius: "15%",
    backgroundColor: `#${getBackgroundColor(train, route)}`,
    color: `#${getTextColor(train, route)}`,
    fontWeight: "bold",
  }

  return <>
    <tr className="h-100">
      <td className="h-100">
        <div className="train-type d-flex h-100 align-items-center justify-content-center">
          <div
            className="transilien-route d-flex align-items-center justify-content-center font-weight-bold small p-1 m-2 text-center text-wrap"
            style={style}>
            {trainType}
        </div>
      </div>
    </td>
    <td className="h-100">
      <div className="train-number d-flex align-items-center justify-content-center h-100">
        <div>
          <div>{trip.short_name}</div>
          <div>{trip.headsign}</div>
        </div>
      </div>
    </td>
    <td>
      <div className="table-hour d-flex align-items-center justify-content-center text-time fw-bold h-100">
        {getDisplayTime(train, tableType)}
      </div>
    </td>
    <td>
      <h3 className="headline">{headline.name}</h3>
      <span className="stops">{stops_names}</span>
    </td>
    </tr>
  </>
}

function getTrainType(train, route) {
  if (train.id.startsWith("IDFM"))
    return route.short_name
  else {
    let trainType = train.stop.split("StopPoint:OCE")[1].split("-")[0]
    if (trainType === "Train TER")
      trainType = "TER"
    else if (trainType === "INTERCITES")
      trainType = "INTER-CITÉS"
    else if (trainType === "INTERCITES de nuit")
      trainType = "INTER-CITÉS de nuit"
    return trainType
  }
}

function getBackgroundColor(train, route) {
  if (route.color)
    return route.color
  else if (getTrainType(train, route) === "OUIGO")
    return "E60075"
  return "FFFFFF"
}

function getTextColor(train, route) {
  if (route.text_color)
    return route.text_color
  else {
    let trainType = getTrainType(train, route)
    switch (trainType) {
      case "OUIGO":
        return "FFFFFF"
      case "TGV INOUI":
        return "9B2743"
      case "ICE":
        return "B4B4B4"
      case "INTER-CITÉS":
      case "INTER-CITÉS de nuit":
        return "404042"
      default:
        return "000000"
    }
  }
}

function getDisplayTime(train, tableType) {
  let time = tableType === "departures" ? train.departure_time : train.arrival_time
  let day_split = time.split(' ')
  return day_split[day_split.length - 1].substring(0, 5)
}

export default TrainsTable;