import React, { useEffect, useMemo, useState} from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableFooter,
  TableHead,
  TableRow,
  CircularProgress,
  Grid,
  Box,
  Button,
  Typography,
  TextField,
  MenuItem,
  InputAdornment,
  Card,
  Dialog,
  DialogActions, DialogContent, DialogTitle, CardContent,Paper, Stack, Chip, Divider
} from "@mui/material";
import { FaMoneyBillWave, FaPlusCircle ,FaFileAlt, FaClipboardList , FaChartPie , FaCog , FaMoneyCheckAlt, FaChartBar } from 'react-icons/fa'; // Example icons

import { useNotifier } from "../../../Core/Notifier";
import { useStyles } from "../../../theme/appStyles";
import { useNavigate, useParams, Link } from "react-router-dom";
import { CiSearch } from "react-icons/ci";
import DeleteOutlineSharpIcon from "@mui/icons-material/DeleteOutlineSharp";
import EditSharpIcon from "@mui/icons-material/EditSharp";
import PaymentIcon from '@mui/icons-material/Payment';
import Pagination from "../../../Components/Pagination";
import axios from "axios";
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import AttachFileIcon from '@mui/icons-material/AttachFile';
import DescriptionIcon from '@mui/icons-material/Description';
import { Pie } from 'react-chartjs-2';
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import CancelIcon from '@mui/icons-material/Cancel';
import CommentIcon from '@mui/icons-material/Comment';
import { Tooltip as MuiTooltip } from '@mui/material';
import InfoIcon from '@mui/icons-material/Info';  
import VisibilitySharpIcon from "@mui/icons-material/VisibilitySharp";
import LoopIcon from '@mui/icons-material/Loop';           // Circular arrow, used for Before
import LoopOutlinedIcon from '@mui/icons-material/LoopOutlined'; // Outlined circular arrow, used for After
import IconButton from '@mui/material/IconButton';
import CloseIcon from '@mui/icons-material/Close';
import SaveAltIcon from "@mui/icons-material/SaveAlt";
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import Collapse from '@mui/material/Collapse';
import { FaTrash } from "react-icons/fa";
import { FaEdit, FaUndo } from "react-icons/fa";
import LinkIcon from "@mui/icons-material/Link";

ChartJS.register(ArcElement, Tooltip, Legend);

interface Expense {
  id: number;
  date: string;
  description: string;
  remarks: string;
  amount: number;
  hst: number;
  category: number;
  status: number;
  type: string;
  total: number;
  installment: number;
  installment_details: Installment[];
  file?: string;
  created_at: string;
  before_images?: string;
  after_images?: string;
}

  interface Installment  {
  date: string;
  amount: string;
  paymentMode: string;
  description: string;
};

interface Category {
  id: number;
  category_name: string;
}

interface Driver {
  id: number;
  driverFirstName: string;
  driverLastName: string;
  driverUserRole: string;
  projectId?: number[];
}

interface Deposit {
  id: number;
  amount: string;
  user_id: number;
  created_at: string;
  date: string;
  is_approved: boolean; 
  remarks: string;
}

interface UserInfo {
  id: number;
  username: string;
  token: string;
  user_id: number;
}



