// pages/evaluation.tsx
"use client";

import { useState, useEffect } from "react";
import { useParams, useRouter } from "next/navigation";
import { axiosInstance } from "@/services/axios";

// Use @hello-pangea/dnd for drag-and-drop.
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";

// Import shadcn/ui components (adjust imports as needed)
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

// ----------------------------------------------------------------
// Import Chart.js and react-chartjs-2 for the final analysis chart.
// ----------------------------------------------------------------
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend,
} from "chart.js";
import { Bar } from "react-chartjs-2";

ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);

// ----------------------------------------------------------------
// Steps Definition – each step represents a cluster evaluation.
// ----------------------------------------------------------------
const steps = [
  {
    type: "cluster1",
    questionEndpoint: "/question/Intrinsic_value",
    submissionEndpoint: "/intrinsic",
    title: "System Quality",
  },
  {
    type: "cluster2",
    questionEndpoint: "/question/Business_value",
    submissionEndpoint: "/business",
    title: "Business Evaluation",
  },
  {
    type: "cluster3",
    questionEndpoint: "/question/Cost_value",
    submissionEndpoint: "/cost",
    title: "Cost Evaluation",
  },
  {
    type: "cluster4",
    questionEndpoint: "/question/ASGC_value",
    submissionEndpoint: "/ASGC",
    title: "ACGS Evaluation",
  },
];

// ----------------------------------------------------------------
// Score Labels and Colors
// ----------------------------------------------------------------
const scoreLabels: { [key: string]: string } = {
  "1": "Low",
  "2": "Below Average",
  "3": "Average",
  "4": "Above Average",
  "5": "High",
};

const columnBgColors: { [key: string]: string } = {
  "1": "bg-red-50",
  "2": "bg-orange-50",
  "3": "bg-yellow-50",
  "4": "bg-blue-50",
  "5": "bg-green-50",
};

const columnHeaderColors: { [key: string]: string } = {
  "1": "bg-red-600",
  "2": "bg-orange-600",
  "3": "bg-yellow-600",
  "4": "bg-blue-600",
  "5": "bg-green-600",
};

// ----------------------------------------------------------------
// Types for Question, UserInfo, and ClusterResponse
// ----------------------------------------------------------------
interface Question {
  _id: string;
  question_no: string;
  question_detail: string;
  type: string;
  answer_type: string;
  created_at: string;
  updated_at: string | null;
  answers: { [key: string]: number }; // e.g. { "answer1": 5, ... }
  is_active: boolean;
  created_by: string;
}

interface UserInfo {
  _id: string;
  userId: string;
  type: string;
  name: string;
  org_name: string;
  created_at: string;
  updated_at: string | null;
  cluster: { [key: string]: boolean };
  deltas: { [key: string]: number };
  is_active: boolean;
}

interface ClusterResponse {
  cluster: string;
  title: string;
  answers: { [key: string]: number };
  questionDetail: string;
  // The original answer keys (for restoring a step).
  answersList: { [key: string]: number };
}

