import React, { useEffect, useMemo, useState,useRef} 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, Select
} 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 dayjs from "dayjs";
import ReactToPrint from "react-to-print";
import LocalPrintshopSharpIcon from "@mui/icons-material/LocalPrintshopSharp";
import DownloadIcon from '@mui/icons-material/Download';
import * as XLSX from "xlsx";
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
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;
  sub_category: number;
  status: number;
  total: number;
  type?: string;
  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;
  mainCatId: number;
}

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;
}

interface SubcategoryData {
  total: number;
  expenses: Expense[];
}

interface Group {
  id: number;
  project_id: number;
  group_name: string;
  category_ids: number[];
}


const Index = () => {
  const classes = useStyles();
  const navigate = useNavigate();
  const { projectId, groupId } = useParams<{ projectId: string; groupId: string }>();
  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 [pageMaterial, setPageMaterial] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(50);
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 [dateFilter, setDateFilter] = useState<string>("");
const [startDate, setStartDate] = useState<string>("");
const [endDate, setEndDate] = useState<string>("");
const [selectedType, setSelectedType] = useState('');
const componentRef = useRef<HTMLDivElement>(null);
const [groups, setGroups] = useState<Group[]>([]); 

const [zoom, setZoom] = useState(1);

const handleZoomIn = () => setZoom((prev) => Math.min(prev + 0.2, 5)); // max 5x
const handleZoomOut = () => setZoom((prev) => Math.max(prev - 0.2, 0.2)); // min 0.2x
const handleResetZoom = () => setZoom(1);



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

// Get the current group based on groupId
const group = groups?.find((g) => g.id === Number(groupId));
console.log(group)

const filteredExpenses = expenses.filter((expense) => {
  // --- Search Query Filter ---
  const matchesSearch =
    expense.description.toLowerCase().includes(searchQuery.toLowerCase()) ||
    (categoryMap[expense.category] || "")
      .toLowerCase()
      .includes(searchQuery.toLowerCase());

  // --- Category Filter ---
 // const matchesCategory =  String(expense.category) === String(categoryId);

 const matchesCategory = group?.category_ids.includes(Number(expense.category))


     const excludeInstallment = expense.installment !== 1;

       // --- Type Filter ---
  const matchesType = selectedType
    ? expense.type === selectedType
    : true;

  // --- Date Filter ---
  const matchesDate = 
  !dateFilter || 
  (expense.date && (() => {
    const expenseDate = new Date(expense.date).toLocaleDateString("en-CA");
    const startDateString = startDate ? new Date(startDate).toLocaleDateString("en-CA") : null;
    const endDateString = endDate ? new Date(endDate).toLocaleDateString("en-CA") : null;

    if (!startDateString || !endDateString) return true; // no custom dates selected
    return expenseDate >= startDateString && expenseDate <= endDateString;
  })());

  // --- Combine All Filters ---
  return matchesSearch && matchesCategory  && excludeInstallment && matchesDate && matchesType;
});




  const handleEditClick = (id: number) => {
 navigate(`/expense/${id}`, {
  state: { projectId },
});

  };

  
  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 fetchGroups = async () => {
  try {
   
   // const response = await axios.get(`${API_URL}/expense-group/${groupId}`);
   const response = await axios.get(`${API_URL}/view-expense-group/${projectId}`);


    const groupsData = response.data.map((group: any) => ({
      ...group,
      category_ids:
        typeof group.category_ids === "string"
          ? JSON.parse(group.category_ids)
          : group.category_ids || []
    }));

       const filteredGroup = groupsData.filter(
      (group: any) => group.id === Number(groupId)
    );

    setGroups(filteredGroup);


   // setGroups(response.data);
 

  } catch (error) {
    console.error("Failed to load groups", 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();
    fetchGroups();
  }, [API_URL]);

   useEffect(() => {
          if (dateFilter !== "custom") {
            let start = "";
            let end = dayjs().format("YYYY-MM-DD");
      
            switch (dateFilter) {
              case "today":
                start = end;
                break;
              case "yesterday":
                start = dayjs().subtract(1, "day").format("YYYY-MM-DD");
                end = start;
                break;
              case "this_week":
                start = dayjs().startOf("week").format("YYYY-MM-DD");
                break;
              case "last_week":
                start = dayjs().subtract(1, "week").startOf("week").format("YYYY-MM-DD");
                end = dayjs().subtract(1, "week").endOf("week").format("YYYY-MM-DD");
                break;
              case "this_month":
                start = dayjs().startOf("month").format("YYYY-MM-DD");
                break;
              case "last_month":
                start = dayjs().subtract(1, "month").startOf("month").format("YYYY-MM-DD");
                end = dayjs().subtract(1, "month").endOf("month").format("YYYY-MM-DD");
                break;
              default:
                break;
            }
      
            setStartDate(start);
            setEndDate(end);
          }
        }, [dateFilter]);

 
  const handleChangePage = (event: unknown, newPage: number) => {
    setPage(newPage);
  };

    const handleChangePageMaterial = (event: unknown, newPageMaterial: number) => {
    setPageMaterial(newPageMaterial);
  };
  
  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 getSubCategoryName = (id: number, categories: Category[]) => {
  const subCategory = categories.find(cat => cat.id === id);
  return subCategory ? subCategory.category_name : "Unknown";
};
  
const generateSubCategoryData = (expenses: Expense[], categories: Category[]) => {
  const subCategoryTotals: Record<string, number> = {};

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

// const subCategories = categories.filter((cat) => String(cat.mainCatId) === String(categoryId));
const subCategories = group
  ? categories.filter((cat) => group.category_ids.includes(Number(cat.mainCatId)))
  : [];

  expenses.forEach((expense) => {
    let totalExpense = typeof expense.total === "string" ? parseFloat(expense.total) : expense.total;

    const subCategory = subCategories.find((sub) => String(sub.id) === String(expense.sub_category));
    if (subCategory && !isNaN(totalExpense)) {
      const subCategoryName = categoryMap[subCategory.id];
      subCategoryTotals[subCategoryName] = (subCategoryTotals[subCategoryName] || 0) + totalExpense;
    }
  });

  return Object.fromEntries(
    Object.entries(subCategoryTotals).map(([key, value]) => [key, parseFloat(value.toFixed(2))])
  );
};
  
  
  const categoryData = generateCategoryData(expenses, categories);
const subCategoryData= generateSubCategoryData(expenses, categories);
  const yearlyData = generateYearlyData(expenses);
  

//   const handleAddProductClick = () => {
//     // navigate(`/expense/create/${projectId}`);
//     navigate(`/expense/create/${projectId}`, {
//   state: { defaultCategoryId: categoryId }
// });
//   };


  const calculateGroupTotal = (group: any) => {
  return expenses
    .filter((expense) => group.category_ids.includes(Number(expense.category)))
    .reduce((sum, expense) => sum + Number(expense.total ?? 0), 0);
};
 

  const parseFiles = (file: string | undefined): string[] => {
    try {
      return file ? JSON.parse(file) : [];
    } catch (error) {
      return [];
    }
  };
  // Function to handle opening the modal
  const handleOpenModal = (file: string): void => {
    const url = `${LARAVEL_API_URL}/${file}`;
    setFileUrl(url);
    setOpenModal(true);
  };

  // Function to handle closing the modal
  const handleCloseModal = () => {
    setOpenModal(false);
    setFileUrl(null);
  };

   

 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;
};

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

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

  const subCategories = categories.filter((cat) => cat.mainCatId);

  expenses.forEach((expense) => {
    let hstAmount = typeof expense.hst === "string" ? parseFloat(expense.hst) : expense.hst;

    const subCategory = subCategories.find((sub) => String(sub.id) === String(expense.sub_category));
    if (subCategory && !isNaN(hstAmount)) {
      const subCategoryName = categoryMap[subCategory.id];
      subCategoryHST[subCategoryName] = (subCategoryHST[subCategoryName] || 0) + hstAmount;
    }
  });

  return Object.fromEntries(
    Object.entries(subCategoryHST).map(([key, value]) => [key, parseFloat(value.toFixed(2))])
  );
};


