import { useEffect, useReducer } from "react";

import "../config/globals";
import assets from "../config/assets";

const custom_assets = {
  pluviometer: assets.pluviometer,
  floodZones: assets.floodZones,
  riverLevel: ["low", "normal", "high", "flooding"].map((key) => {
    return assets.riverLevel[key];
  }),
  rainLevel: [
    "rain_0_5",
    "rain_1_5",
    "rain_2_5",
    "rain_3_5",
    "rain_4_5",
    "rain_5_5",
  ].map((key) => {
    return assets.rainLevel[key];
  }),
};

// NOTE: For debug pourposes, every icon will be placed some `offset` from
// another. In final release, offset must be assigned to 0.0
var offset = 0.0001;
var displacement = 0;

var ID = 0;

var fetched_data = {
  pluv: new Set(),
  flood: new Set(),
  rain: new Set(),
  river: new Set(),
};

function is_valid(id, category) {
  if (fetched_data[category].has(id)) {
    return false;
  } else {
    fetched_data[category].add(id);
  }
  return true;
}

function partsePluviometer(row) {
  if (!is_valid(row["Id"], "pluv")) {
    return null;
  }

  const description = row["Description"] ? "\n\n" + row["Description"] : "";
  // displacement += offset;
  const i = {
    ID: ++ID,
    name: "pluviometer",
    title: "Pluviometro",
    coordinate: {
      latitude: row["Latitude"] + displacement,
      longitude: row["Longitude"],
    },
    image: custom_assets.pluviometer,
    date: row["Date"],
    description:
      row["Precipitation"] + "mm" + ",  " + row["Date"] + description,
    pictures: row["Images"],
    address: row["Address"],
  };
  console.log(i);
  return i;
}

function parseFloodZones(row) {
  if (!is_valid(row["Id"], "flood")) {
    return null;
  }

  // displacement += offset;
  return {
    ID: ++ID,
    name: "flood",
    title: row["Passable"] == 1 ? "Transponível" : "Intransponível",
    coordinate: {
      latitude: row["Latitude"],
      longitude: row["Longitude"] + displacement,
    },
    image:
      row["Passable"] == 1
        ? custom_assets.floodZones.passable
        : custom_assets.floodZones.notPassable,
    description: row["Description"],
    date: row["Date"] + " | " + row["Time"],
    pictures: row["Images"],
    address: row["Address"],
  };
}

function parseRiverLevel(row) {
  if (!is_valid(row["Id"], "river")) {
    return null;
  }
  console.log(JSON.stringify(row));
  // displacement += offset;
  const riverLevel = ["baixo", "normal", "alto", "transbordando"];
  const riverIdx = row["RiverIdx"];
  return {
    ID: ++ID,
    name: "river",
    title: "Rio " + riverLevel[riverIdx],
    coordinate: {
      latitude: row["Latitude"],
      longitude: row["Longitude"] + displacement,
    },
    image: custom_assets.riverLevel[riverIdx],
    description: row["Description"],
    date: row["Date"] + " | " + row["Time"],
    pictures: row["Images"],
    address: row["Address"],
  };
}

function parseRainLevel(row) {
  if (!is_valid(row["Id"], "rain")) {
    return null;
  }

  // displacement += offset;
  const rainLevel = [
    "Sem chuva",
    "Chuva fraca",
    "Chuva moderada",
    "Chuva forte",
    "Chuva muito forte",
    "Pancada de chuva",
  ];
  const rainIdx = row["RainIdx"];
  const description = row["Description"] ? row["Description"] : "";

  return {
    ID: ++ID,
    name: "rain",
    title: rainLevel[rainIdx],
    coordinate: {
      latitude: row["Latitude"],
      longitude: row["Longitude"] + displacement,
    },
    image: custom_assets.rainLevel[rainIdx],
    description: description,
    date: row["Date"] + " | " + row["Time"],
    pictures: row["Images"],
    address: row["Address"],
  };
}

function parseResult(db_result, parseRow) {
  var warnings = [];

  for (let i = 0; i < db_result.rows.length; ++i) {
    var row = db_result.rows.item(i);
    const data = parseRow(row);
    if (data !== null) {
      warnings.push(data);
    }
  }

  return warnings;
}

function isAvailable(dataBase) {
  return dataBase !== undefined && dataBase !== null;
}

function genericSelect(queriesToParsersMapper, dispatch, isFocused) {
  useEffect(() => {
    console.log("requesting data");
    if (isAvailable(global.userDataBase)) {
      queriesToParsersMapper.forEach(([query, parser]) => {
        global.userDataBase.transaction((tx) => {
          tx.executeSql(query, [], (tx, results) => {
            dispatch({ increment: parseResult(results, parser) });
          });
        });
      });
    }
  }, [isFocused]);
}

const initialState = { markers: new Set() };

function reducer(state = initialState, action) {
  action.increment.map((val) => {
    state.markers.add(val);
  });

  return {
    markers: state.markers,
  };
}

function useMarkers(isFocused) {
  const [state, dispatch] = useReducer(reducer, initialState);

  const queriesToParsersMapper = [
    ["SELECT * FROM FloodZones;", parseFloodZones],
    ["SELECT * FROM Pluviometer;", partsePluviometer],
    ["SELECT * FROM RiverLevel;", parseRiverLevel],
    ["SELECT * FROM RainLevel;", parseRainLevel],
  ];

  genericSelect(queriesToParsersMapper, dispatch, isFocused);

  return state;
}

export default useMarkers;