import React from "react";
import { connect } from "react-redux";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import { styled } from "@mui/material/styles";
import PouchDB from "pouchdb";
import { v4 as uuidv4 } from "uuid";

function TaskList(props) {
  // ToDo: Setup alerting for various actions through MaterialToas

  const project = props.projects.find(
    (project) => project.projectId === props.selectedProjectId
  );
  const currentProject = project.projectId;
  const currentProjectStr = JSON.stringify(project.projectId);
  const projectLink = "http://192.168.0.234:5984/" + currentProject;
  // Setup the data persistence
  const localTasksDB = new PouchDB(currentProjectStr);
  const remoteTasksDB = new PouchDB(projectLink, {
    auth: {
      username: "ditswbsclient",
      password: "bluebeard",
    },
  });

  const syncHandler = localTasksDB
    .sync(remoteTasksDB, {
      live: true,
      retry: true,
    })
    .on("paused", (info) => {
      console.log("Task replication paused");
    })
    .on("active", (info) => {
      console.log("Task replication resumed");
    })
    .on("change", (change) => {
      console.log("Task change detected");
    });

  const handleAddTask = () => {
    const taskName = prompt("Enter a new task name:");
    const description = prompt("Enter description for the task");
    const uniqueTaskId = uuidv4();
    console.log(uniqueTaskId);
    const commitToPDB = () => {
      console.log("entering commit to pouchdb");
      try {
        const response = localTasksDB.put({
          _id: uniqueTaskId,
          taskId: uniqueTaskId,
          taskName: taskName,
          description: description,
          status: "not started",
          parentIds: [project.projectId],
          completed: false,
        });
        console.log("added task", taskName);
      } catch (err) {
        console.log(err);
      }
    };
    const commitToRedux = () => {
      console.log("entering commit to redux");
      try {
        if (taskName) {
          props.dispatch({
          type: "ADD_TASK",
          taskId: uniqueTaskId,
          taskName: taskName,
          description: description,
          status: "not started",
          parentIds: [project.projectId],
          completed: false,
          });
        }
      } catch (error) {
        console.error("Could not add task to redux", error);
      }
      return () => {
        console.log("Task added to local store!");
      };
    };
    commitToRedux();
    commitToPDB();
  };

  function compareArraysAndFilterChanges(oldArray, newArray) {
  const changedTasks = [];

  oldArray.forEach((oldItem, index) => {
    const newItem = newArray[index];

    // Compare items based on your criteria
    if (!isEqual(oldItem, newItem)) {
      changedTasks.push(newItem);
    }
  });

  return changedTasks;
  }
  function isEqual(a, b) {
  // Implement your own comparison logic here
  // This can be a deep equality check using a library like lodash or a custom function
  return (
    JSON.stringify(a.completed) === JSON.stringify(b.completed) ||
    JSON.stringify(a.status) === JSON.stringify(b.status) ||
    JSON.stringify(a.description) === JSON.stringify(b.description) ||
    JSON.stringify(a.taskName) === JSON.stringify(b.taskName) 
     );
  }

  //Handle modifications to tasks
  const handleCommitChangesToPDB = () => {
    //identify if any field changed in
    //list of tasks in current redux state
    try {
      const filteredTasks = props.tasks.filter(
        (task) => task.parentIds[0] === project.projectId
      );
      localTasksDB
        .allDocs({ include_docs: true })
        .then((result) => {
          const existingTasks = result.rows.map((row) => row.doc);
          const uniqueChangedTasks = compareArraysAndFilterChanges(existingTasks,filteredTasks);
          console.log("changes", uniqueChangedTasks);
          if (uniqueChangedTasks !== undefined) {
              console.log("task change detected");
              uniqueChangedTasks.map((u) => {
                localTasksDB.get(u.taskId).then(function(doc) {
                  return localTasksDB.put({
                    _id: u.taskId,
                    _rev: doc._rev,
                    taskId: u.taskId,
                    taskName: u.taskName,
                    description: u.description,
                    status: u.status,
                    parentIds: u.parentIds,
                    completed: u.completed,
                  });
                }).then(function(response) {
                  console.log("Some tasks have been changed ")
                }).catch(function (err) {
                  console.log(err);
                });
              });
          } else {
            console.log("no task change detected");
          }
        })
        .then((result) => {
          console.log("Data change is successful.", result);
        })
        .catch((error) => {
          console.error("Error during change staging:", error);
        });
    } catch (error) {
      console.error("Error during data committement from staging: ", error);
    }
    return () => console.log("unmounting...");
  };

  const handleToggleTask = (id) => {
    props.dispatch({
      type: "TOGGLE_COMPLETED",
      id,
    });
  };

  const Item = styled(Paper)(({ theme }) => ({
    backgroundColor: theme.palette.mode === "dark" ? "#1A2027" : "#fff",
    ...theme.typography.body2,
    padding: theme.spacing(1),
    textAlign: "center",
    color: theme.palette.text.secondary,
  }));

  const filterByParentId = (taskList) => {
    return taskList
      .map((task) => {
        console.log(props.selectedProjectId);
        if (task.parentIds[0] === props.selectedProjectId) {
          return (
            <div>
              <Box sx={{ flexGrow: 1 }}>
                <Grid item xs="auto" key={task.taskId}>
                  <input
                    type="checkbox"
                    checked={task.completed}
                    onChange={() => handleToggleTask(task.taskId)}
                  />
                  <Item key={task.taskId} value={task.taskName}>
                    {task.taskName}
                  </Item>
                </Grid>
              </Box>
            </div>
          );
        }
        return null;
      })
      .filter(Boolean);
  };

  return (
    <div>
      <ul>{filterByParentId(props.tasks)}</ul>
      <button onClick={handleAddTask}>Add Task</button>
      <button onClick={handleCommitChangesToPDB}>
        Commit Changes To Tasks
      </button>
    </div>
  );
}

export default connect(mapStateToProps)(TaskList);

function mapStateToProps(state) {
  return {
    tasks: state.tasksReducer.tasks,
    selectedProjectId: state.projectsReducer.selectedProjectId,
    projects: state.projectsReducer.projects,
  };
}