// Example Usage
const categoryHST = calculateCategoryHST(expenses, categories);
const subCategoryHST = generateSubCategoryHST(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", "Material + Labour"]; // All possible types
const typeColors: Record<string, string> = {
  Other: "#FF9800",
  Labour: "#4CAF50",
  Material: "#2196F3",
  "Material + Labour": "#9C27B0",
};

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,
      },
    ],
  };
};

const calculateGroupPieData = (group: any) => {

  const filteredExpenses = expenses.filter((expense) =>
    group.category_ids.includes(Number(expense.category))
  );

  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,
      },
    ],
  };
};

  

const handleExportToExcel = () => {
  if (!filteredExpenses.length) return;

  const exportData = filteredExpenses.map((row, index) => {
    return {
      "#": index + 1,
      "Date": row.date || "",
      "Description": row.description || "",
      "Type": row.type || "",
      "Amount ($)": Number(row.total ?? 0).toFixed(2),
    };
  });

  const worksheet = XLSX.utils.json_to_sheet(exportData);
  const workbook = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(workbook, worksheet, "Expenses");
  XLSX.writeFile(workbook, "expenses.xlsx");
};


  return (

    
    <>
  



<Box sx={{ marginTop: 2 }}>
  {/* Category Overview */}
{groups.map((group)=>{

   const groupCategories = group.category_ids
      .map((id: number) => categoryMap[id])
      .filter(Boolean);

    const totalCategories = group.category_ids.length;

    const pieData = calculateGroupPieData(group);
    const groupTotal = calculateGroupTotal(group);

  const groupPercentage =
    overallExpense > 0
      ? ((groupTotal / overallExpense) * 100).toFixed(2)
      : "0.00";

      const maxRows = 3;
const chipsPerRow =  5; 
const maxVisibleChips = maxRows * chipsPerRow;
const visibleCategories = groupCategories.slice(0, maxVisibleChips);
const remainingCount = groupCategories.length - maxVisibleChips;


  return(
  <Card elevation={4} sx={{ p: 3, mb: 4 }}   key={group.id} >
    <Typography variant="h4" gutterBottom sx={{ fontWeight: "bold", textAlign: "center" }}>
      {group.group_name} Overview
    </Typography>


    <Grid container spacing={3} mt={1} alignItems="center" justifyContent="center">
        
      <Grid item xs={12} md={4}>
        <Box sx={{ width: 200, height: 200, mx: "auto" }}>
          {/* <Pie data={calculatePieData(categoryMap[Number(categoryId)])} /> */}
              <Pie
              data={pieData}
              options={{
              plugins:{
              tooltip:{
              callbacks:{
              label:function(tooltipItem:any){
              
              const value = tooltipItem.raw as number;
              
              const total = (pieData.datasets[0].data as number[]).reduce(
                (a, b) => a + b,
                0
              );
              
              const percentage = ((value / total) * 100).toFixed(2);
              
              return `$${value} (${percentage}%)`;
              }
              }
              },
                  legend: {
                     
                      display: true,
                      labels: {
                        color: '#000',
                         boxWidth: 12,
                      
                      },
                    },
              }
              }}
              />
        </Box>
      </Grid>

  <Grid item xs={12} md={4}>
  <Card elevation={3} sx={{ p: 2 }}>
    <Typography
      variant="h6"
      gutterBottom
      sx={{ fontWeight: "bold", textAlign: "center" }}
    >
      Expense by Type
    </Typography>

    {allTypes.map((type) => {
      const filteredExpenses = expenses.filter(
        (e) =>
      //     categoryMap[e.category] === categoryMap[Number(categoryId)] &&
      //     (e.type || "Other") === type
      // );

        group?.category_ids.includes(Number(e.category)) &&
        (e.type || "Other") === type
    );


      const total = filteredExpenses.reduce(
        (sum, e) => sum + Number(e.total ?? 0),
        0
      );

      return (
        <Box
          key={type}
          sx={{
            display: "flex",
            justifyContent: "space-between",
            p: 1,
            borderBottom: "1px solid #eee",
          }}
        >
          <Typography sx={{ fontWeight: "500" }}>{type}</Typography>
          <Typography sx={{ fontWeight: "bold", color: typeColors[type] }}>
            ${total.toFixed(2)}
          </Typography>
        </Box>
      );
    })}
  </Card>
</Grid>

      <Grid item xs={12} md={4} textAlign="center">
        <Typography variant="h6">Total Expense</Typography>
        <Typography variant="h4" color="primary">
          {/* ${categoryData[categoryMap[Number(categoryId)]]?.toFixed(2)} */}
              ${group.category_ids
      .reduce((sum, catId) => sum + (categoryData[categoryMap[catId]] ?? 0), 0)
      .toFixed(2)}
        </Typography>
        <Typography variant="h6" sx={{ mt: 2 }}>Total HST</Typography>
        <Typography variant="h5" color="secondary">
          {/* ${(categoryHST[categoryMap[Number(categoryId)]] ?? 0).toFixed(2)} */}
         ${group.category_ids
      .reduce((sum, catId) => sum + (categoryHST[categoryMap[catId]] ?? 0), 0)
      .toFixed(2)}
        </Typography>
           <Typography variant="h6" sx={{ mt: 2 }}>Share of Overall</Typography>
        <Typography variant="h3" sx={{ fontWeight: "bold", color: "green" }}>
          {/* {((categoryData[categoryMap[Number(categoryId)]] / overallExpense) * 100).toFixed(2)}% */}
        {(
      (group.category_ids.reduce(
        (sum, catId) => sum + (categoryData[categoryMap[catId]] ?? 0),
        0
      ) /
        overallExpense) *
      100
    ).toFixed(2)}%
        </Typography>
      </Grid>
    
    </Grid>
  </Card>
  );
})}
  


<div>
  
   <Grid container spacing={1} sx={{ marginTop: 1 }}>
     <Grid item xs={12}>
       <Card className={classes.card}>
         <Box mb={2} padding={2}>
           <Grid container spacing={2}>
       
             <Grid item lg={2} md={2} sm={6} xs={12}>
               <Typography variant="subtitle1" sx={{ marginBottom: 1 }}>
                 Select Date
               </Typography>
               <Select
                 className={classes.textField}
                 value={dateFilter}
                 onChange={(e) => setDateFilter(e.target.value)}
                 displayEmpty
                
                 sx={{
                  height: "37px",
                  fontSize: "14px",
                  padding: "4px",
                  minWidth: "120px"
                }}
               >
                 <MenuItem value="">Select date filter</MenuItem>
                 <MenuItem value="today">Today</MenuItem>
                 <MenuItem value="yesterday">Yesterday</MenuItem>
                 <MenuItem value="this_week">This Week</MenuItem>
                 <MenuItem value="last_week">Last Week</MenuItem>
                 <MenuItem value="this_month">This Month</MenuItem>
                 <MenuItem value="last_month">Last Month</MenuItem>
                 <MenuItem value="custom">Custom</MenuItem>
               </Select>
             </Grid>



                {/* Custom Date Fields (Shown Only If "Custom" Is Selected) */}
             {dateFilter === "custom" && (
               <>
                 <Grid item lg={2} md={2} sm={6} xs={12}>
                   <Typography variant="subtitle1" sx={{ marginBottom: 1 }}>
                     Start Date
                   </Typography>
                   <TextField
                   variant="outlined"
                     type="date"
                     size="small"
                    className={classes.textField}
                     value={startDate}
                     onChange={(e) => setStartDate(e.target.value)}
                     InputLabelProps={{ shrink: true }}
                     
                   />
                 </Grid>
                 <Grid item lg={2} md={2} sm={6} xs={12}>
                   <Typography variant="subtitle1" sx={{ marginBottom: 1 }}>
                     End Date
                   </Typography>
                   <TextField
                     type="date"
                     size="small"
                    className={classes.textField}
                     value={endDate}
                     onChange={(e) => setEndDate(e.target.value)}
                     InputLabelProps={{ shrink: true }}
              
                   />
                 </Grid>
               </>
             )}


                         <Grid item lg={2} md={2} sm={6} xs={12}>
               <Typography variant="subtitle1" sx={{ marginBottom: 1 }}>
                Type
               </Typography>
                <Select
                   className={classes.textField}
                   value={selectedType || ""}
                   onChange={(event) => setSelectedType(event.target.value)}
                   displayEmpty
                   sx={{
                     height: "37px",
                     fontSize: "14px",
                     padding: "4px",
                     minWidth: "120px"
                   }}
                 >
                   <MenuItem value="">All Types</MenuItem>
                    <MenuItem value="Labour">Labour</MenuItem>
                   <MenuItem value="Material">Material</MenuItem>
                    <MenuItem value="Material + Labour">Material + Labour</MenuItem>
                   <MenuItem value="Other">Other</MenuItem>
                 </Select>
              
             </Grid>
 
          
           </Grid>
         </Box>
       </Card>
     </Grid>
   </Grid>
 </div>


   <div>
    <Grid container spacing={1} sx={{ marginTop: 1 }}>
         <Grid item xs={12}>
          
     </Grid>
   </Grid>
 </div>

  <Grid container spacing={4} >
    <Grid item xs={12} sm={12} md={12}>
       <div ref={componentRef}>
    <Card className={classes.card}>
  
  <Grid
          container
          justifyContent={"space-between"}
          spacing={5}
          sx={{ borderBottom: 2, padding: 2 }}
          className={classes.titleGrid}
        >
          <Grid item lg={4} md={4} sm={4} xs={4} pt={2} alignContent={"center"}>
            <Typography className={classes.cardTitle}>Expense</Typography>
          </Grid>
          <Grid
            item
            lg={8}
            md={8}  
            sm={8}
            xs={8}
            sx={{ display: "flex", justifyContent: "flex-end" }}
          >
            <Grid
              container
              spacing={1}
              justifyContent="flex-end"
              sx={{ display: "flex" }}
            >

              <Grid item sx={{ '@media print': {
                      display: 'none',
                    } }}>
                <TextField
                  InputProps={{
                    startAdornment: (
                      <InputAdornment position="start">
                        <CiSearch className={classes.searchWidgetIcon} />
                      </InputAdornment>
                    ),
                    classes: {
                      root: classes.formControlList,
                    },
                  }}
                  fullWidth
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  placeholder="Expense .."
                  sx={{ width: "100%" }}
                  size="small" />
              </Grid>


                            {filteredExpenses.length > 0 && (
                                <>

                                <Grid item sx={{ '@media print': {
    display: 'none',
  } }}>
                            <Button
                              variant="contained"
                              className={classes.addButton}
                           //   onClick={handleAddProductClick}
                            >
                              Add Expense
                            </Button>
           </Grid>
                              <Grid item sx={{ '@media print': {
                                display: 'none',
                              } }}>
                                <ReactToPrint
                                  trigger={() => (
                                    <Button
                                      variant="contained"
                                      startIcon={<LocalPrintshopSharpIcon />}
                                      className={classes.addButton}
                                    >
                                      Print
                                    </Button>
                                  )}
                                  content={() => componentRef.current}
                                />
                              </Grid>

                              <Grid item sx={{ '@media print': {
    display: 'none',
  } }}>
        <Button
          variant="contained"
          startIcon={<DownloadIcon />} // You can use any icon you like
          className={classes.addButton}
          onClick={handleExportToExcel}
        >
          Excel
        </Button>
      </Grid>
      </>
                            )}

                          
                          
                          </Grid>

 
          </Grid>
        </Grid>

      <Grid item lg={12} md={12} sm={12} xs={12}>
        <Card sx={{ padding: 3 }}>
        <TableContainer sx={{ minHeight: 300}}>
        <Table className={classes.table}>
        <TableHead className={classes.tableHeaderRow}>
              <TableRow className={classes.tableRowHover}>
             <TableCell className={classes.tablheader}>Date</TableCell>
                                 <TableCell className={classes.tablheader}><strong>Description</strong></TableCell>
                                  <TableCell className={classes.tablheader}><strong>Category</strong></TableCell>
                                 <TableCell className={classes.tablheader}><strong>Type</strong></TableCell>
                                 <TableCell className={classes.tablheader} align="right"><strong>Amount</strong></TableCell>
                                   <TableCell className={classes.tablheader} sx={{ textAlign: "right" }}>
                                                       <strong>Actions</strong>
                                                     </TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
                {filteredExpenses.length === 0 ? (
                                                <TableRow>
                                                  <TableCell colSpan={5} align="center" className={classes.tablCell}>
                                                    No Data Available
                                                  </TableCell>
                                                </TableRow>
                                              ) : (
                         filteredExpenses
                          .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                          .sort((a, b) => {
                  const dateA = new Date(a.date).getTime();
                  const dateB = new Date(b.date).getTime();
              
                  // First sort by date (descending)
                  if (dateB !== dateA) {
                    return dateB - dateA;
                  }
              
                  // If the dates are the same, sort by ID (ascending)
                  return b.id - a.id;
                })
                          // .filter((expense) => expense.type === "Labour")
                          .map((expense, index) => (
                 
                                    <TableRow key={index}>
                                      <TableCell  scope="row" className={classes.tablCell}>{expense.date}</TableCell>
                                       <TableCell  scope="row" className={classes.tablCell}>
                                        {/* {expense.description} */}
                                         <Box display="flex" alignItems="center">
                                            {/* Details text */}
                                            <span>{expense.description}</span>
                                                                    {expense.file && expense.file.length > 0 && (
                                              <Box display="flex" marginLeft={1}>
                                                {parseFiles(expense.file).map((file, index) => (
                                                  <Button
                                                    key={index}
                                                    variant="text"
                                                    className={classes.viewInvoiceButton}
                                                    size="small"
                                                    onClick={() => handleOpenModal(file)}
                                                    sx={{
                                                      minWidth: "auto",
                                                      padding: 0,
                                                      marginRight: 1, // Add space between icons
                                                    }}
                                                  >
                                                    <DescriptionIcon style={{ fontSize: 16 }} />
                                                  </Button>
                                                ))}
                                                
                                                                      </Box>
                                                                    )}
                                                                   </Box>
                                        </TableCell>
                                        <TableCell scope="row" className={classes.tablCell}>
                          {/* <span style={{ display: "inline-flex", alignItems: "center" }}> */}
                        <Link 
                           to={`/project/${projectId}/category/${expense.category}`}
                  style={{ textDecoration: 'none', marginLeft: "6px", color: 'inherit' }}
                > 
                         {categoryMap[expense.category] || "Unknown"}
                          
                  {/* <LinkIcon fontSize="small" style={{ verticalAlign: "middle" }} /> */}
                </Link>
                {/* </span> */}
</TableCell>
                                     <TableCell  scope="row" className={classes.tablCell}>{expense.type}</TableCell>
                                  <TableCell  scope="row" className={classes.tablCell} align="right">${Number(expense.total ?? 0).toFixed(2)}</TableCell>
                                      <TableCell scope="row" className={classes.tablCell}>
                                       <Grid
                                                               container
                                                               spacing={1}
                                                               sx={{ display: "flex", justifyContent: "flex-end" }}
                                                             >
                                                               <Button
                                                                    variant="contained"
                                                                    className={classes.editButtonList}
                                                                    onClick={() => handleEditClick(expense.id)}
                                                                    sx={{
                                                                      marginLeft: "auto", // Pushes the edit button to the right
                                                                    }}
                                                                  >
                                                                    <EditSharpIcon className={classes.editListIcon} style={{ fontSize: 20 }} />
                                                                  </Button>
                                                             </Grid>
                                                               </TableCell>
                                    </TableRow>
                              
                   ))
                                )}
            </TableBody>
          </Table>

          <Grid
            spacing={5}
            sx={{ '@media print': { display: 'none',  } }}
            p={"18px"}
            py={4}
            justifyContent={"end"}
            container
            textAlign={"center"}
            alignContent={"center"}
            alignItems={"center"}
          >
            <Grid
              sx={{
                textAlign: "end",
                justifyContent: "flex-end",
                alignItems: "flex-end",
              }}
            >
             
         <Pagination
        count={Math.ceil(filteredExpenses.length / rowsPerPage)}
        page={page}
        rowsPerPage={rowsPerPage}
        onPageChange={handleChangePage}
      />
          </Grid>
        </Grid>
        
    </TableContainer>
           
        
        </Card>
      </Grid>
 </Card>
 </div>
      </Grid>

      </Grid>

      

   


  {/* Subcategories */}



  


 <Grid container spacing={4} justifyContent="center" sx={{ marginTop: 2 }}>
  {Object.entries(subCategoryData).map(([subCategoryName, totalAmount]) => {
    const filteredExpenses = expenses.filter(
      exp => categories.find(cat => String(cat.id) === String(exp.sub_category))?.category_name === subCategoryName
    );

    const pieData = calculatePieData(subCategoryName);

    return (
  <>
      {/* <Grid item xs={12} sm={4} md={4} key={subCategoryName}>
        <Typography variant="h5" sx={{ fontWeight: "bold", mb: 2, mt: 1 }}>
        Sub Categories
      </Typography>
          <Card elevation={3} sx={{ height: '510px', display: 'flex', flexDirection: 'column' }}>
            <CardContent sx={{ flex: 1, display: 'flex', flexDirection: 'column', position: 'relative' }}>
              <Grid container direction="column" alignItems="center">

              
                <Typography variant="body2" mt={2} align="center" sx={{ fontWeight: 'bold', fontSize: '15px' }}>
                  {subCategoryName}
                </Typography>

         
                <Grid container direction="row" alignItems="center" spacing={2} sx={{ marginTop: '10px' }}>
                  <Grid item md={8} sx={{ display: 'flex', justifyContent: 'center' }}>
                    <Box sx={{ width: '150px', height: '150px' }}>
                      <Pie
                        data={pieData}
                        options={{
                          plugins: {
                            tooltip: {
                              callbacks: {
                                label: function (tooltipItem) {
                                  const { dataIndex, dataset } = tooltipItem;
                                  const value = dataset.data[dataIndex] as number;
                                  const percentage = ((value / overallExpense) * 100).toFixed(2);
                                  return `${percentage}%`;
                                },
                              },
                            },
                            legend: { display: true, labels: { color: '#000' } },
                          },
                        }} />
                    </Box>
                  </Grid>

                  <Grid item md={3} sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
                    <Box sx={{ textAlign: 'center' }}>
                      <Typography variant="body2">
                        Total {filteredExpenses.length}
                      </Typography>
                      <Typography variant="h3" sx={{ fontSize: '1.2rem' }}>
                        {((totalAmount / overallExpense) * 100).toFixed(2)}%
                      </Typography>
                    </Box>
                  </Grid>
                </Grid>

      
                <Box
                  sx={{
                    flex: 1,
                    overflowY: 'auto',
                    maxHeight: '200px',
                    width: '100%',
                    marginTop: 2,
                  }}
                  className={classes.thinScrollbar}
                >
                  <Grid container direction="column" spacing={2}>
                    {filteredExpenses.map((expense, index) => (
                      <Grid item key={index} container justifyContent="space-between">
                        <Grid item xs={8}>
                          <Typography variant="body2">
                            {expense.date} <br /> {expense.description}
                          </Typography>
                        </Grid>
                        <Grid item xs={4} textAlign="right">
                          <Typography variant="body2">${expense.total}</Typography>
                        </Grid>
                        {index < filteredExpenses.length - 1 && (
                          <Grid item xs={12}>
                            <Box sx={{ borderBottom: '1px solid #ccc', my: 1 }} />
                          </Grid>
                        )}
                      </Grid>
                    ))}
                  </Grid>
                </Box>

         
                <Grid container justifyContent="space-between" sx={{ padding: '16px', position: 'absolute', bottom: 0, left: 0, right: 0 }}>
                  <Grid item xs={6}>
                    <Typography variant="h6">Total Expense:</Typography>
                    <Typography variant="body2" sx={{ fontSize: "1.00rem" }}>
                      ${totalAmount.toFixed(2)}
                    </Typography>
                  </Grid>

                  <Grid item xs={6} textAlign="right">
                    <Typography variant="h6">Total HST:</Typography>
                    <Typography variant="body2" sx={{ fontSize: "1.00rem" }}>
                      ${(subCategoryHST[subCategoryName] ?? 0).toFixed(2)}
                    </Typography>
                  </Grid>
                </Grid>

              </Grid>
            </CardContent>
          </Card>
        </Grid> */}
        
        </>
    );
  })}
</Grid>




</Box>


<Dialog open={openModal} onClose={handleCloseModal} fullWidth maxWidth="md">
  <DialogTitle>View File</DialogTitle>
  <DialogContent
    sx={{
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center',
     // overflow: 'auto', // allow scrolling when zoomed
     overflow:'hidden'
    }}
  >
    {isPdf ? (
      <iframe
        src={fileUrl || ''}
        style={{
          width: `${100 * zoom}%`,
          height: `${500 * zoom}px`,
        }}
        title="PDF Viewer"
      />
    ) : (
      <img
        src={fileUrl || ''}
        alt="File Content"
        style={{
          width: '100%',
          maxWidth: '100%',
          height: '500px',
          objectFit: 'contain',
          transform: `scale(${zoom})`,
          transformOrigin: 'center',
          transition: 'transform 0.2s ease',
        }}
      />
    )}
  </DialogContent>
  <DialogActions>
     <Box display="flex" justifyContent="center" flexGrow={1} gap={1} width="100%">
      <Button
        variant="outlined"
        size="small"
        onClick={handleZoomOut}
        sx={{ minWidth: '36px', fontSize:'16px' }}
      >
        -
      </Button>
      <Button
        variant="outlined"
        size="small"
        onClick={handleResetZoom}
        sx={{ minWidth: '60px' }}
      >
        Reset
      </Button>
      <Button
        variant="outlined"
        size="small"
        onClick={handleZoomIn}
        sx={{ minWidth: '36px',  fontSize:'16px' }}
      >
        +
      </Button>
    </Box>

    <Button onClick={handleCloseModal} color="primary">Close</Button>
  </DialogActions>
</Dialog>






      </>




       

  );
};

export default Index;