const Index = () => {
  const classes = useStyles();
  const navigate = useNavigate();
  const { projectId } = useParams();
  const [expenses, setExpenses] = useState<Expense[]>([]); 
  const [categories, setCategories] = useState<Category[]>([]); 
  const [team, setTeam] = useState<Driver[]>([]); 
  const [deposit, setDeposit] = useState<Deposit[]>([]); 
  const { showErrorMessage, showMessage } = useNotifier();
  const API_URL = process.env.REACT_APP_API_URL;
  const [searchQuery, setSearchQuery] = useState(""); 
  const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(5);
const LARAVEL_API_URL = process.env.REACT_APP_LARAVEL_API;
const [openModal, setOpenModal] = useState(false);
const [openModalView, setOpenModalView] = useState(false);
const [fileUrl, setFileUrl] = useState<string | null>(null);
const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
const [tooltipOpen, setTooltipOpen] = React.useState<Record<number, boolean>>({});
const [showImages, setShowImages] = useState(false);
const [beforeImages, setBeforeImages] = useState<string[]>([]);
const [afterImages, setAfterImages] = useState<string[]>([]);
const isPdf = fileUrl?.endsWith('.pdf');
const [modalOpen, setModalOpen] = useState(false);
const [editIndex, setEditIndex] = useState(null);
  const [installments, setInstallments] = useState<Installment[]>([]);
const [installmentData, setInstallmentData] = useState({
     date: new Date().toLocaleDateString("en-CA", { timeZone: "America/Toronto" }),
    amount: "",
    paymentMode:"",
    description: "",
  });

const [selectedExpense, setSelectedExpense] = useState<Expense | null>(null);
const [expandedExpenseId, setExpandedExpenseId] = useState<number | null>(null);
const storedCategoryName  = sessionStorage.getItem("categoryName");





const handleViewImages = (beforeImagesData: string[], afterImagesData: string[]) => {
  console.log("Before Images Data:", beforeImagesData);  // This should now show the images
  setBeforeImages(beforeImagesData || []);
  setAfterImages(afterImagesData || []);
  setOpenModalView(true);
};



// Handle touch on mobile
const handleMobileTooltipToggle = (id: number) => {
  if (window.innerWidth <= 768) {
    setTooltipOpen((prev) => ({
      ...prev,
      [id]: !prev[id], // Toggle the open state for the specific tooltip
    })); // Toggle open/close on tap for mobile
  }
};

const categoryMap = useMemo(
  () =>
    categories.reduce((map, category) => {
      map[category.id] = category.category_name;
      return map;
    }, {} as Record<number, string>),
  [categories]
);


 

  
  const fetchExpenses = async () => {
      try {
       
        const response = await axios.get(`${API_URL}/view-expenses/${projectId}`);
        setExpenses(response.data); // Set the fetched data to state
   // console.log(response.data)
      if (selectedExpense) {
      const updatedExpense = response.data.find((exp: any) => exp.id === selectedExpense.id);
      if (updatedExpense) {
        setSelectedExpense(updatedExpense);
        // Also update installments based on the updated expense
        let updatedInstallments = [];
        try {
          updatedInstallments = updatedExpense.installment_details
            ? JSON.parse(updatedExpense.installment_details)
            : [];
        } catch {
          updatedInstallments = [];
        }
        setInstallments(updatedInstallments);
      }
    }
  } catch (error) {
    console.error("Failed to load expenses", error);
  }
};
    const fetchCategories = async () => {
      try {
        const response = await axios.get(`${API_URL}/view-expense-category/${projectId}`);
        setCategories(response.data);
        //console.log(response.data);
      } catch (error) {
        console.error("Failed to load categories", error);
      }
    };
    const fetchTeam = async () => {
      try {
        const response = await axios.get(`${API_URL}/view-team`);
        // setTeam(response.data.data);
        const team: Driver[] = response.data.data;
   const managers = team.filter(driver => {
  const ids = typeof driver.projectId === 'string' ? JSON.parse(driver.projectId) : driver.projectId;
  return (
    driver.driverUserRole === 'manager' &&
    Array.isArray(ids) &&
    ids.includes(parseInt(projectId || '0'))
  );
});

   
        setTeam(managers); 
       // console.log(response.data.data);
      } catch (error) {
        console.error("Failed to load team members", error);
      }
    };

    const fetchDeposit = async () => {
      try {
        const response = await axios.get(`${API_URL}/view-deposit/${projectId}`);
        setDeposit(response.data); // Set the fetched data to state
        // console.log(response.data);
      } catch (error) {
        console.error("Failed to load expenses", error);
      }
    };

    const fetchUserInfo = async () => {
      try {
          const response = await axios.post(
              `${API_URL}/user/userInfo`,
              {}, // No body required
              {
                  headers: {
                      'Content-Type': 'application/json',
                      Authorization: `Bearer ${localStorage.getItem('token') || ''}`, // Include token from localStorage
                  },
              }
          );
          setUserInfo(response.data.data); // Update your state with the response
        // console.log(response.data.data)
      } catch (error) {
          console.error('Error fetching user info', error);
      }
  };
  useEffect(() => {
  

    fetchExpenses();
    fetchCategories();
    fetchTeam();
    fetchDeposit();
    fetchUserInfo();
  }, [API_URL]);

 
  const handleChangePage = (event: unknown, newPage: number) => {
    setPage(newPage);
  };
  
  const generateYearlyData = (expenses: Expense[]) => {
    const yearlyData = Array(12).fill(0); // Array to store expenses for each month (12 months)
  
    expenses.forEach((expense) => {
      const expenseDate = new Date(expense.date);
      const month = expenseDate.getMonth(); // Get month (0-11)
      
      // Ensure expense.total is a number
      let totalExpense = expense.total;
      
      if (typeof totalExpense === 'string') {
        totalExpense = parseFloat(totalExpense); // Convert string to number
      }
    
      // Check if totalExpense is a valid number
      if (!isNaN(totalExpense)) {
        yearlyData[month] += totalExpense; // Aggregate expense by month
      } else {
        console.error("Invalid total expense:", expense.total); // Log invalid total
      }
    });
  
    // Ensure that no NaN values are in yearlyData
    const validYearlyData = yearlyData.map((value) => (isNaN(value) ? 0 :  parseFloat(value.toFixed(2)))); // Replace NaN with 0
  
//    console.log(validYearlyData); // Check the data
    return validYearlyData;
  };
  
  
  const generateCategoryData = (expenses: Expense[], categories: Category[]) => {
    const categoryTotals: Record<string, number> = {};

    // Map category ID to category name
    const categoryMap = categories.reduce((acc, category) => {
      acc[category.id] = category.category_name;
      return acc;
    }, {} as Record<number, string>);

    expenses.forEach((expense) => {
      let totalExpense = expense.total;

      // Ensure totalExpense is a number
      if (typeof totalExpense === 'string') {
        totalExpense = parseFloat(totalExpense); // Convert string to number
      }

      // Get the category name using the category ID
      const categoryName = categoryMap[expense.category];

      if (categoryName) {
        //console.log(`Processing Category: ${categoryName}, Total Expense: ${totalExpense}`);

        // Check if totalExpense is a valid number
        if (!isNaN(totalExpense)) {
          if (!categoryTotals[categoryName]) {
            categoryTotals[categoryName] = 0;
          }
          categoryTotals[categoryName] += totalExpense; // Aggregate by category name
        } else {
          console.error("Invalid category total:", expense.total);
        }
      } else {
        console.error("Invalid category ID:", expense.category);
      }
    });

    // Ensure that no NaN values are in categoryTotals
    const validCategoryTotals = Object.fromEntries(
      Object.entries(categoryTotals).map(([key, value]) => [key, isNaN(value) ? 0 :  parseFloat(value.toFixed(2))])
    );

    //console.log('Final Category Totals:', validCategoryTotals);
    return validCategoryTotals;
  };
  
  
  
  
  const categoryData = generateCategoryData(expenses, categories);
  const yearlyData = generateYearlyData(expenses);
  

 
  

 const calculateCategoryHST = (expenses: Expense[], categories: Category[]) => {
  const categoryHST: Record<string, number> = {};

  const categoryMap = categories.reduce((acc, category) => {
    acc[category.id] = category.category_name;
    return acc;
  }, {} as Record<number, string>);

  expenses.forEach((expense) => {
    const hst = Number(expense.hst) || 0; // Use the existing value or default to 0
    const categoryName = categoryMap[expense.category];

    if (categoryName) {
      categoryHST[categoryName] = (categoryHST[categoryName] || 0) + hst;
    }
  });

  return categoryHST;
};

// Example Usage
const categoryHST = calculateCategoryHST(expenses, categories);
const totalBankBalance = deposit.filter((d) => d.is_approved).reduce((acc, curr) => acc + Number(curr.amount), 0);
const overallExpense = expenses.reduce((acc, expense) => acc + Number(expense.total), 0);
const paidExpense =  expenses
.filter(expense => String(expense.status) === 'Paid')  // Convert status to string
.reduce((total, expense) => total + expense.amount, 0); 


const allTypes = ["Other", "Labour", "Material"]; // All possible types
const typeColors: Record<string, string> = {
  Other: "#FF9800",
  Labour: "#4CAF50",
  Material: "#2196F3",
};

const calculatePieData = (categoryName: string) => {
  // Filter expenses for this category
  const filteredExpenses = expenses.filter(
    (expense) => categoryMap[expense.category] === categoryName
  );

  // Total per type, 0 if type not present
  const typeTotals = allTypes.map((type) =>
    filteredExpenses
      .filter((e) => (e.type || "Other") === type)
      .reduce((sum, e) => sum + Number(e.total ?? 0), 0)
  );

  return {
    labels: allTypes,
    datasets: [
      {
        data: typeTotals,
        backgroundColor: allTypes.map((t) => typeColors[t]),
        hoverOffset: 4,
      },
    ],
  };
};



if (!storedCategoryName) {
  return <Typography>No category selected</Typography>;
}

const pieData = calculatePieData(storedCategoryName);
const filteredExpenses = expenses.filter(
  (expense) => categoryMap[expense.category] === storedCategoryName
);
const totalCategoryExpense = categoryData[storedCategoryName] ?? 0;
const totalCategoryHST = categoryHST[storedCategoryName] ?? 0;




  return (

    
    <>


 <Grid container spacing={4} justifyContent="center">
      {/* First Card: Pie Chart + Summary */}
      <Grid item xs={12} md={10}>
        <Card elevation={3} sx={{ p: 3 }}>
          <Typography variant="h6" align="center" sx={{ fontWeight: "bold", mb: 3 }}>
            {storedCategoryName}
          </Typography>

          <Box sx={{ display: "flex", flexDirection: { xs: "column", md: "row" }, justifyContent: "space-between", alignItems: "center", gap: 3 }}>
            {/* Pie Chart */}
            <Box sx={{ width: { xs: "100%", md: 250 }, height: 250, mx: "auto" }}>
              <Pie data={pieData} options={{
                plugins: {
                  tooltip: {
                    callbacks: {
                      label: (tooltipItem) => {
                        const { dataIndex, dataset } = tooltipItem;
                        const value = dataset.data[dataIndex] as number;
                        const total = dataset.data.reduce((a, b) => a + b, 0);
                        const percentage = ((value / total) * 100).toFixed(2);
                        return `$${value.toFixed(2)} (${percentage}%)`;
                      },
                    },
                  },
                  legend: { display: true, position: "bottom", labels: { color: "#000", boxWidth: 12 } },
                },
                maintainAspectRatio: false,
              }} />
            </Box>

            {/* Summary Metrics */}
            <Box sx={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 150, textAlign: { xs: "center", md: "left" } }}>
              <Typography variant="body1">Total Expense: <strong>${totalCategoryExpense.toFixed(2)}</strong></Typography>
              <Typography variant="body1">Total HST: <strong>${totalCategoryHST.toFixed(2)}</strong></Typography>
              <Typography variant="body1">Transactions: <strong>{filteredExpenses.length}</strong></Typography>
            </Box>
          </Box>
        </Card>
      </Grid>

      {/* Second Card: Expense Table */}
      <Grid item xs={12} md={10}>
        <Card elevation={3} sx={{ p: 3 }}>
          <Typography variant="h6" align="center" sx={{ fontWeight: "bold", mb: 3 }}>
            Expense Details
          </Typography>

          <TableContainer component={Paper}>
            <Table>
              <TableHead sx={{ backgroundColor: "#f5f5f5" }}>
                <TableRow>
                  <TableCell>Date</TableCell>
                  <TableCell>Description</TableCell>
                  <TableCell>Type</TableCell>
                  <TableCell align="right">Amount</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {filteredExpenses
                  .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                  .map((expense, index) => {
                    const type = expense.type || "Other";
                    let bgColor = "#607d8b";
                    const typeIndex = pieData.labels.indexOf(type);
                    if (typeIndex !== -1) {
                      bgColor = pieData.datasets[0].backgroundColor[typeIndex % pieData.datasets[0].backgroundColor.length];
                    }

                    return (
                      <TableRow key={index} sx={{ backgroundColor: index % 2 === 0 ? "#fafafa" : "#fff" }}>
                        <TableCell>{expense.date}</TableCell>
                        <TableCell>
                          <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                            <Box
                              sx={{
                                width: 18,
                                height: 18,
                                borderRadius: "50%",
                                backgroundColor: bgColor,
                                color: "#fff",
                                display: "flex",
                                alignItems: "center",
                                justifyContent: "center",
                                fontSize: "0.75rem",
                                fontWeight: 700,
                              }}
                            >
                              {type[0].toUpperCase()}
                            </Box>
                            {expense.description}
                          </Box>
                        </TableCell>
                        <TableCell>{type}</TableCell>
                        <TableCell align="right">${Number(expense.total ?? 0).toFixed(2)}</TableCell>
                      </TableRow>
                    );
                  })}
              </TableBody>
            </Table>
          </TableContainer>

          {/* Pagination */}
          <Box sx={{ display: "flex", justifyContent: "center", mt: 3 }}>
            <Pagination
              count={Math.ceil(filteredExpenses.length / rowsPerPage)}
                    page={page}
                    rowsPerPage={rowsPerPage}
                    onPageChange={handleChangePage} />

          </Box>
        </Card>
      </Grid>
    </Grid>



      </>




       

  );
};

export default Index;