// ----------------------------------------------------------------
// Main EvaluationPage Component
// ----------------------------------------------------------------
const EvaluationPage = () => {
  const { id } = useParams(); // user id from URL params
  const router = useRouter();

  const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
  const [question, setQuestion] = useState<Question | null>(null);
  // “answers” maps each answer key to a droppable ID:
  // either "pool" or one of "1" to "5"
  const [answers, setAnswers] = useState<{ [key: string]: string }>({});
  const [loading, setLoading] = useState<boolean>(false);
  const [submitting, setSubmitting] = useState<boolean>(false);
  // currentStep ranges from 0 to steps.length (if completed, show analysis)
  const [currentStep, setCurrentStep] = useState<number>(0);
  // To store responses for analytics and for restoring previous steps.
  const [clusterResponses, setClusterResponses] = useState<ClusterResponse[]>([]);
  // Flag to ensure auto-assignment runs only once per question.
  const [autoAssigned, setAutoAssigned] = useState<boolean>(false);
  // State to track which cards have just been auto-assigned to trigger the pop effect.
  const [autoPopCards, setAutoPopCards] = useState<string[]>([]);

  // ----------------------------------------------------------------
  // 1. Fetch User Info from /userInfo?userId={id}
  // ----------------------------------------------------------------
  useEffect(() => {
    if (!id) return;
    const fetchUserInfo = async () => {
      try {
        setLoading(true);
        const { data: responseData } = await axiosInstance.post(`/userInfo?userId=${id}`);
        if (responseData.data) {
          setUserInfo(responseData.data);
        }
      } catch (error) {
        console.error("Error fetching user info:", error);
      } finally {
        setLoading(false);
      }
    };
    fetchUserInfo();
  }, [id]);

  // ----------------------------------------------------------------
  // 2. For the current step, fetch the question.
  // Initialize all answer cards to start in the "pool" and reset autoAssigned.
  // ----------------------------------------------------------------
  useEffect(() => {
    if (!id || currentStep >= steps.length) return;
    const fetchQuestion = async () => {
      try {
        setLoading(true);
        const endpoint = steps[currentStep].questionEndpoint;
        const { data: questionData } = await axiosInstance.post(endpoint, {});
        if (questionData && Array.isArray(questionData) && questionData.length > 0) {
          const fetchedQuestion = questionData[0];
          setQuestion(fetchedQuestion);
          // All answer keys start in the pool.
          const initialAnswers: { [key: string]: string } = {};
          Object.keys(fetchedQuestion.answers).forEach((key) => {
            initialAnswers[key] = "pool";
          });
          setAnswers(initialAnswers);
          setAutoAssigned(false);
        }
      } catch (error) {
        console.error("Error fetching question:", error);
      } finally {
        setLoading(false);
      }
    };
    fetchQuestion();
  }, [currentStep, id]);

  // ----------------------------------------------------------------
  // 3. After a question loads, auto-assign the cards from the pool to
  // random columns with a staggered delay to animate the transition.
  // A pop effect is applied only during this auto-assignment.
  // ----------------------------------------------------------------
  useEffect(() => {
    if (
      question &&
      !autoAssigned &&
      Object.values(answers).every((loc) => loc === "pool")
    ) {
      const keys = Object.keys(answers);
      keys.forEach((key, index) => {
        setTimeout(() => {
          // Update the answer assignment.
          setAnswers((prev) => ({
            ...prev,
            [key]: (Math.floor(Math.random() * 5) + 1).toString(),
          }));
          // Trigger the pop effect by adding the card to autoPopCards.
          setAutoPopCards((prev) => [...prev, key]);
          // Remove the pop effect after 300ms (duration of pop animation).
          setTimeout(() => {
            setAutoPopCards((prev) => prev.filter((id) => id !== key));
          }, 300);
          // When the last card is processed, mark auto-assignment complete.
          if (index === keys.length - 1) {
            setAutoAssigned(true);
          }
        }, index * 300); // 300ms delay between each card
      });
    }
  }, [question, autoAssigned, answers]);

  // ----------------------------------------------------------------
  // 4. Handle Drag End – update the answers mapping.
  // Manual drag-drop will NOT trigger a pop animation.
  // Also, if the current cluster is locked (per userInfo.cluster), do nothing.
  // ----------------------------------------------------------------
  const onDragEnd = (result: any) => {
    if (!result.destination) return;
    // If the current cluster is locked, disallow changes.
    if (userInfo && userInfo.cluster[steps[currentStep].type]) {
      return;
    }
    const { destination, source, draggableId } = result;
    if (
      destination.droppableId === source.droppableId &&
      destination.index === source.index
    )
      return;
    setAnswers((prev) => ({
      ...prev,
      [draggableId]: destination.droppableId,
    }));
  };

  // ----------------------------------------------------------------
  // 5. Allow clicking on a step in the sidebar to return to that step.
  // If going back, restore that step’s answers.
  // ----------------------------------------------------------------
  const handleStepClick = (index: number) => {
    if (index > currentStep) return; // disallow jumping ahead
    if (index < currentStep) {
      const prevResponse = clusterResponses[index];
      if (prevResponse) {
        setQuestion({
          _id: "",
          question_no: "",
          question_detail: prevResponse.questionDetail,
          type: "",
          answer_type: "",
          created_at: "",
          updated_at: null,
          answers: prevResponse.answersList,
          is_active: true,
          created_by: "",
        });
        const restoredAnswers: { [key: string]: string } = {};
        Object.entries(prevResponse.answers).forEach(([key, score]) => {
          restoredAnswers[key] = score.toString();
        });
        setAnswers(restoredAnswers);
      }
    }
    setCurrentStep(index);
  };

  // ----------------------------------------------------------------
  // 6. When the user clicks "Next", validate that no card remains in the pool,
  // convert droppable IDs to numbers, post the payload, and move on.
  // ----------------------------------------------------------------
  const handleNext = async () => {
    if (!id || !question) return;
    const unassigned = Object.values(answers).filter((val) => val === "pool");
    if (unassigned.length > 0) {
      alert("Please assign all cards to a score column before proceeding.");
      return;
    }
    try {
      setSubmitting(true);
      const payloadAnswers: { [key: string]: number } = {};
      Object.entries(answers).forEach(([key, value]) => {
        payloadAnswers[key] = parseInt(value, 10);
      });
      const payload = {
        type: steps[currentStep].type,
        userId: id,
        answer: payloadAnswers,
        delta: 0,
        value: {},
      };
      const { data: submissionResponse } = await axiosInstance.post(
        steps[currentStep].submissionEndpoint,
        payload
      );
      console.log("Submission response:", submissionResponse);
      setClusterResponses((prev) => [
        ...prev,
        {
          cluster: steps[currentStep].type,
          title: steps[currentStep].title,
          answers: payloadAnswers,
          questionDetail: question.question_detail,
          answersList: question.answers,
        },
      ]);
      setCurrentStep(currentStep + 1);
      setQuestion(null);
      setAnswers({});
    } catch (error) {
      console.error("Error submitting data:", error);
    } finally {
      setSubmitting(false);
    }
  };

  const SideBar = ()=>{
    return(
      <div className="min-w-48 border-r border-gray-200 p-2 bg-white flex flex-col static top-0">
            {/* Step Navigation */}
            <div className="mb-4">
              <h3 className="text-sm font-bold text-gray-800 mb-2">Steps</h3>
              <ul className="space-y-2">
                {steps.map((step, index) => (
                  <li
                    key={index}
                    onClick={() => handleStepClick(index)}
                    className={`px-3 py-2 rounded cursor-pointer text-xs font-medium ${
                      index === currentStep
                        ? "bg-blue-600 text-white"
                        : index < currentStep
                        ? "bg-green-500 text-white"
                        : "bg-gray-100 text-gray-700"
                    }`}
                  >
                    {step.title}
                  </li>
                ))}
                {currentStep >= steps.length && (
                  <li className="px-3 py-2 rounded bg-purple-600 text-white text-xs font-medium">
                    Final Analysis
                  </li>
                )}
              </ul>
            </div>
            {/* Card Pool */}
            {poolCards.length > 0 && (
              <div className="flex-1">
                <h3 className="text-sm font-bold text-gray-800 mb-2">
                  Attributes
                </h3>
                <Droppable droppableId="pool">
                  {(provided) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.droppableProps}
                      className="border border-gray-300 rounded p-2 h-[300px] overflow-auto"
                    >
                      {poolCards.map((item, index) => (
                        <Draggable key={item.id} draggableId={item.id} index={index}>
                          {(provided) => (
                            <div
                              className="mb-2 transition-all duration-500"
                              ref={provided.innerRef}
                              {...provided.draggableProps}
                              {...provided.dragHandleProps}
                            >
                              <Card className="p-2 border border-gray-300">
                                <CardHeader>
                                  <CardTitle className="text-xs text-gray-800">
                                    {item.content}
                                  </CardTitle>
                                </CardHeader>
                              </Card>
                            </div>
                          )}
                        </Draggable>
                      ))}
                      {provided.placeholder}
                    </div>
                  )}
                </Droppable>
              </div>
            )}
          </div>
    )
  }

  // ----------------------------------------------------------------
  // 7. Final Analysis Screen – an elegant summary using a bar chart for delta values
  // and tables for each of the 4 clusters showing their answer scores.
  // ----------------------------------------------------------------
  const FinalAnalyticsScreen = () => {
    const [finalUserInfo, setFinalUserInfo] = useState<UserInfo | null>(null);
    const [chartData, setChartData] = useState<any>(null);
    const [loadingFinal, setLoadingFinal] = useState<boolean>(false);

    useEffect(() => {
      if (!id) return;
      const fetchFinalUserInfo = async () => {
        try {
          setLoadingFinal(true);
          const { data: responseData } = await axiosInstance.post(
            `/userInfo?userId=${id}`
          );
          if (responseData.data) {
            setFinalUserInfo(responseData.data);
            const deltaKeys = Object.keys(responseData.data.deltas);
            const deltaValues = deltaKeys.map(
              (key) => responseData.data.deltas[key]
            );
            setChartData({
              labels: deltaKeys,
              datasets: [
                {
                  label: "Delta Values",
                  data: deltaValues,
                  backgroundColor: "rgba(54, 162, 235, 0.6)",
                  borderColor: "rgba(54, 162, 235, 1)",
                  borderWidth: 1,
                },
              ],
            });
          }
        } catch (error) {
          console.error("Error fetching final user info:", error);
        } finally {
          setLoadingFinal(false);
        }
      };
      fetchFinalUserInfo();
    }, [id]);

    if (loadingFinal) {
      return (
        <div className="p-4">
          <p className="text-xs text-blue-600">Loading final analysis...</p>
        </div>
      );
    }

    if (!finalUserInfo) {
      return (
        <div className="p-4">
          <p className="text-xs text-red-600">
            Failed to load final analysis data.
          </p>
        </div>
      );
    }

    return (
      <div className="overflow-auto flex w-full bg-gray-50">
        <SideBar></SideBar>
        <div className="flex  flex-col gap-1 w-full p-5">
        
        {/* Delta Values Bar Chart */}
        <div className="h-[85vh] flex flex-col overflow-auto">
 
        <div className="mb-4 ">
          <h3 className="text-xs font-medium text-gray-700 mb-2">
            Delta Values
          </h3>
          <div className="w-full h-48">
            {chartData ? (
              <Bar
                data={chartData}
                options={{
                  responsive: true,
                  maintainAspectRatio: false,
                  plugins: {
                    legend: { display: false },
                    title: { display: false },
                  },
                  scales: {
                    y: {
                      beginAtZero: true,
                      ticks: { font: { size: 10 } },
                    },
                    x: {
                      ticks: { font: { size: 10 } },
                    },
                  },
                }}
              />
            ) : (
              <p className="text-xs text-gray-500">
                No delta data available.
              </p>
            )}
          </div>
        </div>
        {/* Tables for each of the evaluated clusters */}
        <div>
          {clusterResponses.map((cluster, idx) => (
            <div key={idx} className="bg-white border rounded p-4 shadow-sm mb-4">
              <h3 className="text-xs font-semibold text-gray-800 mb-2">
                {cluster.title}
              </h3>
              <table className="w-full text-xs text-gray-600">
                <thead>
                  <tr>
                    <th className="border-b pb-1 text-left">Attribute</th>
                    <th className="border-b pb-1 text-right">Score</th>
                  </tr>
                </thead>
                <tbody>
                  {Object.entries(cluster.answers).map(([key, value]) => (
                    <tr key={key}>
                      <td className="py-1">{key}</td>
                      <td className="py-1 text-right">{value}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ))}
        </div>
        </div>
        <div className="flex justify-end mt-4">
          <Button onClick={() => router.push("/")} className="text-xs px-3 py-1">
            Finish
          </Button>
        </div>
        </div>
      </div>
    );
  };

  // ----------------------------------------------------------------
  // 8. Loading / Error UI
  // ----------------------------------------------------------------
  if (loading && !question) {
    return (
      <div className="flex items-center justify-center h-screen bg-white">
        <p className="text-sm text-blue-600">Loading...</p>
      </div>
    );
  }
  if (!userInfo) {
    return (
      <div className="flex items-center justify-center h-screen bg-white">
        <p className="text-sm text-red-600">
          User not found or invalid ID.
        </p>
      </div>
    );
  }

  // ----------------------------------------------------------------
  // 9. Prepare the lists of answer cards grouped by droppable.
  // ----------------------------------------------------------------
  const poolCards: { id: string; content: string }[] = [];
  const columnCards: { [key: string]: { id: string; content: string }[] } = {
    "1": [],
    "2": [],
    "3": [],
    "4": [],
    "5": [],
  };

  Object.entries(answers).forEach(([key, location]) => {
    if (location === "pool") {
      poolCards.push({ id: key, content: key });
    } else {
      if (columnCards[location]) {
        columnCards[location].push({ id: key, content: key });
      }
    }
  });

  // If all steps have been completed, show the final analysis screen.
  if (currentStep >= steps.length) {
    return <FinalAnalyticsScreen />;
  }

  // ----------------------------------------------------------------
  // 10. Render the layout: a sidebar with step navigation and card pool,
  // and the main area with the Kanban board columns.
  // ----------------------------------------------------------------
  return (
    <>
      <DragDropContext onDragEnd={onDragEnd}>
        <div className="flex flex-1 h-auto w-full">
          {/* Sidebar */}
          <SideBar/>
          {/* Main Content */}
          <div className="h-[90vh] w-full flex flex-col bg-white">
            {/* Header */}
            <div className="p-4 border-b border-gray-200">
              <h1 className="text-xl font-bold text-gray-800">
                {steps[currentStep]?.title}
              </h1>
              <p className="text-xs text-gray-600">
                Step {currentStep + 1} of {steps.length}
              </p>
              <p className="mt-2 text-sm text-gray-700">
                {question?.question_detail}
              </p>
              {userInfo && userInfo.cluster[steps[currentStep].type] && (
                <p className="text-xs text-red-500">
                  This cluster is locked for editing.
                </p>
              )}
            </div>
            {/* Kanban Board Columns */}
            <div className="flex flex-1 overflow-x-auto w-full pr-28 p-4 gap-4">
              {(["1", "2", "3", "4", "5"] as const).map((score) => (
                <Droppable key={score} droppableId={score}>
                  {(provided) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.droppableProps}
                      className={`flex-shrink-0 w-[250px] h-full overflow-auto no-scrollbar ${columnBgColors[score]} border border-gray-300 rounded`}
                    >
                      {/* Column Header */}
                      <div className={`${columnHeaderColors[score]} text-white py-2 px-3 rounded-t sticky top-0`}>
                        <h3 className="text-center text-xs font-bold">
                         Score: {score}
                        </h3>
                      </div>
                      {/* Column Body */}
                      <div className="p-2 min-h-full space-y-2">
                        {columnCards[score].map((item, index) => (
                          <Draggable key={item.id} draggableId={item.id} index={index}>
                            {(provided) => (
                              <div
                                ref={provided.innerRef}
                                {...provided.draggableProps}
                                {...provided.dragHandleProps}
                                className={`transition-all duration-500 ${
                                  autoPopCards.includes(item.id) ? "pop" : ""
                                }`}
                              >
                                <Card className="p-2 border border-gray-300">
                                  <CardHeader>
                                    <CardTitle className="text-xs text-gray-800">
                                      {item.content}
                                    </CardTitle>
                                  </CardHeader>
                                  <CardContent>
                                    <p className="text-xs text-gray-600">
                                      {scoreLabels[score]}
                                    </p>
                                  </CardContent>
                                </Card>
                              </div>
                            )}
                          </Draggable>
                        ))}
                        {provided.placeholder}
                      </div>
                    </div>
                  )}
                </Droppable>
              ))}
            </div>
            {/* Footer */}
            <div className="p-4 border-t border-gray-200 pr-28 flex justify-end sticky bottom-0">
              {currentStep < steps.length && (
                <Button
                  onClick={handleNext}
                  disabled={submitting}
                  className="px-4 py-2"
                >
                  {submitting
                    ? "Submitting..."
                    : currentStep === steps.length - 1
                    ? "Submit & View Analysis"
                    : "Next"}
                </Button>
              )}
            </div>
          </div>
        </div>
      </DragDropContext>
      {/* CSS for the pop effect (applied only during auto-assignment) */}
      <style jsx>{`
        @keyframes pop {
          0% {
            transform: scale(0.8);
          }
          50% {
            transform: scale(1.1);
          }
          100% {
            transform: scale(1);
          }
        }
        .pop {
          animation: pop 0.3s ease-out;
        }
      `}</style>
    </>
  );
};

export default EvaluationPage;
