import React, { useState, useEffect } from 'react';
import { useNumberCards, useDashboardChart } from '../hooks/useApi';
import { useWorkOrders } from '../hooks/useWorkOrder';
import { useAssetMaintenanceLogs } from '../hooks/useAssetMaintenance';
import { useAssets } from '../hooks/useAsset';
import { useTranslation } from 'react-i18next';
import { FaShoppingCart, FaChartLine, FaBoxes, FaTools, FaCheckCircle, FaClock, FaExclamationTriangle, FaArrowUp, FaArrowDown, FaUserClock, FaHardHat, FaExternalLinkAlt, FaFilter, FaTimes, FaWrench, FaCalendarCheck, FaBan } from 'react-icons/fa';
import TechnicianWorkingHoursReportModal from '../components/TechnicianWorkingHoursReportModal';
import TechnicianWorkOrderSummaryReportModal from '../components/TechnicianWorkOrderSummaryReportModal';
import useUserPermissions from '../hooks/useUserPermissions';

const isNullOrUnknownLabel = (val: any): boolean => {
  if (val === null || val === undefined) return true;
  const s = String(val).trim().toLowerCase();
  return s === '' || s === 'null' || s === 'unknown' || s === 'undefined' || s === 'none';
};

const ModernDashboard: React.FC = () => {
  const { t } = useTranslation();
  const { data: numberCards, loading: cardsLoading } = useNumberCards();

  const { workOrders: allWorkOrders } = useWorkOrders({}, 0, 0);
  const workOrders = React.useMemo(
    () => (allWorkOrders || []).filter(wo => wo.custom_delete_status !== 'Deleted'),
    [allWorkOrders]
  );

  const { logs: maintenanceLogs } = useAssetMaintenanceLogs({}, 0, 0);
  const { assets } = useAssets({}, 0, 0);

  const [workOrderChartData, setWorkOrderChartData] = useState<any>(null);
  const [workOrderGroupedChartData, setWorkOrderGroupedChartData] = useState<any>(null);
  const [maintenanceAssetChartData, setMaintenanceAssetChartData] = useState<any>(null);
  const [upDownTimeChartData, setUpDownTimeChartData] = useState<any>(null);
  const [assetDeviceStatusChartData, setAssetDeviceStatusChartData] = useState<any>(null);
  const [assigneesGroupedChartData, setAssigneesGroupedChartData] = useState<any>(null);
  const [maintenanceFrequencyChartData, setMaintenanceFrequencyChartData] = useState<any>(null);
  const [completionByTypeChartData, setCompletionByTypeChartData] = useState<any>(null);

  // ── Extended counts now include wfRejected (workflow_state === 'Rejected')
  //    and rejected (repair_status === 'Rejected')
  const [realWorkOrderCounts, setRealWorkOrderCounts] = useState({
    open: 0,
    inProgress: 0,
    completed: 0,
    pendingReview: 0,
    rejected: 0,          // repair_status === 'Rejected'
    total: 0,
    wfCompleted: 0,
    wfInProgress: 0,
    wfRejected: 0,        // workflow_state === 'Rejected'
  });

  const [insights, setInsights] = useState({
    assetsDown: 0,
    avgResponseTime: 0,
    maintenanceEfficiency: 0,
    overdueTasks: 0,
    plannedMaintenance: 0
  });

  const { data: upDownChart } = useDashboardChart('Up & Down Time Chart');
  const { data: workOrderChart } = useDashboardChart('Work Order Status Chart');
  const { data: assetWiseChart } = useDashboardChart('Maintenance - Asset wise Count');
  const { data: assigneesChart } = useDashboardChart('Asset Maintenance Assignees Status Count');
  const { data: frequencyChart } = useDashboardChart('Asset Maintenance Frequency Chart');

  const { restrictions, isAdmin: isWoAdmin } = useUserPermissions('Work_Order');
  const permittedIssueTypes: string[] = React.useMemo(
    () => restrictions['Issue Type']?.values || [],
    [JSON.stringify(restrictions['Issue Type']?.values)]
  );

  const [userRoles, setUserRoles] = useState<string[]>([]);

  useEffect(() => {
    const fetchRoles = async () => {
      try {
        const res = await fetch('/api/method/frappe.client.get_value?doctype=User&fieldname=["roles"]&filters={"name":"__user__"}'.replace('__user__', ''), {
          credentials: 'include',
        });
        const sessionRes = await fetch('/api/method/frappe.auth.get_logged_user', {
          credentials: 'include',
        });
        const sessionData = await sessionRes.json();
        const loggedUser = sessionData.message;
        if (loggedUser) {
          const rolesRes = await fetch(
            `/api/resource/User/${encodeURIComponent(loggedUser)}?fields=["roles"]`,
            { headers: { Accept: 'application/json' }, credentials: 'include' }
          );
          const rolesData = await rolesRes.json();
          const roles: string[] = (rolesData.data?.roles || []).map((r: any) => r.role);
          setUserRoles(roles);
        }
      } catch (e) {
        console.error('Error fetching user roles:', e);
      }
    };
    fetchRoles();
  }, []);

  const canSeeInspectionRejection = isWoAdmin ||
    userRoles.includes('System Manager') ||
    userRoles.includes('Quality Supervisor');

  const canSeeTimeToRepair = isWoAdmin ||
    userRoles.includes('System Manager') ||
    userRoles.includes('Cluster Manager');

  const [technicianHoursData, setTechnicianHoursData] = useState<any>(null);
  const [technicianWorkedData, setTechnicianWorkedData] = useState<any>(null);

  const [showTechnicianHoursReport, setShowTechnicianHoursReport] = useState(false);
  const [showTechnicianWorkOrderReport, setShowTechnicianWorkOrderReport] = useState(false);

  const [inspectionSummaryData, setInspectionSummaryData] = useState<any>(null);
  const [rejectionSummaryData, setRejectionSummaryData] = useState<any>(null);
  const [showInspectionReport, setShowInspectionReport] = useState(false);
  const [showRejectionReport, setShowRejectionReport] = useState(false);
  const [timeToRepairData, setTimeToRepairData] = useState<any>(null);
  const [showTimeToRepairReport, setShowTimeToRepairReport] = useState(false);
  const [chartDetail, setChartDetail] = useState<{ title: string; data: any; redirectContext?: 'wo_status' | 'wo_type' | null } | null>(null);

  // ── Asset status report modal
  const [showAssetReport, setShowAssetReport] = useState(false);

  const [issueTypes, setIssueTypes] = useState<string[]>([]);
  const [selectedIssueType, setSelectedIssueType] = useState<string>('');

  useEffect(() => {
    const fetchIssueTypes = async () => {
      try {
        const response = await fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', {
          headers: { 'Accept': 'application/json' },
          credentials: 'include'
        });
        const data = await response.json();
        if (data.data) {
          setIssueTypes(data.data.map((d: any) => d.name));
        }
      } catch (error) {
        console.error('Error fetching issue types:', error);
      }
    };
    fetchIssueTypes();
  }, []);

  const filteredWorkOrders = React.useMemo(() => {
    if (!workOrders) return [];
    if (!isWoAdmin && permittedIssueTypes.length > 0) return workOrders;
    if (!selectedIssueType) return workOrders;
    return workOrders.filter(wo => wo.work_order_type === selectedIssueType);
  }, [workOrders, isWoAdmin, permittedIssueTypes, selectedIssueType]);

  useEffect(() => {
    const fetchTechnicianHours = async () => {
      try {
        const filters: Record<string, any> = {};
        if (!isWoAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1
            ? permittedIssueTypes[0]
            : ['in', permittedIssueTypes];
        } else if (selectedIssueType) {
          filters.work_order_type = selectedIssueType;
        }

        const response = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({
            report_name: 'Technicians working Hours',
            filters: filters,
            ignore_prepared_report: 1
          })
        });
        const data = await response.json();

        if (data.message?.result) {
          const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
          const labels = rows.map((r: any) => r.technician_name || 'Unknown');
          const values = rows.map((r: any) => parseFloat(r.total_hours) || 0);

          setTechnicianHoursData({
            labels,
            datasets: [{ name: 'Total Hours', values, colors: ['#6366F1'] }],
            type: 'Bar'
          });
        }
      } catch (error) {
        console.error('Error fetching technician hours:', error);
      }
    };
    fetchTechnicianHours();
  }, [permittedIssueTypes, isWoAdmin, selectedIssueType]);

  useEffect(() => {
    const fetchTechnicianWorked = async () => {
      try {
        const filters: Record<string, any> = {};
        if (!isWoAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1
            ? permittedIssueTypes[0]
            : ['in', permittedIssueTypes];
        } else if (selectedIssueType) {
          filters.work_order_type = selectedIssueType;
        }

        const response = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          credentials: 'include',
          body: JSON.stringify({
            report_name: 'Technician Work Order Summary',
            filters: filters,
            ignore_prepared_report: 1
          })
        });
        const data = await response.json();

        if (data.message?.result) {
          const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
          const labels = rows.map((r: any) => r.assigned_technician || 'Unknown');
          const datasets = [
            { name: 'completed', values: rows.map((r: any) => parseFloat(r.completed) || 0), color: '#10B981' },
            { name: 'in_progress', values: rows.map((r: any) => parseFloat(r.in_progress) || 0), color: '#3B82F6' },
            { name: 'open', values: rows.map((r: any) => parseFloat(r.open) || 0), color: '#F59E0B' }
          ].filter(ds => ds.values.some((v: number) => v > 0));

          setTechnicianWorkedData({ labels, datasets, type: 'Bar' });
        }
      } catch (error) {
        console.error('Error fetching technician worked:', error);
      }
    };
    fetchTechnicianWorked();
  }, [permittedIssueTypes, isWoAdmin, selectedIssueType]);

  const findWoTypeLabelKey = (cols: any[], rows: any[]): string => {
    const byFieldname = cols.find((c: any) =>
      c?.fieldname &&
      (c.fieldname.toLowerCase().includes('work_order_type') ||
        c.fieldname.toLowerCase().includes('wo_type') ||
        c.fieldname.toLowerCase() === 'type')
    );
    if (byFieldname) return byFieldname.fieldname;
    const byLabel = cols.find((c: any) =>
      c?.label &&
      (c.label.toLowerCase().includes('wo type') ||
        c.label.toLowerCase().includes('work order type') ||
        c.label.toLowerCase() === 'type')
    );
    if (byLabel) return byLabel.fieldname;
    if (cols[1]?.fieldname) return cols[1].fieldname;
    return cols[0]?.fieldname || Object.keys(rows[0] || {})[0] || 'name';
  };

  const findCountKey = (cols: any[], rows: any[], excludeKey: string): string | null => {
    const isNumericVal = (val: any) =>
      (typeof val === 'number' && !isNaN(val)) ||
      (typeof val === 'string' && val !== '' && !isNaN(parseFloat(val)));
    const numericCols = cols.filter((c: any) =>
      c?.fieldname && c.fieldname !== excludeKey &&
      rows.some((r: any) => isNumericVal(r[c.fieldname]))
    );
    const preferred = numericCols.find((c: any) => {
      const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
      return s.includes('count') || s.includes('linked') || s.includes('inspection') ||
        s.includes('rejection') || s.includes('total') || s.includes('wo');
    });
    if (preferred) return preferred.fieldname;
    return numericCols[0]?.fieldname || null;
  };

  useEffect(() => {
    if (!canSeeInspectionRejection) return;
    const fetchInspectionSummary = async () => {
      try {
        const filters: Record<string, any> = {};
        if (!isWoAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
        } else if (selectedIssueType) { filters.work_order_type = selectedIssueType; }
        const response = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'Inspection Linked Work Orders Summary', filters, ignore_prepared_report: 1 })
        });
        const data = await response.json();
        if (data.message?.result) {
          const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
          const cols: any[] = data.message?.columns || [];
          const labelKey = findWoTypeLabelKey(cols, rows);
          const countKey = findCountKey(cols, rows, labelKey);
          const grouped: Record<string, number> = {};
          rows.forEach((r: any) => {
            const label = (r[labelKey] !== null && r[labelKey] !== undefined && r[labelKey] !== '') ? String(r[labelKey]) : '(No Type)';
            const val = countKey ? (parseFloat(r[countKey]) || 0) : 0;
            grouped[label] = (grouped[label] || 0) + val;
          });
          const labels = Object.keys(grouped);
          const values = Object.values(grouped);
          const countCol = cols.find((c: any) => c?.fieldname === countKey);
          setInspectionSummaryData({ labels, datasets: [{ name: countCol?.label || 'Count', values }], rawRows: rows, columns: cols, type: 'Bar' });
        }
      } catch (error) { console.error('Error fetching inspection summary:', error); }
    };
    fetchInspectionSummary();
  }, [canSeeInspectionRejection, permittedIssueTypes, isWoAdmin, selectedIssueType]);

  useEffect(() => {
    if (!canSeeInspectionRejection) return;
    const fetchRejectionSummary = async () => {
      try {
        const filters: Record<string, any> = {};
        if (!isWoAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
        } else if (selectedIssueType) { filters.work_order_type = selectedIssueType; }
        const response = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'WO Rejection Summary', filters, ignore_prepared_report: 1 })
        });
        const data = await response.json();
        if (data.message?.result) {
          const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
          const cols: any[] = data.message?.columns || [];
          const labelKey = findWoTypeLabelKey(cols, rows);
          const isNumericVal = (val: any) =>
            (typeof val === 'number' && !isNaN(val)) || (typeof val === 'string' && val !== '' && !isNaN(parseFloat(val)));
          const isNumericCol = (c: any) => {
            if (!c?.fieldname || c.fieldname === labelKey || !rows.length) return false;
            if (c.fieldtype && ['Int', 'Float', 'Currency', 'Percent'].includes(c.fieldtype)) return true;
            const sample = rows.find((r: any) => r[c.fieldname] != null && r[c.fieldname] !== '');
            if (!sample) return false;
            return isNumericVal(sample[c.fieldname]);
          };
          const numericCols = cols.filter(isNumericCol);
          const colsToUse = numericCols.length > 0 ? numericCols : cols.filter((c: any) => {
            if (!c?.fieldname || c.fieldname === labelKey || !rows.length) return false;
            const sample = rows.find((r: any) => r[c.fieldname] != null && r[c.fieldname] !== '');
            if (!sample) return false;
            return !isNaN(parseFloat(String(sample[c.fieldname])));
          });
          const groupedMap: Record<string, Record<string, number>> = {};
          rows.forEach((r: any) => {
            const label = (r[labelKey] !== null && r[labelKey] !== undefined && r[labelKey] !== '') ? String(r[labelKey]) : '(No Type)';
            if (!groupedMap[label]) groupedMap[label] = {};
            colsToUse.forEach((c: any) => {
              groupedMap[label][c.fieldname] = (groupedMap[label][c.fieldname] || 0) + (parseFloat(r[c.fieldname]) || 0);
            });
          });
          const totalRejectedColKey = (() => {
            const preferred = colsToUse.find((c: any) => {
              const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
              return s.includes('total_rejected') || s.includes('total rejected') || s.includes('rejected');
            });
            return preferred?.fieldname || colsToUse[colsToUse.length - 1]?.fieldname || null;
          })();
          const labels = Object.keys(groupedMap);
          const totalRejectedValues = labels.map(lbl => totalRejectedColKey ? (groupedMap[lbl][totalRejectedColKey] || 0) : 0);
          const grandTotal = totalRejectedValues.reduce((s, v) => s + v, 0);
          setRejectionSummaryData({ labels, datasets: [{ name: 'Total Rejected', values: totalRejectedValues }], totalRejected: grandTotal, rawRows: rows, columns: cols, type: 'Bar' });
        }
      } catch (error) { console.error('Error fetching rejection summary:', error); }
    };
    fetchRejectionSummary();
  }, [canSeeInspectionRejection, permittedIssueTypes, isWoAdmin, selectedIssueType]);

  useEffect(() => {
    if (assets && assets.length > 0) {
      let totalUpTime = 0, totalDownTime = 0;
      assets.forEach(asset => {
        const upTime = asset.custom_up_time || 0;
        const downTime = asset.custom_down_time || 0;
        totalUpTime += typeof upTime === 'number' ? upTime : 0;
        totalDownTime += typeof downTime === 'number' ? downTime : 0;
      });
      const labels: string[] = [], values: number[] = [];
      if (totalUpTime > 0) { labels.push(t('dashboard.upTime')); values.push(totalUpTime); }
      if (totalDownTime > 0) { labels.push(t('dashboard.downTime')); values.push(totalDownTime); }
      if (labels.length > 0) {
        const pieColors: string[] = [];
        if (totalUpTime > 0) pieColors.push('#6366F1');
        if (totalDownTime > 0) pieColors.push('#8B5CF6');
        setUpDownTimeChartData({ labels, datasets: [{ name: 'Time', values, colors: pieColors }], type: 'Pie' });
      } else { setUpDownTimeChartData(null); }
    } else { setUpDownTimeChartData(null); }
  }, [assets]);

  useEffect(() => {
    if (assets && assets.length > 0) {
      const downCount = assets.filter(asset => (asset.custom_device_status || '').trim().toLowerCase() === 'down').length;
      setInsights(prev => ({ ...prev, assetsDown: downCount }));
    }
  }, [assets]);

  // Asset UP & Down — group by custom_device_status (Count)
  useEffect(() => {
    if (assets && assets.length > 0) {
      const statusCounts: Record<string, number> = {};
      assets.forEach(asset => {
        const status = (asset.custom_device_status || 'Unknown').trim();
        statusCounts[status] = (statusCounts[status] || 0) + 1;
      });
      const entries = Object.entries(statusCounts).sort(([, a], [, b]) => b - a);
      const labels = entries.map(([s]) => s);
      const values = entries.map(([, c]) => c);
      const colorPalette: Record<string, string> = {
        'Up': '#10B981', 'up': '#10B981',
        'Down': '#EF4444', 'down': '#EF4444',
        'Under Maintenance': '#F59E0B', 'under maintenance': '#F59E0B',
        'Decommissioned': '#6B7280',
      };
      const colors = labels.map((l, i) => colorPalette[l] || colorPalette[l.toLowerCase()] || generateColors(labels.length)[i]);
      setAssetDeviceStatusChartData({ labels, datasets: [{ name: 'Assets', values, colors }], type: 'Pie', total: assets.length });
    } else {
      setAssetDeviceStatusChartData(null);
    }
  }, [assets]);

  useEffect(() => {
    if (filteredWorkOrders && filteredWorkOrders.length > 0) {
      const statusCounts: Record<string, number> = {};
      let openCount = 0, inProgressCount = 0, completedCount = 0, pendingReviewCount = 0, rejectedCount = 0;

      filteredWorkOrders.forEach(wo => {
        const status = wo.repair_status || 'Unknown';
        statusCounts[status] = (statusCounts[status] || 0) + 1;
        const sl = status.toLowerCase();
        if (sl === 'open') openCount++;
        if (sl === 'work in progress') inProgressCount++;
        if (sl === 'closed') completedCount++;
        if (sl === 'pending review') pendingReviewCount++;
        if (sl === 'rejected') rejectedCount++;
      });

      // ── Workflow state counts ──────────────────────────────────────────────
      let wfCompletedCount = 0, wfInProgressCount = 0, wfRejectedCount = 0;
      filteredWorkOrders.forEach(wo => {
        const wfState = (wo.workflow_state || '').toLowerCase();
        if (wfState === 'closed' || wfState === 'sent to supervisor') {
          wfCompletedCount++;
        } else if (wfState === 'rejected') {
          wfRejectedCount++;
        } else {
          wfInProgressCount++;
        }
      });

      const statusDisplayOrder = ['Open', 'Work In Progress', 'Pending Review', 'Closed', 'Rejected', 'Cancelled', 'Unknown'];
      const sortedEntries = Object.entries(statusCounts).sort(([a], [b]) => {
        const aIdx = statusDisplayOrder.indexOf(a), bIdx = statusDisplayOrder.indexOf(b);
        if (aIdx === -1 && bIdx === -1) return a.localeCompare(b);
        if (aIdx === -1) return 1; if (bIdx === -1) return -1;
        return aIdx - bIdx;
      });
      const labels = sortedEntries.map(([label]) => label);
      const values = sortedEntries.map(([, count]) => count);
      const colorMap: Record<string, string> = {
        'Open': '#F59E0B', 'Work In Progress': '#3B82F6', 'Pending Review': '#E11D48',
        'Pending': '#8B5CF6', 'Completed': '#10B981', 'Closed': '#10B981',
        'Rejected': '#EF4444', 'Cancelled': '#EC4899', 'Unknown': '#6B7280'
      };
      const colors = labels.map(label => colorMap[label] || '#6366F1');
      setWorkOrderChartData({ labels, datasets: [{ name: 'Work Orders', values, colors }], type: 'bar' });
      setRealWorkOrderCounts({
        open: openCount,
        inProgress: inProgressCount,
        completed: completedCount,
        pendingReview: pendingReviewCount,
        rejected: rejectedCount,
        total: filteredWorkOrders.length,
        wfCompleted: wfCompletedCount,
        wfInProgress: wfInProgressCount,
        wfRejected: wfRejectedCount,
      });

      const normalizeStatus = (status: string): string => {
        const s = status.toLowerCase().trim();
        if (s.includes('open')) return 'Open';
        if (s.includes('work in progress') || s.includes('in progress') || s.includes('wip')) return 'Work In Progress';
        if (s.includes('pending review') || s.includes('pending')) return 'Pending Review';
        if (s.includes('completed') || s.includes('complete')) return 'Completed';
        if (s.includes('closed')) return 'Closed';
        if (s.includes('rejected')) return 'Rejected';
        return status;
      };

      const groupedData: Record<string, Record<string, number>> = {};
      const allStatuses = new Set<string>();
      filteredWorkOrders.forEach(wo => {
        const rawType = wo.work_order_type;
        if (isNullOrUnknownLabel(rawType)) return;
        const workOrderType = String(rawType);
        const repairStatus = normalizeStatus(wo.repair_status || 'Unknown');
        allStatuses.add(repairStatus);
        if (!groupedData[workOrderType]) groupedData[workOrderType] = {};
        groupedData[workOrderType][repairStatus] = (groupedData[workOrderType][repairStatus] || 0) + 1;
      });

      const workOrderTypeLabels = Object.keys(groupedData);
      const statusOrder = ['Open', 'Work In Progress', 'Pending Review', 'Completed', 'Closed', 'Rejected'];
      const statusList = Array.from(allStatuses).sort((a, b) => {
        const aI = statusOrder.indexOf(a), bI = statusOrder.indexOf(b);
        if (aI !== -1 && bI !== -1) return aI - bI;
        if (aI !== -1) return -1; if (bI !== -1) return 1;
        return a.localeCompare(b);
      });
      const datasets = statusList.map(status => ({ name: status, values: workOrderTypeLabels.map(type => groupedData[type][status] || 0) }));
      setWorkOrderGroupedChartData({ labels: workOrderTypeLabels, datasets, type: 'Bar' });

      // ── Per-type stats including wfRejected and rejected ─────────────────
      const typeStatMap: Record<string, {
        total: number; wfCompleted: number; wfInProgress: number; wfRejected: number;
        closed: number; pendingReview: number; open: number; inProgress: number; rejected: number;
      }> = {};
      filteredWorkOrders.forEach(wo => {
        const rawType = wo.work_order_type;
        if (isNullOrUnknownLabel(rawType)) return;
        const type = String(rawType);
        if (!typeStatMap[type]) typeStatMap[type] = {
          total: 0, wfCompleted: 0, wfInProgress: 0, wfRejected: 0,
          closed: 0, pendingReview: 0, open: 0, inProgress: 0, rejected: 0
        };
        typeStatMap[type].total++;
        const wfState = (wo.workflow_state || '').toLowerCase();
        if (wfState === 'closed' || wfState === 'sent to supervisor') typeStatMap[type].wfCompleted++;
        else if (wfState === 'rejected') typeStatMap[type].wfRejected++;
        else typeStatMap[type].wfInProgress++;
        const rs = (wo.repair_status || '').toLowerCase();
        if (rs === 'closed') typeStatMap[type].closed++;
        if (rs === 'pending review') typeStatMap[type].pendingReview++;
        if (rs === 'open') typeStatMap[type].open++;
        if (rs === 'work in progress') typeStatMap[type].inProgress++;
        if (rs === 'rejected') typeStatMap[type].rejected++;
      });

      const completionTypeLabels = Object.keys(typeStatMap);
      const completionRateByType = completionTypeLabels.map(type => {
        const s = typeStatMap[type];
        return {
          type, ...s,
          rate: s.total > 0 ? (s.wfCompleted / s.total) * 100 : 0,
        };
      });
      setCompletionByTypeChartData({ labels: completionTypeLabels, rates: completionRateByType });
    } else {
      setWorkOrderGroupedChartData(null);
      setCompletionByTypeChartData(null);
    }
  }, [filteredWorkOrders]);

  useEffect(() => {
    if (maintenanceLogs && maintenanceLogs.length > 0) {
      const assetCounts: Record<string, number> = {};
      let completedMaintenance = 0, plannedMaintenance = 0, overdueMaintenance = 0;
      const today = new Date();

      maintenanceLogs.forEach(log => {
        const assetName = log.asset_name || 'Unknown';
        assetCounts[assetName] = (assetCounts[assetName] || 0) + 1;
        if (log.maintenance_status?.toLowerCase() === 'completed') completedMaintenance++;
        if (log.maintenance_status?.toLowerCase() === 'planned') plannedMaintenance++;
        if (log.due_date && new Date(log.due_date) < today && log.maintenance_status !== 'Completed') overdueMaintenance++;
      });

      const sorted = Object.entries(assetCounts).sort(([, a], [, b]) => b - a).slice(0, 10);
      setMaintenanceAssetChartData({ labels: sorted.map(([name]) => name), datasets: [{ name: 'Maintenance Count', values: sorted.map(([, count]) => count), colors: generateColors(sorted.length) }], type: 'bar' });

      const maintenanceEfficiency = maintenanceLogs.length > 0 ? (completedMaintenance / maintenanceLogs.length) * 100 : 0;
      setInsights(prev => ({ ...prev, maintenanceEfficiency, overdueTasks: overdueMaintenance, plannedMaintenance }));

      const groupedData: Record<string, Record<string, number>> = {};
      const allStatuses = new Set<string>();
      const normalizeStatus = (status: string, log: any): string => {
        const statusLower = status.toLowerCase().trim();
        const today = new Date();
        const dueDate = log.due_date ? new Date(log.due_date) : null;
        if (dueDate && dueDate < today && statusLower !== 'completed' && statusLower !== 'cancelled') return 'Overdue';
        if (statusLower.includes('completed on time') || statusLower === 'completed on time') return 'Completed On Time';
        if (statusLower.includes('completed within') || statusLower.includes('within sla') || statusLower === 'completed') return 'Completed Within SLA';
        if (statusLower.includes('delay') || statusLower.includes('late')) return 'Delay In Completion';
        if (statusLower.includes('pending') || statusLower === 'planned') return 'Pending';
        if (statusLower.includes('overdue')) return 'Overdue';
        if (statusLower.includes('cancelled') || statusLower === 'cancelled') return 'Cancelled';
        return status;
      };

      maintenanceLogs.forEach(log => {
        const assignee = log.assign_to_name || 'null';
        const normalizedStatus = normalizeStatus(log.maintenance_status || 'Unknown', log);
        allStatuses.add(normalizedStatus);
        if (!groupedData[assignee]) groupedData[assignee] = {};
        groupedData[assignee][normalizedStatus] = (groupedData[assignee][normalizedStatus] || 0) + 1;
      });

      const assigneeLabels = Object.keys(groupedData);
      const statusOrder = ['Completed On Time', 'Completed Within SLA', 'Delay In Completion', 'Pending', 'Overdue', 'Cancelled'];
      const statusList = Array.from(allStatuses).sort((a, b) => {
        const aI = statusOrder.indexOf(a), bI = statusOrder.indexOf(b);
        if (aI !== -1 && bI !== -1) return aI - bI;
        if (aI !== -1) return -1; if (bI !== -1) return 1;
        return a.localeCompare(b);
      });
      const datasets = statusList.map(status => ({ name: status, values: assigneeLabels.map(assignee => groupedData[assignee][status] || 0) }));
      setAssigneesGroupedChartData({ labels: assigneeLabels, datasets, type: 'Bar' });

      const frequencyCounts: Record<string, number> = {};
      maintenanceLogs.forEach(log => {
        const frequency = log.periodicity || log.maintenance_type || 'Other';
        frequencyCounts[frequency] = (frequencyCounts[frequency] || 0) + 1;
      });
      const sortedFrequencies = Object.entries(frequencyCounts).sort(([, a], [, b]) => b - a);
      setMaintenanceFrequencyChartData({ labels: sortedFrequencies.map(([name]) => name), datasets: [{ name: 'Frequency', values: sortedFrequencies.map(([, count]) => count), colors: generateColors(sortedFrequencies.length) }], type: 'bar' });
    } else {
      setAssigneesGroupedChartData(null);
      setMaintenanceFrequencyChartData(null);
    }
  }, [maintenanceLogs]);

  useEffect(() => {
    if (workOrders && workOrders.length > 0) {
      let totalResponseHours = 0, responseCount = 0;
      workOrders.forEach(wo => {
        if (wo.creation && wo.first_responded_on) {
          const created = new Date(wo.creation);
          const responded = new Date(wo.first_responded_on);
          const hours = (responded.getTime() - created.getTime()) / (1000 * 60 * 60);
          if (hours >= 0) { totalResponseHours += hours; responseCount++; }
        }
      });
      const avgResponseTime = responseCount > 0 ? totalResponseHours / responseCount : 0;
      setInsights(prev => ({ ...prev, avgResponseTime }));
    }
  }, [workOrders]);

  useEffect(() => {
    if (!canSeeTimeToRepair) return;
    const fetchTimeToRepair = async () => {
      try {
        const filters: Record<string, any> = {};
        if (!isWoAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
        } else if (selectedIssueType) { filters.work_order_type = selectedIssueType; }
        const response = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'Time to Repair', filters, ignore_prepared_report: 1 })
        });
        const data = await response.json();
        if (data.message?.result) {
          const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
          const cols: any[] = data.message?.columns || [];
          const woTypeCol = cols.find((c: any) => {
            const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
            return s.includes('wo_type') || s.includes('wo type') || s.includes('work_order_type') || s.includes('work order type');
          }) || cols[1];
          const timeCol = cols.find((c: any) => {
            const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
            return s.includes('time_to_repair') || s.includes('time to repair') || s.includes('repair_time') || s.includes('hours');
          }) || cols[cols.length - 1];

          const typeMap: Record<string, { total: number; count: number }> = {};
          rows.forEach((r: any) => {
            const rawWoType = woTypeCol ? r[woTypeCol.fieldname] : null;
            if (isNullOrUnknownLabel(rawWoType)) return;
            const woType = String(rawWoType);
            const time = timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0;
            if (!typeMap[woType]) typeMap[woType] = { total: 0, count: 0 };
            typeMap[woType].total += time;
            typeMap[woType].count += 1;
          });

          const typeLabels = Object.keys(typeMap);
          const avgByType = typeLabels.map(t => parseFloat((typeMap[t].total / typeMap[t].count).toFixed(3)));
          const validRows = rows.filter((r: any) => !isNullOrUnknownLabel(woTypeCol ? r[woTypeCol.fieldname] : null));
          const overallAvg = validRows.length > 0
            ? parseFloat((validRows.reduce((s: number, r: any) => s + (timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0), 0) / validRows.length).toFixed(3))
            : 0;

          const reportSummary = data.message?.report_summary || [];
          const summaryAvg = reportSummary.find((s: any) => s.label?.toLowerCase().includes('avg') || s.label?.toLowerCase().includes('overall'));
          setTimeToRepairData({
            labels: typeLabels, datasets: [{ name: 'Avg Time to Repair (hrs)', values: avgByType }],
            overallAvg: summaryAvg ? parseFloat(summaryAvg.value) || overallAvg : overallAvg,
            rawRows: rows, columns: cols, reportSummary, type: 'Bar'
          });
        }
      } catch (error) { console.error('Error fetching time to repair:', error); }
    };
    fetchTimeToRepair();
  }, [canSeeTimeToRepair, permittedIssueTypes, isWoAdmin, selectedIssueType]);

  if (cardsLoading) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600 mx-auto mb-4"></div>
          <div className="text-gray-600 dark:text-gray-400">{t('dashboard.loading')}</div>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 p-6">
      <div className="max-w-[1600px] mx-auto">

        {/* ── Global Filter Bar ───────────────────────────────────────── */}
        {(isWoAdmin || permittedIssueTypes.length === 0) && (
          <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 px-5 py-3 mb-5 flex items-center gap-4 flex-wrap">
            <div className="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
              <div className="w-7 h-7 bg-indigo-50 dark:bg-indigo-900/30 rounded-lg flex items-center justify-center">
                <FaFilter className="text-indigo-500 text-xs" />
              </div>
              <span className="font-semibold text-gray-700 dark:text-gray-300">{t('dashboard.dashboardFilter', 'Dashboard Filter')}</span>
            </div>
            <div className="flex items-center gap-2">
              <label className="text-xs font-medium text-gray-500 dark:text-gray-400">Technical Department</label>
              <select
                value={selectedIssueType}
                onChange={(e) => setSelectedIssueType(e.target.value)}
                className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[200px]"
              >
                <option value="">{t('dashboard.allDepartments', 'All Departments')}</option>
                {issueTypes.map(type => <option key={type} value={type}>{type}</option>)}
              </select>
            </div>
            {selectedIssueType && (
              <>
                <button
                  onClick={() => setSelectedIssueType('')}
                  className="text-xs text-red-500 hover:text-red-700 dark:text-red-400 flex items-center gap-1 px-2 py-1 rounded-lg hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
                >
                  <FaTimes size={10} /> {t('dashboard.clearFilter', 'Clear')}
                </button>
                <span className="text-xs text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-900/30 px-3 py-1 rounded-full font-medium">
                  {selectedIssueType}
                </span>
              </>
            )}
          </div>
        )}

        {/*
          ── TOP SECTION ─────────────────────────────────────────────
          3-row × 12-col grid
        */}
        <div className="grid grid-cols-12 gap-4 mb-5" style={{ gridTemplateRows: 'auto 1fr 1fr' }}>

          {/* ── Stats bar — left 7 cols, row 1 ── */}
          <div className="col-span-12 lg:col-span-7">
            <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 px-4 py-2">
              {/* 7 items: Assets | Open | In Progress | Pending | Closed | Rejected | Total */}
              <div className="grid grid-cols-4 lg:grid-cols-7 divide-x divide-gray-200 dark:divide-gray-700">
                <StatCard icon={<FaBoxes className="text-indigo-600" />} value={assets?.length ?? numberCards?.total_assets ?? 0} label={t('dashboard.totalAssets')} bgColor="bg-indigo-50 dark:bg-indigo-900/20" iconColor="text-indigo-600" href="/asm_app/assets" />
                <StatCard icon={<FaShoppingCart className="text-amber-500" />} value={realWorkOrderCounts.open || (numberCards?.work_orders_open ?? 0)} label={t('dashboard.openWorkOrders')} bgColor="bg-amber-50 dark:bg-amber-900/20" iconColor="text-amber-500" href="/asm_app/work-orders?status=Open" />
                <StatCard icon={<FaClock className="text-blue-600" />} value={realWorkOrderCounts.inProgress || (numberCards?.work_orders_in_progress ?? 0)} label={t('dashboard.workOrdersInProgress')} bgColor="bg-blue-50 dark:bg-blue-900/20" iconColor="text-blue-600" href="/asm_app/work-orders?status=In+Progress" />
                <StatCard icon={<FaExclamationTriangle className="text-orange-500" />} value={realWorkOrderCounts.pendingReview} label={t('dashboard.pendingReviewWorkOrders', 'Pending Review')} bgColor="bg-orange-50 dark:bg-orange-900/20" iconColor="text-orange-500" href="/asm_app/work-orders?status=Pending+Review" />
                <StatCard icon={<FaCheckCircle className="text-emerald-600" />} value={realWorkOrderCounts.completed || (numberCards?.work_orders_completed ?? 0)} label={t('dashboard.closedWorkOrders')} bgColor="bg-emerald-50 dark:bg-emerald-900/20" iconColor="text-emerald-600" href="/asm_app/work-orders?status=Closed" />
                <StatCard icon={<FaBan className="text-red-500" />} value={realWorkOrderCounts.rejected} label={t('dashboard.rejectedWorkOrders', 'Rejected WOs')} bgColor="bg-red-50 dark:bg-red-900/20" iconColor="text-red-500" href="/asm_app/work-orders?status=Rejected" />
                <StatCard icon={<FaChartLine className="text-purple-600" />} value={realWorkOrderCounts.total} label={t('dashboard.totalWorkOrders')} bgColor="bg-purple-50 dark:bg-purple-900/20" iconColor="text-purple-600" href="/asm_app/work-orders" />
              </div>
            </div>
          </div>

          {/* ── WO Status Distribution — right 5 cols, spans rows 1 + 2 ── */}
          <div className="col-span-12 lg:col-span-5 lg:row-span-2 flex">
            <DepartmentSalesCard
              className="flex-1 w-full"
              data={workOrderChartData || workOrderChart}
              totalWorkOrders={realWorkOrderCounts.total}
              completedWorkOrders={realWorkOrderCounts.completed}
              onOpenReport={() => setChartDetail({ title: 'Work Order Status Distribution', data: workOrderChartData || workOrderChart, redirectContext: 'wo_status' })}
            />
          </div>

          {/* ── Workflow Completion Rate — left 7 cols, row 2 ── */}
          <div className="col-span-12 lg:col-span-7 flex">
            <CompletionRateCard
              className="flex-1 w-full"
              totalWorkOrders={realWorkOrderCounts.total}
              completedWorkOrders={realWorkOrderCounts.wfCompleted}
              inProgressWorkOrders={realWorkOrderCounts.wfInProgress}
              rejectedWorkOrders={realWorkOrderCounts.wfRejected}
              byTypeChartData={completionByTypeChartData}
              onOpenReport={() => {
                const rates = completionByTypeChartData?.rates || [];
                setChartDetail({
                  title: t('dashboard.completionRate', 'Completion Rate by Department'),
                  data: {
                    labels: rates.map((r: any) => r.type),
                    datasets: [
                      { name: 'Completion Rate (%)', values: rates.map((r: any) => parseFloat(r.rate.toFixed(2))) },
                      { name: 'WF Completed', values: rates.map((r: any) => r.wfCompleted) },
                      { name: 'In Progress', values: rates.map((r: any) => r.wfInProgress) },
                      { name: 'Rejected (WF)', values: rates.map((r: any) => r.wfRejected) },
                      { name: 'Closed WOs', values: rates.map((r: any) => r.closed) },
                      { name: 'Pending Review', values: rates.map((r: any) => r.pendingReview) },
                      { name: 'Open', values: rates.map((r: any) => r.open) },
                      { name: 'Total', values: rates.map((r: any) => r.total) },
                    ],
                    hideFooterTotal: true
                  }
                });
              }}
            />
          </div>

          {/* ── Overall Completion Rate (repair_status) — left 7 cols, row 3 ── */}
          <div className="col-span-12 lg:col-span-7 flex">
            <RepairStatusCompletionCard
              className="flex-1 w-full"
              totalWorkOrders={realWorkOrderCounts.total}
              closedWorkOrders={realWorkOrderCounts.completed}
              inProgressWorkOrders={realWorkOrderCounts.inProgress}
              rejectedWorkOrders={realWorkOrderCounts.rejected}
              byTypeChartData={completionByTypeChartData}
              onOpenReport={() => {
                const rates = completionByTypeChartData?.rates || [];
                setChartDetail({
                  title: 'Overall Completion Rate by Department',
                  data: {
                    labels: rates.map((r: any) => r.type),
                    datasets: [
                      { name: 'Completion Rate (%)', values: rates.map((r: any) => parseFloat(((r.closed / (r.total || 1)) * 100).toFixed(2))) },
                      { name: 'Closed WOs', values: rates.map((r: any) => r.closed) },
                      { name: 'In Progress', values: rates.map((r: any) => r.inProgress) },
                      { name: 'Rejected', values: rates.map((r: any) => r.rejected) },
                      { name: 'Total WOs', values: rates.map((r: any) => r.total) },
                    ],
                    hideFooterTotal: true
                  }
                });
              }}
            />
          </div>

          {/* ── Asset UP & Down — right 5 cols, row 3 ── */}
          <div className="col-span-12 lg:col-span-5 flex">
            <AssetUpDownCard
              className="flex-1 w-full"
              data={assetDeviceStatusChartData}
              totalAssets={assets?.length ?? 0}
              onOpenReport={() => setShowAssetReport(true)}
            />
          </div>

        </div>

        {/* ── INSIGHTS ROW (25 / 25 / 25 / 25) ─────────────────────── */}
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-5">
          <InsightCard
            icon={<FaExclamationTriangle className="text-red-500" />}
            title={t('dashboard.assetsDown', 'Assets Down')}
            value={insights.assetsDown}
            trend={insights.assetsDown === 0 ? 'All Operational' : insights.assetsDown <= 3 ? 'Low' : 'High Priority'}
            trendUp={insights.assetsDown === 0}
            bgColor="bg-red-50 dark:bg-red-900/20"
          />
          <InsightCard
            icon={<FaClock className="text-blue-500" />}
            title={t('dashboard.avgResponseTime')}
            value={insights.avgResponseTime > 0 ? `${insights.avgResponseTime.toFixed(1)} hrs` : 'N/A'}
            trend={insights.avgResponseTime > 0 && insights.avgResponseTime < 4 ? 'Fast Response' : 'Monitor'}
            trendUp={insights.avgResponseTime > 0 && insights.avgResponseTime < 4}
            bgColor="bg-blue-50 dark:bg-blue-900/20"
          />
          <InsightCard
            icon={<FaTools className="text-orange-500" />}
            title={t('dashboard.maintenanceEfficiency')}
            value={`${insights.maintenanceEfficiency.toFixed(1)}%`}
            trend={insights.maintenanceEfficiency >= 70 ? 'On Track' : 'Needs Attention'}
            trendUp={insights.maintenanceEfficiency >= 70}
            bgColor="bg-orange-50 dark:bg-orange-900/20"
          />
          <InsightCard
            icon={<FaExclamationTriangle className="text-rose-500" />}
            title={t('dashboard.overdueMaintenance')}
            value={insights.overdueTasks}
            trend={insights.overdueTasks === 0 ? 'All Clear' : insights.overdueTasks <= 3 ? 'Low' : 'High Priority'}
            trendUp={insights.overdueTasks <= 3}
            bgColor="bg-rose-50 dark:bg-rose-900/20"
          />
        </div>

        {/* ── WO STATUS BY TYPE + ASSIGNEES (50 / 50) ───────────────── */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
          <GroupedChartCard
            title={t('dashboard.workOrderStatus')}
            data={workOrderGroupedChartData || workOrderChart}
            onOpenReport={() => setChartDetail({ title: t('dashboard.workOrderStatus'), data: workOrderGroupedChartData || workOrderChart, redirectContext: 'wo_type' })}
          />
          <GroupedChartCard
            title={t('dashboard.assigneesStatus')}
            data={assigneesGroupedChartData || assigneesChart}
            onOpenReport={() => setChartDetail({ title: t('dashboard.assigneesStatus'), data: assigneesGroupedChartData || assigneesChart })}
            showSummary
          />
        </div>

        {/* ── TECHNICIAN CHARTS (50 / 50) ───────────────────────────── */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
          <TechnicianHoursChartCard
            title={t('dashboard.technicianWorkingHours', 'Technicians Working Hours')}
            data={technicianHoursData}
            onOpenReport={() => setShowTechnicianHoursReport(true)}
          />
          <TechnicianWorkedChartCard
            title={t('dashboard.techniciansWorked', 'Technicians Work Summary')}
            data={technicianWorkedData}
            onOpenReport={() => setShowTechnicianWorkOrderReport(true)}
          />
        </div>

        {/* ── INSPECTION & REJECTION (50 / 50, role-gated) ──────────── */}
        {canSeeInspectionRejection && (
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
            <InspectionSummaryChartCard
              title={t('dashboard.inspectionLinkedWOSummary', 'Inspection Linked Work Orders Summary')}
              data={inspectionSummaryData}
              onOpenReport={() => setShowInspectionReport(true)}
            />
            <RejectionSummaryChartCard
              title={t('dashboard.woRejectionSummary', 'WO Rejection Summary')}
              data={rejectionSummaryData}
              onOpenReport={() => setShowRejectionReport(true)}
            />
          </div>
        )}

        {/* ── TIME TO REPAIR + MAINTENANCE OVERVIEW (50 / 50, role-gated) */}
        {canSeeTimeToRepair && (
          <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
            <TimeToRepairCard
              data={timeToRepairData}
              onOpenReport={() => setShowTimeToRepairReport(true)}
            />
            <MaintenanceOverviewCard
              insights={insights}
              maintenanceLogs={maintenanceLogs || []}
            />
          </div>
        )}

      </div>

      {/* ── Modals ──────────────────────────────────────────────────── */}
      <TechnicianWorkingHoursReportModal
        isOpen={showTechnicianHoursReport}
        onClose={() => setShowTechnicianHoursReport(false)}
        permittedIssueTypes={permittedIssueTypes}
        isAdmin={isWoAdmin}
        defaultWorkOrderType={selectedIssueType}
      />
      <TechnicianWorkOrderSummaryReportModal
        isOpen={showTechnicianWorkOrderReport}
        onClose={() => setShowTechnicianWorkOrderReport(false)}
        permittedIssueTypes={permittedIssueTypes}
        isAdmin={isWoAdmin}
        defaultWorkOrderType={selectedIssueType}
      />
      {canSeeInspectionRejection && (
        <InspectionSummaryReportModal
          isOpen={showInspectionReport}
          onClose={() => setShowInspectionReport(false)}
          permittedIssueTypes={permittedIssueTypes}
          isAdmin={isWoAdmin}
          defaultWorkOrderType={selectedIssueType}
        />
      )}
      {canSeeInspectionRejection && (
        <RejectionSummaryReportModal
          isOpen={showRejectionReport}
          onClose={() => setShowRejectionReport(false)}
          permittedIssueTypes={permittedIssueTypes}
          isAdmin={isWoAdmin}
          defaultWorkOrderType={selectedIssueType}
        />
      )}
      {canSeeTimeToRepair && (
        <TimeToRepairReportModal
          isOpen={showTimeToRepairReport}
          onClose={() => setShowTimeToRepairReport(false)}
          permittedIssueTypes={permittedIssueTypes}
          isAdmin={isWoAdmin}
          defaultWorkOrderType={selectedIssueType}
        />
      )}
      <AssetStatusReportModal
        isOpen={showAssetReport}
        onClose={() => setShowAssetReport(false)}
        assets={assets || []}
        chartData={assetDeviceStatusChartData}
      />
      <ChartDetailModal
        isOpen={!!chartDetail}
        onClose={() => setChartDetail(null)}
        title={chartDetail?.title || ''}
        data={chartDetail?.data}
        redirectContext={chartDetail?.redirectContext}
      />
    </div>
  );
};

// ─── StatCard ─────────────────────────────────────────────────────────────────
const StatCard: React.FC<{
  icon: React.ReactNode;
  value: string | number;
  label: string;
  bgColor: string;
  iconColor?: string;
  href?: string;
}> = ({ icon, value, label, bgColor, href }) => {
  const handleClick = () => { if (href) window.location.href = href; };
  return (
    <div
      className={`text-center py-3 px-2 last:border-r-0 ${href ? 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors rounded-lg group' : ''}`}
      onClick={href ? handleClick : undefined}
      title={href ? `View ${label}` : undefined}
    >
      <div className={`w-10 h-10 ${bgColor} rounded-xl flex items-center justify-center text-base mx-auto mb-2 ${href ? 'group-hover:scale-105 transition-transform' : ''}`}>
        {icon}
      </div>
      <div className="text-xl font-bold text-gray-900 dark:text-white leading-none mb-1">{value}</div>
      <div className="text-[9px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide leading-tight px-1">{label}</div>
      {href && <div className="text-[8px] text-indigo-400 dark:text-indigo-500 opacity-0 group-hover:opacity-100 transition-opacity mt-0.5">View →</div>}
    </div>
  );
};

// ─── InsightCard ──────────────────────────────────────────────────────────────
const InsightCard: React.FC<{
  icon: React.ReactNode;
  title: string;
  value: string | number;
  trend: string;
  trendUp: boolean;
  bgColor: string;
}> = ({ icon, title, value, trend, trendUp, bgColor }) => (
  <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-4 border border-gray-200 dark:border-gray-700">
    <div className="flex items-start justify-between mb-3">
      <div className={`w-10 h-10 ${bgColor} rounded-xl flex items-center justify-center text-lg`}>{icon}</div>
      <div className={`flex items-center gap-1 text-xs font-semibold px-2 py-1 rounded-full ${trendUp ? 'text-emerald-700 bg-emerald-50 dark:text-emerald-400 dark:bg-emerald-900/20' : 'text-red-700 bg-red-50 dark:text-red-400 dark:bg-red-900/20'}`}>
        {trendUp ? <FaArrowUp className="text-[9px]" /> : <FaArrowDown className="text-[9px]" />}
        {trend}
      </div>
    </div>
    <div className="text-2xl font-bold text-gray-900 dark:text-white mb-1">{value}</div>
    <div className="text-xs font-medium text-gray-500 dark:text-gray-400">{title}</div>
  </div>
);

// ─── CompletionRateCard ───────────────────────────────────────────────────────
// Footer now shows: Total | In Progress | Rejected (WF) | WF Completed
const CompletionRateCard: React.FC<{
  totalWorkOrders: number;
  completedWorkOrders: number;
  inProgressWorkOrders: number;
  rejectedWorkOrders: number;
  byTypeChartData: any;
  onOpenReport?: () => void;
  className?: string;
}> = ({ totalWorkOrders, completedWorkOrders, inProgressWorkOrders, rejectedWorkOrders, byTypeChartData, onOpenReport, className = '' }) => {
  const { t } = useTranslation();
  const completionRate = totalWorkOrders > 0 ? ((completedWorkOrders / totalWorkOrders) * 100).toFixed(2) : '0.00';

  return (
    <div className={`bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all px-5 py-4 border border-gray-200 dark:border-gray-700 flex flex-col h-full ${className}`}>
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 bg-indigo-50 dark:bg-indigo-900/20 rounded-xl flex items-center justify-center">
            <FaChartLine className="text-indigo-600 text-base" />
          </div>
          <div>
            <div className="text-2xl font-bold text-gray-900 dark:text-white">{completionRate}%</div>
            <div className="text-xs font-semibold text-indigo-600 dark:text-indigo-400 uppercase tracking-wide">
              {t('dashboard.completionRate', 'Workflow Completion Rate')}
            </div>
          </div>
        </div>
        {onOpenReport && (
          <button onClick={onOpenReport} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" title="View Detail">
            <FaExternalLinkAlt className="text-gray-400 text-xs" />
          </button>
        )}
      </div>

      {byTypeChartData && byTypeChartData.rates?.length > 0 ? (
        <CompletionByTypeBarChart data={byTypeChartData} />
      ) : (
        <div className="h-28 flex items-center justify-center text-gray-400 text-xs">{t('dashboard.noDataAvailable', 'No data available')}</div>
      )}

      {/* Footer: Total | In Progress | Rejected | WF Completed */}
      <div className="grid grid-cols-4 gap-3 mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
        <div className="text-center">
          <div className="text-lg font-bold text-indigo-600 dark:text-indigo-400">{totalWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Total</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-blue-600 dark:text-blue-400">{inProgressWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">In Progress</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-red-600 dark:text-red-400">{rejectedWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Rejected</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-emerald-600 dark:text-emerald-400">{completedWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Completed</div>
        </div>
      </div>
    </div>
  );
};

// ─── CompletionByTypeBarChart ─────────────────────────────────────────────────
const CompletionByTypeBarChart: React.FC<{ data: any }> = ({ data }) => {
  const { t } = useTranslation();
  const [hoveredIdx, setHoveredIdx] = React.useState<number | null>(null);
  const containerRef = React.useRef<HTMLDivElement>(null);
  const [tooltipPos, setTooltipPos] = React.useState<{ x: number; y: number } | null>(null);

  const rates = (data?.rates || []).filter((item: any) => !isNullOrUnknownLabel(item.type));

  if (!rates.length) {
    return <div className="h-28 flex items-center justify-center text-gray-400 text-xs">{t('dashboard.noDataAvailable', 'No data available')}</div>;
  }

  const typeColors = generateColors(rates.length);
  const chartH = 110;
  const paddingLeft = 32, paddingRight = 12, paddingTop = 10, paddingBottom = 28;
  const innerH = chartH - paddingTop - paddingBottom;
  const numBars = rates.length;
  const svgW = Math.max(260, numBars * 72 + paddingLeft + paddingRight);
  const innerW = svgW - paddingLeft - paddingRight;
  const groupW = innerW / numBars;
  const barW = Math.min(44, groupW * 0.55);
  const gridRatios = [0, 0.25, 0.5, 0.75, 1];

  const handleMouseEnter = (idx: number, e: React.MouseEvent<SVGGElement>) => {
    setHoveredIdx(idx);
    if (containerRef.current) {
      const containerRect = containerRef.current.getBoundingClientRect();
      const svgEl = e.currentTarget.ownerSVGElement as SVGSVGElement;
      const svgRect = svgEl.getBoundingClientRect();
      const scaleX = svgRect.width / svgW;
      const barCentrePixel = svgRect.left - containerRect.left + (paddingLeft + idx * groupW + groupW / 2) * scaleX;
      setTooltipPos({ x: barCentrePixel, y: 0 });
    }
  };

  return (
    <div className="w-full relative" ref={containerRef}>
      <div className="overflow-x-auto">
        <svg width="100%" height={chartH} viewBox={`0 0 ${svgW} ${chartH}`} preserveAspectRatio="xMidYMid meet" className="w-full"
          onMouseLeave={() => { setHoveredIdx(null); setTooltipPos(null); }}>
          {gridRatios.map((ratio, i) => {
            const y = paddingTop + innerH - ratio * innerH;
            return (
              <g key={i}>
                <line x1={paddingLeft} y1={y} x2={svgW - paddingRight} y2={y} stroke="#E5E7EB" strokeWidth="1" />
                <text x={paddingLeft - 3} y={y + 3} textAnchor="end" fontSize="7" fill="#9CA3AF">{Math.round(ratio * 100)}%</text>
              </g>
            );
          })}
          <line x1={paddingLeft} y1={paddingTop + innerH} x2={svgW - paddingRight} y2={paddingTop + innerH} stroke="#D1D5DB" strokeWidth="1" />
          {rates.map((item: any, idx: number) => {
            const barH = Math.max(0, (item.rate / 100) * innerH);
            const cx = paddingLeft + idx * groupW + groupW / 2;
            const bX = cx - barW / 2;
            const bY = paddingTop + innerH - barH;
            const color = typeColors[idx];
            const isHovered = hoveredIdx === idx;
            return (
              <g key={idx} onMouseEnter={(e) => handleMouseEnter(idx, e)} style={{ cursor: 'pointer' }}>
                <rect x={paddingLeft + idx * groupW} y={paddingTop} width={groupW} height={innerH} fill="transparent" />
                <rect x={bX} y={barH > 0 ? bY : paddingTop + innerH - 1} width={barW} height={barH > 0 ? barH : 1} fill={color} rx="4" ry="4"
                  opacity={isHovered ? 1 : 0.8} style={{ transition: 'opacity 0.15s, filter 0.15s', filter: isHovered ? 'brightness(1.15)' : 'none' }} />
                {barH > 14 && <text x={cx} y={bY - 3} textAnchor="middle" fontSize="7.5" fontWeight="700" fill={color}>{item.rate.toFixed(1)}%</text>}
                <text x={cx} y={paddingTop + innerH + 12} textAnchor="middle" fontSize="6.5" fill={isHovered ? color : '#6B7280'} fontWeight={isHovered ? '700' : '400'}>
                  {(item.type || '').length > 11 ? (item.type || '').substring(0, 9) + '…' : (item.type || '')}
                </text>
              </g>
            );
          })}
        </svg>
      </div>
      {hoveredIdx !== null && tooltipPos && rates[hoveredIdx] && (() => {
        const item = rates[hoveredIdx];
        const color = typeColors[hoveredIdx];
        return (
          <div className="absolute pointer-events-none z-30" style={{ left: tooltipPos.x, top: 4, transform: 'translateX(-50%)', minWidth: 160 }}>
            <div className="bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-xl shadow-2xl px-3 py-2">
              <div className="flex items-center gap-1.5 mb-1 pb-1 border-b border-white/20">
                <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: color }} />
                <span className="font-semibold text-[11px] truncate max-w-[120px]">{item.type}</span>
              </div>
              <div className="text-green-400 font-bold text-sm text-center mb-0.5">WF: {item.rate.toFixed(2)}%</div>
              <div className="text-gray-300 text-[10px] text-center">
                {item.wfCompleted} done · {item.wfInProgress} prog · {item.wfRejected} rej
              </div>
            </div>
            <div className="w-2.5 h-2.5 bg-gray-900 dark:bg-gray-700 rotate-45 mx-auto -mt-1.5" />
          </div>
        );
      })()}
      <div className="flex flex-wrap items-center gap-x-3 gap-y-1 mt-2 pt-2 border-t border-gray-100 dark:border-gray-700">
        {rates.map((item: any, idx: number) => (
          <div key={idx} className="flex items-center gap-1.5">
            <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[idx] }} />
            <span className="text-[10px] text-gray-500 dark:text-gray-400">{(item.type || '').length > 22 ? (item.type || '').substring(0, 20) + '…' : (item.type || '')}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── RepairStatusCompletionCard ───────────────────────────────────────────────
// Footer now shows: Total | In Progress | Rejected | Closed (Completed)
const RepairStatusCompletionCard: React.FC<{
  totalWorkOrders: number;
  closedWorkOrders: number;
  inProgressWorkOrders: number;
  rejectedWorkOrders: number;
  byTypeChartData: any;
  onOpenReport?: () => void;
  className?: string;
}> = ({ totalWorkOrders, closedWorkOrders, inProgressWorkOrders, rejectedWorkOrders, byTypeChartData, onOpenReport, className = '' }) => {
  const { t } = useTranslation();
  const completionRate = totalWorkOrders > 0 ? ((closedWorkOrders / totalWorkOrders) * 100).toFixed(2) : '0.00';

  return (
    <div className={`bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all px-5 py-4 border border-gray-200 dark:border-gray-700 flex flex-col h-full ${className}`}>
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 bg-emerald-50 dark:bg-emerald-900/20 rounded-xl flex items-center justify-center">
            <FaCheckCircle className="text-emerald-600 text-base" />
          </div>
          <div>
            <div className="text-2xl font-bold text-gray-900 dark:text-white">{completionRate}%</div>
            <div className="text-xs font-semibold text-emerald-600 dark:text-emerald-400 uppercase tracking-wide">Overall Completion Rate</div>
          </div>
        </div>
        {onOpenReport && (
          <button onClick={onOpenReport} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" title="View Detail">
            <FaExternalLinkAlt className="text-gray-400 text-xs" />
          </button>
        )}
      </div>

      {byTypeChartData && byTypeChartData.rates?.length > 0 ? (
        <RepairStatusCompletionBarChart data={byTypeChartData} />
      ) : (
        <div className="h-28 flex items-center justify-center text-gray-400 text-xs">{t('dashboard.noDataAvailable', 'No data available')}</div>
      )}

      {/* Footer: Total | In Progress | Rejected | Closed */}
      <div className="grid grid-cols-4 gap-3 mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
        <div className="text-center">
          <div className="text-lg font-bold text-indigo-600 dark:text-indigo-400">{totalWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Total</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-blue-600 dark:text-blue-400">{inProgressWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">In Progress</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-red-600 dark:text-red-400">{rejectedWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Rejected</div>
        </div>
        <div className="text-center">
          <div className="text-lg font-bold text-emerald-600 dark:text-emerald-400">{closedWorkOrders}</div>
          <div className="text-[9px] font-semibold text-gray-400 uppercase tracking-wide">Completed</div>
        </div>
      </div>
    </div>
  );
};

// ─── RepairStatusCompletionBarChart ──────────────────────────────────────────
const RepairStatusCompletionBarChart: React.FC<{ data: any }> = ({ data }) => {
  const { t } = useTranslation();
  const [hoveredIdx, setHoveredIdx] = React.useState<number | null>(null);
  const containerRef = React.useRef<HTMLDivElement>(null);
  const [tooltipPos, setTooltipPos] = React.useState<{ x: number; y: number } | null>(null);

  const allRates = ((data?.rates || []) as Array<{ type: string; total: number; closed: number; inProgress: number; rejected: number }>)
    .filter((item) => !isNullOrUnknownLabel(item.type));

  if (!allRates.length) {
    return <div className="h-28 flex items-center justify-center text-gray-400 text-xs">{t('dashboard.noDataAvailable', 'No data available')}</div>;
  }

  const rates = allRates.map(item => ({
    type: item.type, total: item.total, closed: item.closed,
    inProgress: item.inProgress, rejected: item.rejected,
    rate: item.total > 0 ? (item.closed / item.total) * 100 : 0,
  }));

  const typeColors = generateColors(rates.length);
  const chartH = 110;
  const paddingLeft = 32, paddingRight = 12, paddingTop = 10, paddingBottom = 28;
  const innerH = chartH - paddingTop - paddingBottom;
  const numBars = rates.length;
  const svgW = Math.max(260, numBars * 72 + paddingLeft + paddingRight);
  const innerW = svgW - paddingLeft - paddingRight;
  const groupW = innerW / numBars;
  const barW = Math.min(44, groupW * 0.55);
  const gridRatios = [0, 0.25, 0.5, 0.75, 1];

  const handleMouseEnter = (idx: number, e: React.MouseEvent<SVGGElement>) => {
    setHoveredIdx(idx);
    if (containerRef.current) {
      const containerRect = containerRef.current.getBoundingClientRect();
      const svgEl = e.currentTarget.ownerSVGElement as SVGSVGElement;
      const svgRect = svgEl.getBoundingClientRect();
      const scaleX = svgRect.width / svgW;
      const barCentrePixel = svgRect.left - containerRect.left + (paddingLeft + idx * groupW + groupW / 2) * scaleX;
      setTooltipPos({ x: barCentrePixel, y: 0 });
    }
  };

  return (
    <div className="w-full relative" ref={containerRef}>
      <div className="overflow-x-auto">
        <svg width="100%" height={chartH} viewBox={`0 0 ${svgW} ${chartH}`} preserveAspectRatio="xMidYMid meet" className="w-full"
          onMouseLeave={() => { setHoveredIdx(null); setTooltipPos(null); }}>
          {gridRatios.map((ratio, i) => {
            const y = paddingTop + innerH - ratio * innerH;
            return (
              <g key={i}>
                <line x1={paddingLeft} y1={y} x2={svgW - paddingRight} y2={y} stroke="#E5E7EB" strokeWidth="1" />
                <text x={paddingLeft - 3} y={y + 3} textAnchor="end" fontSize="7" fill="#9CA3AF">{Math.round(ratio * 100)}%</text>
              </g>
            );
          })}
          <line x1={paddingLeft} y1={paddingTop + innerH} x2={svgW - paddingRight} y2={paddingTop + innerH} stroke="#D1D5DB" strokeWidth="1" />
          {rates.map((item, idx) => {
            const barH = Math.max(0, (item.rate / 100) * innerH);
            const cx = paddingLeft + idx * groupW + groupW / 2;
            const bX = cx - barW / 2;
            const bY = paddingTop + innerH - barH;
            const color = typeColors[idx];
            const isHovered = hoveredIdx === idx;
            return (
              <g key={idx} onMouseEnter={(e) => handleMouseEnter(idx, e)} style={{ cursor: 'pointer' }}>
                <rect x={paddingLeft + idx * groupW} y={paddingTop} width={groupW} height={innerH} fill="transparent" />
                <rect x={bX} y={barH > 0 ? bY : paddingTop + innerH - 1} width={barW} height={barH > 0 ? barH : 1} fill={color} rx="4" ry="4"
                  opacity={isHovered ? 1 : 0.8} style={{ transition: 'opacity 0.15s, filter 0.15s', filter: isHovered ? 'brightness(1.15)' : 'none' }} />
                {barH > 14 && <text x={cx} y={bY - 3} textAnchor="middle" fontSize="7.5" fontWeight="700" fill={color}>{item.rate.toFixed(1)}%</text>}
                <text x={cx} y={paddingTop + innerH + 12} textAnchor="middle" fontSize="6.5" fill={isHovered ? color : '#6B7280'} fontWeight={isHovered ? '700' : '400'}>
                  {(item.type || '').length > 11 ? (item.type || '').substring(0, 9) + '…' : (item.type || '')}
                </text>
              </g>
            );
          })}
        </svg>
      </div>
      {hoveredIdx !== null && tooltipPos && rates[hoveredIdx] && (() => {
        const item = rates[hoveredIdx];
        const color = typeColors[hoveredIdx];
        return (
          <div className="absolute pointer-events-none z-30" style={{ left: tooltipPos.x, top: 4, transform: 'translateX(-50%)', minWidth: 160 }}>
            <div className="bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-xl shadow-2xl px-3 py-2">
              <div className="flex items-center gap-1.5 mb-1 pb-1 border-b border-white/20">
                <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: color }} />
                <span className="font-semibold text-[11px] truncate max-w-[120px]">{item.type}</span>
              </div>
              <div className="text-green-400 font-bold text-sm text-center mb-0.5">{item.rate.toFixed(2)}% Closed</div>
              <div className="text-gray-300 text-[10px] text-center">
                {item.closed} closed · {item.inProgress} prog · {item.rejected} rej
              </div>
              <div className="text-gray-400 text-[10px] text-center">{item.total} total</div>
            </div>
            <div className="w-2.5 h-2.5 bg-gray-900 dark:bg-gray-700 rotate-45 mx-auto -mt-1.5" />
          </div>
        );
      })()}
      <div className="flex flex-wrap items-center gap-x-3 gap-y-1 mt-2 pt-2 border-t border-gray-100 dark:border-gray-700">
        {rates.map((item, idx) => (
          <div key={idx} className="flex items-center gap-1.5">
            <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[idx] }} />
            <span className="text-[10px] text-gray-500 dark:text-gray-400">{(item.type || '').length > 22 ? (item.type || '').substring(0, 20) + '…' : (item.type || '')}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── MaintenanceOverviewCard ───────────────────────────────────────────────────
const MaintenanceOverviewCard: React.FC<{
  insights: { assetsDown: number; avgResponseTime: number; maintenanceEfficiency: number; overdueTasks: number; plannedMaintenance: number };
  maintenanceLogs: any[];
}> = ({ insights, maintenanceLogs }) => {
  const completed = React.useMemo(() => maintenanceLogs.filter(l => l.maintenance_status?.toLowerCase() === 'completed').length, [maintenanceLogs]);
  const total = maintenanceLogs.length;

  const kpis = [
    { label: 'Total Logs', value: total, color: 'bg-indigo-50 dark:bg-indigo-900/20', textColor: 'text-indigo-600 dark:text-indigo-400' },
    { label: 'Planned', value: insights.plannedMaintenance, color: 'bg-blue-50 dark:bg-blue-900/20', textColor: 'text-blue-600 dark:text-blue-400' },
    { label: 'Completed', value: completed, color: 'bg-emerald-50 dark:bg-emerald-900/20', textColor: 'text-emerald-600 dark:text-emerald-400' },
    { label: 'Overdue', value: insights.overdueTasks, color: 'bg-red-50 dark:bg-red-900/20', textColor: 'text-red-600 dark:text-red-400' },
  ];

  const efficiency = Math.min(insights.maintenanceEfficiency, 100);
  const efficiencyColor = efficiency >= 70 ? '#10B981' : efficiency >= 40 ? '#F59E0B' : '#EF4444';

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700 flex flex-col">
      <div className="flex items-center gap-3 mb-4">
        <div className="w-10 h-10 bg-orange-50 dark:bg-orange-900/20 rounded-xl flex items-center justify-center">
          <FaCalendarCheck className="text-orange-500 text-base" />
        </div>
        <div>
          <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Maintenance Overview</h3>
          <p className="text-xs text-gray-400">{total} total maintenance logs</p>
        </div>
      </div>
      <div className="grid grid-cols-2 gap-3 mb-4">
        {kpis.map((kpi, i) => (
          <div key={i} className={`${kpi.color} rounded-xl p-3 text-center`}>
            <div className={`text-2xl font-bold ${kpi.textColor}`}>{kpi.value}</div>
            <div className="text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mt-0.5">{kpi.label}</div>
          </div>
        ))}
      </div>
      <div className="mt-auto space-y-2">
        <div className="flex justify-between items-center text-xs mb-1">
          <span className="font-semibold text-gray-600 dark:text-gray-300">Maintenance Efficiency</span>
          <span className="font-bold" style={{ color: efficiencyColor }}>{insights.maintenanceEfficiency.toFixed(1)}%</span>
        </div>
        <div className="h-3 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
          <div className="h-full rounded-full transition-all duration-700" style={{ width: `${efficiency}%`, backgroundColor: efficiencyColor }} />
        </div>
        <div className="flex justify-between text-[10px] text-gray-400 mt-1">
          <span>0%</span>
          <span className={efficiency >= 70 ? 'text-emerald-500' : 'text-amber-500'}>{efficiency >= 70 ? '✓ On Track' : 'Needs Attention'}</span>
          <span>100%</span>
        </div>
      </div>
      <div className="mt-3 pt-3 border-t border-gray-100 dark:border-gray-700 flex items-center justify-between">
        <div className="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400">
          <FaClock className="text-blue-400" />
          <span>Avg Response Time</span>
        </div>
        <span className="text-sm font-bold text-blue-600 dark:text-blue-400">
          {insights.avgResponseTime > 0 ? `${insights.avgResponseTime.toFixed(1)} hrs` : 'N/A'}
        </span>
      </div>
    </div>
  );
};

// ─── DepartmentSalesCard ──────────────────────────────────────────────────────
const DepartmentSalesCard: React.FC<{
  data: any;
  totalWorkOrders: number;
  completedWorkOrders: number;
  onOpenReport?: () => void;
  className?: string;
}> = ({ data, totalWorkOrders, completedWorkOrders, onOpenReport, className = '' }) => {
  const { t } = useTranslation();
  return (
    <div className={`bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all px-5 py-5 border border-gray-200 dark:border-gray-700 flex flex-col h-full ${className}`}>
      <div className="flex items-center justify-between mb-4 flex-shrink-0">
        <div>
          <h3 className="text-base font-semibold text-gray-900 dark:text-white">Work Order Status Distribution</h3>
          <div className="text-2xl font-bold text-gray-900 dark:text-white mt-1">{totalWorkOrders} <span className="text-sm font-medium text-gray-500">Total</span></div>
        </div>
        <button onClick={onOpenReport} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" title={t('dashboard.viewFullReport')}>
          <FaExternalLinkAlt className="w-4 h-4 text-gray-400" />
        </button>
      </div>
      <div className="flex-1">
        {data && (data?.labels?.length || data?.datasets?.[0]?.values?.length) ? (
          <PieChart data={data} />
        ) : (
          <div className="h-48 flex items-center justify-center text-gray-400 text-sm">{t('dashboard.noDataAvailable')}</div>
        )}
      </div>
    </div>
  );
};

// ─── AssetUpDownCard ──────────────────────────────────────────────────────────
// Now accepts onOpenReport to show the asset status report modal
const AssetUpDownCard: React.FC<{
  data: any;
  totalAssets: number;
  onOpenReport?: () => void;
  className?: string;
}> = ({ data, totalAssets, onOpenReport, className = '' }) => {
  return (
    <div className={`bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all px-5 py-5 border border-gray-200 dark:border-gray-700 flex flex-col h-full ${className}`}>
      <div className="flex items-center justify-between mb-4 flex-shrink-0">
        <div>
          <h3 className="text-base font-semibold text-gray-900 dark:text-white">Asset UP &amp; Down</h3>
          <div className="text-2xl font-bold text-gray-900 dark:text-white mt-1">
            {totalAssets} <span className="text-sm font-medium text-gray-500">Total</span>
          </div>
        </div>
        {onOpenReport && (
          <button
            onClick={onOpenReport}
            className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            title="View Asset Status Report"
          >
            <FaExternalLinkAlt className="w-4 h-4 text-gray-400" />
          </button>
        )}
      </div>
      <div className="flex-1">
        {data && data?.labels?.length ? (
          <PieChart data={data} />
        ) : (
          <div className="h-48 flex items-center justify-center text-gray-400 text-sm">No asset status data</div>
        )}
      </div>
    </div>
  );
};

// ─── AssetStatusReportModal ───────────────────────────────────────────────────
// Reads directly from chartData (labels + values + colors) — no raw asset
// iteration, so it works regardless of asset field names.
// Each status card is clickable and navigates to the asset list with a filter.
const AssetStatusReportModal: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  assets: any[];       // kept in props for total count only
  chartData: any;      // { labels, datasets[0].values, datasets[0].colors, total }
}> = ({ isOpen, onClose, assets, chartData }) => {
  if (!isOpen) return null;

  const labels: string[] = chartData?.labels || [];
  const values: number[] = chartData?.datasets?.[0]?.values || [];
  const colors: string[] = chartData?.datasets?.[0]?.colors || generateColors(labels.length);
  const total: number = chartData?.total ?? assets?.length ?? values.reduce((s, v) => s + v, 0);

  // Semantic style per status label
  const statusStyle = (label: string): { border: string; bg: string; text: string; badge: string } => {
    const l = label.toLowerCase();
    if (l === 'up')                 return { border: 'border-emerald-200 dark:border-emerald-700', bg: 'bg-emerald-50 dark:bg-emerald-900/20', text: 'text-emerald-700 dark:text-emerald-300', badge: 'bg-emerald-100 dark:bg-emerald-800 text-emerald-700 dark:text-emerald-200' };
    if (l === 'down')               return { border: 'border-red-200 dark:border-red-700',     bg: 'bg-red-50 dark:bg-red-900/20',         text: 'text-red-700 dark:text-red-300',         badge: 'bg-red-100 dark:bg-red-800 text-red-700 dark:text-red-200' };
    if (l.includes('maintenance'))  return { border: 'border-amber-200 dark:border-amber-700', bg: 'bg-amber-50 dark:bg-amber-900/20',     text: 'text-amber-700 dark:text-amber-300',     badge: 'bg-amber-100 dark:bg-amber-800 text-amber-700 dark:text-amber-200' };
    if (l.includes('decommission')) return { border: 'border-gray-200 dark:border-gray-600',   bg: 'bg-gray-50 dark:bg-gray-700/30',       text: 'text-gray-600 dark:text-gray-400',       badge: 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300' };
    return { border: 'border-indigo-200 dark:border-indigo-700', bg: 'bg-indigo-50 dark:bg-indigo-900/20', text: 'text-indigo-700 dark:text-indigo-300', badge: 'bg-indigo-100 dark:bg-indigo-800 text-indigo-700 dark:text-indigo-200' };
  };

  const handleStatusClick = (label: string) => {
    const url = `/asm_app/assets?device_status=${encodeURIComponent(label)}`;
    window.location.href = url;
  };

  const handleViewAll = () => {
    window.location.href = '/asm_app/assets';
  };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl w-full max-w-lg overflow-hidden flex flex-col">

        {/* ── Header ── */}
        <div className="bg-gradient-to-r from-teal-500 to-emerald-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-3">
            <FaBoxes className="text-white text-xl" />
            <div>
              <h3 className="text-lg font-semibold text-white leading-tight">Asset Status Overview</h3>
              <p className="text-teal-100 text-xs mt-0.5">Click a card to view filtered assets</p>
            </div>
          </div>
          <button onClick={onClose} className="text-white/80 hover:text-white p-1.5 rounded-lg hover:bg-white/20 transition-colors">
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        {/* ── Body ── */}
        <div className="p-6 space-y-4">

          {/* Total tile */}
          <button
            onClick={handleViewAll}
            className="w-full flex items-center justify-between bg-indigo-50 dark:bg-indigo-900/20 border border-indigo-200 dark:border-indigo-700 rounded-xl px-5 py-4 hover:bg-indigo-100 dark:hover:bg-indigo-900/40 transition-colors group"
          >
            <div className="flex items-center gap-3">
              <div className="w-10 h-10 bg-indigo-100 dark:bg-indigo-800 rounded-xl flex items-center justify-center">
                <FaBoxes className="text-indigo-600 dark:text-indigo-300 text-base" />
              </div>
              <div className="text-left">
                <div className="text-xs font-semibold text-indigo-500 dark:text-indigo-400 uppercase tracking-wide">Total Assets</div>
                <div className="text-3xl font-bold text-indigo-700 dark:text-indigo-200 leading-tight">{total}</div>
              </div>
            </div>
            <div className="flex items-center gap-1.5 text-xs font-semibold text-indigo-500 dark:text-indigo-400 group-hover:text-indigo-700 dark:group-hover:text-indigo-200 transition-colors">
              View all <FaExternalLinkAlt size={10} />
            </div>
          </button>

          {/* Per-status tiles */}
          {labels.length === 0 ? (
            <div className="text-center text-gray-400 py-8 text-sm">No status data available</div>
          ) : (
            <div className="grid grid-cols-2 gap-3">
              {labels.map((label, i) => {
                const count = values[i] ?? 0;
                const pct = total > 0 ? ((count / total) * 100).toFixed(1) : '0.0';
                const st = statusStyle(label);
                const barColor = colors[i] || '#6366F1';

                return (
                  <button
                    key={label}
                    onClick={() => handleStatusClick(label)}
                    className={`flex flex-col items-start text-left ${st.bg} border ${st.border} rounded-xl px-4 py-4 hover:opacity-80 hover:shadow-md transition-all group`}
                  >
                    {/* Count + arrow */}
                    <div className="flex items-start justify-between w-full mb-2">
                      <div className={`text-4xl font-bold ${st.text} leading-none`}>{count}</div>
                      <div className={`flex items-center gap-1 text-[10px] font-semibold ${st.text} opacity-60 group-hover:opacity-100 transition-opacity mt-1`}>
                        View <FaExternalLinkAlt size={8} />
                      </div>
                    </div>

                    {/* Label */}
                    <div className={`text-xs font-semibold ${st.text} uppercase tracking-wide mb-3`}>{label}</div>

                    {/* Progress bar */}
                    <div className="w-full h-1.5 bg-white/60 dark:bg-black/20 rounded-full overflow-hidden">
                      <div
                        className="h-full rounded-full transition-all duration-700"
                        style={{ width: `${pct}%`, backgroundColor: barColor }}
                      />
                    </div>

                    {/* Percentage */}
                    <div className={`text-[11px] font-semibold ${st.text} mt-1.5 opacity-70`}>{pct}% of total</div>
                  </button>
                );
              })}
            </div>
          )}
        </div>

      </div>
    </div>
  );
};

// ─── GroupedBarChart ──────────────────────────────────────────────────────────
const GroupedBarChart: React.FC<{ data: any }> = ({ data }) => {
  const { t } = useTranslation();
  const labels = data?.labels || [];
  const datasets = data?.datasets || [];
  if (!datasets.length) return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;

  const allValues = datasets.flatMap((ds: any) => ds.values || []);
  const max = Math.max(...allValues, 1);
  const chartHeight = 240;
  const width = Math.max(800, labels.length * 100);
  const groupWidth = Math.min(120, (width - 100) / labels.length);
  const barSpacing = 4;
  const numBars = datasets.length;
  const barWidth = Math.max(12, (groupWidth - barSpacing * (numBars + 1)) / numBars);

  const statusColors: Record<string, string> = {
    'Completed On Time': '#6366F1', 'Completed Within SLA': '#3B82F6', 'Delay In Completion': '#8B5CF6',
    'Pending': '#A855F7', 'Overdue': '#EC4899', 'Cancelled': '#0EA5E9',
    'Open': '#F59E0B', 'Work In Progress': '#3B82F6', 'Pending Review': '#E11D48',
    'Completed': '#10B981', 'Closed': '#10B981', 'Rejected': '#EF4444',
  };

  const getDatasetColor = (name: string, index: number): string => {
    for (const [key, color] of Object.entries(statusColors)) {
      if (name.toLowerCase().includes(key.toLowerCase())) return color;
    }
    return generateColors(numBars)[index];
  };

  return (
    <div className="relative w-full overflow-x-auto">
      <svg width="100%" height={chartHeight + 40} viewBox={`0 0 ${width} ${chartHeight + 40}`} className="w-full" preserveAspectRatio="xMidYMid meet">
        <defs>
          {datasets.map((ds: any, i: number) => {
            const color = getDatasetColor(ds.name || '', i);
            return (
              <linearGradient key={i} id={`groupedBarGradient${i}`} x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" style={{ stopColor: color, stopOpacity: 0.9 }} />
                <stop offset="100%" style={{ stopColor: color, stopOpacity: 0.7 }} />
              </linearGradient>
            );
          })}
        </defs>
        {[0, 0.25, 0.5, 0.75, 1].map((ratio, i) => (
          <line key={i} x1="60" y1={chartHeight - ratio * chartHeight} x2={width - 20} y2={chartHeight - ratio * chartHeight} stroke="#E5E7EB" strokeWidth="1" />
        ))}
        {[0, 0.25, 0.5, 0.75, 1].map((ratio, i) => (
          <text key={i} x="45" y={chartHeight - ratio * chartHeight + 4} textAnchor="end" className="text-xs fill-gray-400">{(max * ratio).toFixed(ratio === 0 ? 0 : max < 5 ? 1 : 0)}</text>
        ))}
        {labels.map((label: string, labelIndex: number) => {
          const groupX = 80 + labelIndex * groupWidth;
          return (
            <g key={labelIndex}>
              {datasets.map((dataset: any, dsIndex: number) => {
                const value = dataset.values?.[labelIndex] || 0;
                const barHeight = (value / max) * chartHeight;
                const x = groupX + barSpacing + dsIndex * (barWidth + barSpacing);
                const y = chartHeight - barHeight;
                const color = getDatasetColor(dataset.name || '', dsIndex);
                return (
                  <g key={dsIndex}>
                    <rect x={x} y={y} width={barWidth} height={barHeight} fill={color} rx="3" ry="3" className="hover:opacity-80 cursor-pointer transition-opacity">
                      <title>{`${label || 'Unknown'} — ${dataset.name || 'Series'}: ${value}`}</title>
                    </rect>
                  </g>
                );
              })}
              <text x={groupX + groupWidth / 2} y={chartHeight + 15} textAnchor="middle" className="text-xs fill-gray-600 dark:fill-gray-400">
                {label && label.length > 12 ? label.substring(0, 10) + '...' : label || 'null'}
              </text>
            </g>
          );
        })}
      </svg>
      <div className="flex flex-wrap items-center justify-center gap-2 mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
        {datasets.map((dataset: any, i: number) => {
          const color = getDatasetColor(dataset.name || '', i);
          return (
            <div key={i} className="flex items-center gap-1.5">
              <div className="w-2.5 h-2.5 rounded" style={{ backgroundColor: color }}></div>
              <span className="text-xs text-gray-600 dark:text-gray-400">{dataset.name && dataset.name.length > 20 ? dataset.name.substring(0, 18) + '...' : dataset.name || `Series ${i + 1}`}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ─── StackedBarChart ──────────────────────────────────────────────────────────
const StackedBarChart: React.FC<{ data: any }> = ({ data }) => {
  const { t } = useTranslation();
  const labels = data?.labels || [];
  const datasets = data?.datasets || [];
  if (!datasets.length) return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;

  const totalsProvided = Array.isArray(data?.totals) && data.totals.length === labels.length;
  const stackedTotals = totalsProvided
    ? data.totals
    : labels.map((_: string, labelIndex: number) => datasets.reduce((sum: number, ds: any) => sum + (ds.values?.[labelIndex] || 0), 0));

  const maxTotal = Math.max(...stackedTotals, 1);
  const stackColors: Record<string, string> = { total: '#6366F1', completed: '#10B981', in_progress: '#3B82F6', open: '#F59E0B' };
  const getStackColor = (name: string, index: number): string => {
    for (const [key, color] of Object.entries(stackColors)) { if (name.toLowerCase().includes(key)) return color; }
    return generateColors(datasets.length)[index];
  };

  return (
    <div className="space-y-2 max-h-72 overflow-y-auto">
      {labels.map((label: string, labelIndex: number) => {
        const total = stackedTotals[labelIndex];
        const tooltipParts = datasets.map((ds: any) => {
          const value = ds.values?.[labelIndex] || 0;
          return value > 0 ? `${(ds.name || '').replace(/_/g, ' ')}: ${value}` : null;
        }).filter(Boolean).join('  •  ');
        return (
          <div key={labelIndex} className="flex items-center gap-2">
            <div className="w-32 text-xs text-gray-700 dark:text-gray-200 truncate" title={label}>{label}</div>
            <div className="flex-1 h-4 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden flex cursor-default" title={`${tooltipParts}  •  Total: ${total}`}>
              {datasets.map((ds: any, dsIndex: number) => {
                const value = ds.values?.[labelIndex] || 0;
                if (!value) return null;
                return <div key={ds.name} className="h-full" style={{ width: `${(value / maxTotal) * 100}%`, backgroundColor: getStackColor(ds.name || '', dsIndex) }} />;
              })}
            </div>
            <div className="w-10 text-xs text-right text-gray-500 dark:text-gray-400">{total}</div>
          </div>
        );
      })}
      <div className="flex flex-wrap items-center gap-3 pt-2 border-t border-gray-200 dark:border-gray-700 mt-2">
        {datasets.map((dataset: any, index: number) => (
          <div key={dataset.name || index} className="flex items-center gap-1 text-[11px] text-gray-600 dark:text-gray-300">
            <span className="inline-block w-3 h-3 rounded-sm" style={{ backgroundColor: getStackColor(dataset.name || '', index) }} />
            <span>{(dataset.name || `Series ${index + 1}`).replace(/_/g, ' ')}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── TechnicianHoursChartCard ─────────────────────────────────────────────────
const TechnicianHoursChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
  const { t } = useTranslation();
  const [showMenu, setShowMenu] = useState(false);
  const totalHours = React.useMemo(() => {
    if (!data?.datasets?.[0]?.values) return 0;
    return data.datasets[0].values.reduce((sum: number, val: number) => sum + val, 0);
  }, [data]);

  useEffect(() => {
    const handleClickOutside = () => setShowMenu(false);
    if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
  }, [showMenu]);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <button onClick={onOpenReport} className="w-10 h-10 bg-indigo-50 dark:bg-indigo-900/20 rounded-xl flex items-center justify-center hover:bg-indigo-100 transition-colors group">
            <FaUserClock className="text-indigo-600 text-lg group-hover:scale-110 transition-transform" />
          </button>
          <div>
            <h3 className="text-sm font-semibold text-gray-900 dark:text-white">{title}</h3>
            <p className="text-xs text-gray-400">Total: <span className="font-semibold text-indigo-600">{totalHours.toFixed(1)} hrs</span></p>
          </div>
        </div>
        <div className="relative">
          <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
            <svg className="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
          </button>
          {showMenu && (
            <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
              <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
                <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport')}
              </button>
            </div>
          )}
        </div>
      </div>
      {!data || !data.datasets?.length ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaUserClock className="text-4xl mx-auto mb-2 opacity-30" /><div className="text-sm">Loading...</div></div></div>
      ) : (
        <HorizontalBarChart data={data} valueLabel="hrs" />
      )}
    </div>
  );
};

// ─── TechnicianWorkedChartCard ────────────────────────────────────────────────
const TechnicianWorkedChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
  const { t } = useTranslation();
  const [showMenu, setShowMenu] = useState(false);
  const totals = React.useMemo(() => {
    if (!data?.datasets) return { completed: 0, inProgress: 0, open: 0 };
    const result = { completed: 0, inProgress: 0, open: 0 };
    data.datasets.forEach((ds: any) => {
      const sum = ds.values?.reduce((s: number, v: number) => s + v, 0) || 0;
      if (ds.name === 'completed') result.completed = sum;
      else if (ds.name === 'in_progress') result.inProgress = sum;
      else if (ds.name === 'open') result.open = sum;
    });
    return result;
  }, [data]);

  useEffect(() => {
    const handleClickOutside = () => setShowMenu(false);
    if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
  }, [showMenu]);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <button onClick={onOpenReport} className="w-10 h-10 bg-purple-50 dark:bg-purple-900/20 rounded-xl flex items-center justify-center hover:bg-purple-100 transition-colors group">
            <FaHardHat className="text-purple-600 text-lg group-hover:scale-110 transition-transform" />
          </button>
          <div>
            <h3 className="text-sm font-semibold text-gray-900 dark:text-white">{title}</h3>
            <div className="flex items-center gap-2 text-xs mt-0.5">
              <span className="text-emerald-600 font-semibold">{totals.completed} done</span>
              <span className="text-gray-300">•</span>
              <span className="text-blue-600 font-semibold">{totals.inProgress} wip</span>
              <span className="text-gray-300">•</span>
              <span className="text-amber-600 font-semibold">{totals.open} open</span>
            </div>
          </div>
        </div>
        <div className="relative">
          <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
            <svg className="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
          </button>
          {showMenu && (
            <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
              <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
                <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport')}
              </button>
            </div>
          )}
        </div>
      </div>
      {!data || !data.datasets?.length ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaHardHat className="text-4xl mx-auto mb-2 opacity-30" /><div className="text-sm">Loading...</div></div></div>
      ) : (
        <StackedBarChart data={data} />
      )}
    </div>
  );
};

// ─── HorizontalBarChart ───────────────────────────────────────────────────────
const HorizontalBarChart: React.FC<{ data: any; valueLabel?: string }> = ({ data, valueLabel = '' }) => {
  const { t } = useTranslation();
  const labels = data?.labels || [];
  const values = data?.datasets?.[0]?.values || [];
  if (!values.length) return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
  const max = Math.max(...values, 1);

  return (
    <div className="space-y-3">
      {labels.map((label: string, i: number) => {
        const value = values[i] || 0;
        const percentage = (value / max) * 100;
        return (
          <div key={i} className="flex items-center gap-3">
            <div className="w-28 text-xs text-gray-600 dark:text-gray-400 truncate text-right" title={label || '(No Type)'}>{label || '(No Type)'}</div>
            <div className="flex-1 h-6 bg-gray-100 dark:bg-gray-700 rounded-lg overflow-hidden">
              <div className="h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-lg transition-all duration-500" style={{ width: `${percentage}%` }} />
            </div>
            <div className="w-12 text-xs font-semibold text-gray-800 dark:text-gray-200 text-right">
              {typeof value === 'number' ? (Number.isInteger(value) ? value : value.toFixed(1)) : value}{valueLabel ? ` ${valueLabel}` : ''}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── RejectionHorizontalBarChart ──────────────────────────────────────────────
const RejectionHorizontalBarChart: React.FC<{ data: any }> = ({ data }) => {
  const { t } = useTranslation();
  const labels = data?.labels || [];
  const values = data?.datasets?.[0]?.values || [];
  if (!values.length) return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
  const max = Math.max(...values, 1);

  return (
    <div className="space-y-3">
      {labels.map((label: string, i: number) => {
        const value = values[i] || 0;
        const percentage = (value / max) * 100;
        return (
          <div key={i} className="flex items-center gap-3">
            <div className="w-32 text-xs text-gray-600 dark:text-gray-400 truncate text-right" title={label || '(No Type)'}>{label || '(No Type)'}</div>
            <div className="flex-1 h-6 bg-gray-100 dark:bg-gray-700 rounded-lg overflow-hidden">
              <div className="h-full rounded-lg transition-all duration-500" style={{ width: `${percentage}%`, background: 'linear-gradient(to right, #EF4444, #F87171)' }} />
            </div>
            <div className="w-10 text-xs font-semibold text-red-600 dark:text-red-400 text-right">
              {typeof value === 'number' ? (Number.isInteger(value) ? value : value.toFixed(1)) : value}
            </div>
          </div>
        );
      })}
    </div>
  );
};

// ─── PieChart ─────────────────────────────────────────────────────────────────
const PieChart: React.FC<{ data: any }> = ({ data }) => {
  const labels = data?.labels || [];
  const values = data?.datasets?.[0]?.values || [];
  const isUpDownTimeChart = labels.some((label: string) =>
    label.toLowerCase().includes('up time') || label.toLowerCase().includes('down time') ||
    label.toLowerCase().includes('uptime') || label.toLowerCase().includes('downtime')
  );
  let colors: string[] = [];
  if (isUpDownTimeChart) {
    colors = labels.map((label: string) => {
      const l = label.toLowerCase();
      return l.includes('up time') || l.includes('uptime') ? '#6366F1' : '#8B5CF6';
    });
  } else {
    const datasetColors = data?.datasets?.[0]?.colors;
    colors = datasetColors && datasetColors.length === values.length ? datasetColors : generateColors(values.length);
  }
  const total = values.reduce((sum: number, val: number) => sum + val, 0);
  const radius = 100;
  const pad = 22;
  const cx = radius + pad;
  const cy = radius + pad;
  let cumulative = 0;
  const slices = values.map((value: number, i: number) => {
    const startAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
    cumulative += value;
    const endAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
    const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
    const x1 = cx + radius * Math.cos(startAngle), y1 = cy + radius * Math.sin(startAngle);
    const x2 = cx + radius * Math.cos(endAngle), y2 = cy + radius * Math.sin(endAngle);
    return { path: `M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`, color: colors[i], label: labels[i], value, percentage: ((value / total) * 100).toFixed(1) };
  });

  return (
    <div className="flex flex-col md:flex-row items-center justify-around">
      <svg width={cx * 2} height={cy * 2} viewBox={`0 0 ${cx * 2} ${cy * 2}`} className="max-w-xs">
        {slices.map((slice: any, i: number) => (
          <path key={i} d={slice.path} fill={slice.color} className="hover:opacity-80 transition-opacity cursor-pointer drop-shadow-sm">
            <title>{`${slice.label}: ${slice.value} (${slice.percentage}%)`}</title>
          </path>
        ))}
      </svg>
      <div className="flex flex-col gap-2.5 mt-4 md:mt-0">
        {slices.map((slice: any, i: number) => (
          <div key={i} className="flex items-center gap-3">
            <div className="w-3 h-3 rounded-full flex-shrink-0" style={{ backgroundColor: slice.color }}></div>
            <span className="text-sm text-gray-700 dark:text-gray-300">{slice.label}</span>
            <span className="text-sm font-bold text-gray-900 dark:text-white ml-auto pl-4">{slice.value}</span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── GroupedChartCard ─────────────────────────────────────────────────────────
const GroupedChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void; showSummary?: boolean }> = ({ title, data, onOpenReport, showSummary }) => {
  const { t } = useTranslation();
  const labels = data?.labels || [];
  const datasets = data?.datasets || [];
  const totalAssignees = labels.length;
  const totalTasks = datasets.reduce((sum: number, ds: any) => sum + (ds.values || []).reduce((a: number, b: number) => a + b, 0), 0);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-4 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-3">
        <h3 className="text-sm font-semibold text-gray-800 dark:text-white">{title}</h3>
        <button onClick={onOpenReport} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors" title={t('dashboard.viewFullReport')}>
          <FaExternalLinkAlt className="w-3.5 h-3.5 text-gray-400" />
        </button>
      </div>
      {!data || !datasets.length ? (
        <div className="h-48 flex items-center justify-center text-gray-400"><div className="text-xs">No chart data available</div></div>
      ) : (
        <>
          <GroupedBarChart data={data} />
          {showSummary && totalAssignees > 0 && (
            <div className="grid grid-cols-2 gap-2 mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
              <div className="bg-indigo-50 dark:bg-indigo-900/20 rounded-xl px-3 py-2 text-center">
                <div className="text-lg font-bold text-indigo-600 dark:text-indigo-400">{totalAssignees}</div>
                <div className="text-[10px] text-gray-500 dark:text-gray-400 uppercase tracking-wide font-semibold">Assignees</div>
              </div>
              <div className="bg-purple-50 dark:bg-purple-900/20 rounded-xl px-3 py-2 text-center">
                <div className="text-lg font-bold text-purple-600 dark:text-purple-400">{totalTasks}</div>
                <div className="text-[10px] text-gray-500 dark:text-gray-400 uppercase tracking-wide font-semibold">Tasks</div>
              </div>
            </div>
          )}
        </>
      )}
    </div>
  );
};

// ─── ChartDetailModal ─────────────────────────────────────────────────────────
// redirectContext:
//   'wo_status'  → labels are statuses; clicking label or any value cell
//                  navigates to /asm_app/work-orders?status={label}
//   'wo_type'    → labels are WO types; clicking label navigates to
//                  /asm_app/work-orders?work_order_type={label}&page=1
//                  clicking a value cell also appends &status={datasetName}
//   null/undefined → plain table, no redirects
const ChartDetailModal: React.FC<{
  isOpen: boolean;
  onClose: () => void;
  title: string;
  data: any;
  redirectContext?: 'wo_status' | 'wo_type' | null;
}> = ({ isOpen, onClose, title, data, redirectContext }) => {
  const { t } = useTranslation();
  if (!isOpen) return null;
  const labels = data?.labels || [];
  const datasets = data?.datasets || [];
  const hideFooterTotal = data?.hideFooterTotal === true;

  const goTo = (url: string) => { window.location.href = url; };

  const labelHref = (label: string): string | null => {
    if (!redirectContext) return null;
    if (redirectContext === 'wo_status') return `/asm_app/work-orders?status=${encodeURIComponent(label)}`;
    if (redirectContext === 'wo_type')   return `/asm_app/work-orders?work_order_type=${encodeURIComponent(label)}&page=1`;
    return null;
  };

  const cellHref = (label: string, dsName: string): string | null => {
    if (!redirectContext) return null;
    if (redirectContext === 'wo_status') return `/asm_app/work-orders?status=${encodeURIComponent(label)}`;
    if (redirectContext === 'wo_type')   return `/asm_app/work-orders?work_order_type=${encodeURIComponent(label)}&page=1&status=${encodeURIComponent(dsName)}`;
    return null;
  };

  const clickable = !!redirectContext;

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden">
        <div className="bg-gradient-to-r from-indigo-500 to-purple-600 px-6 py-4 flex items-center justify-between">
          <div>
            <h3 className="text-lg font-semibold text-white">{title}</h3>
            {clickable && <p className="text-indigo-200 text-xs mt-0.5">Click a row or value to view filtered work orders</p>}
          </div>
          <button onClick={onClose} className="text-white/80 hover:text-white transition-colors p-1 rounded-lg hover:bg-white/20">
            <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
          </button>
        </div>
        <div className="p-6 overflow-auto max-h-[calc(90vh-120px)]">
          {labels.length === 0 || datasets.length === 0 ? (
            <div className="text-center text-gray-400 py-8">{t('dashboard.noDataAvailable')}</div>
          ) : (
            <table className="w-full text-sm border-collapse">
              <thead>
                <tr className="border-b border-gray-200 dark:border-gray-700">
                  <th className="text-left py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 rounded-tl-lg">
                    {redirectContext === 'wo_type' ? 'WO Type' : redirectContext === 'wo_status' ? 'Status' : 'Label'}
                  </th>
                  {datasets.map((ds: any, i: number) => (
                    <th key={i} className="text-right py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 last:rounded-tr-lg">
                      {(ds.name || `Series ${i + 1}`).replace(/_/g, ' ')}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {labels.map((label: string, labelIdx: number) => {
                  const lHref = labelHref(label);
                  return (
                    <tr key={labelIdx} className={`border-b border-gray-100 dark:border-gray-700/50 transition-colors ${clickable ? 'hover:bg-indigo-50 dark:hover:bg-indigo-900/20' : 'hover:bg-gray-50 dark:hover:bg-gray-700/30'}`}>
                      <td
                        className={`py-2.5 px-4 text-gray-800 dark:text-gray-200 font-medium ${lHref ? 'cursor-pointer text-indigo-700 dark:text-indigo-300 hover:underline' : ''}`}
                        onClick={lHref ? () => goTo(lHref) : undefined}
                        title={lHref ? `View work orders for ${label}` : undefined}
                      >
                        <span className="flex items-center gap-1.5">
                          {label || 'Unknown'}
                          {lHref && <FaExternalLinkAlt size={9} className="opacity-50 flex-shrink-0" />}
                        </span>
                      </td>
                      {datasets.map((ds: any, dsIdx: number) => {
                        const val = ds.values?.[labelIdx] ?? 0;
                        const cHref = cellHref(label, ds.name || '');
                        return (
                          <td
                            key={dsIdx}
                            className={`py-2.5 px-4 text-right tabular-nums ${cHref ? 'cursor-pointer text-indigo-600 dark:text-indigo-400 font-semibold hover:text-indigo-800 dark:hover:text-indigo-200 hover:underline' : 'text-gray-600 dark:text-gray-300'}`}
                            onClick={cHref ? () => goTo(cHref) : undefined}
                            title={cHref ? `View ${ds.name} work orders for ${label}` : undefined}
                          >
                            {val}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
              {!hideFooterTotal && (
                <tfoot>
                  <tr className="border-t-2 border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-900/50">
                    <td className="py-3 px-4 font-bold text-gray-800 dark:text-gray-200">Total</td>
                    {datasets.map((ds: any, dsIdx: number) => {
                      const colTotal = (ds.values || []).reduce((s: number, v: number) => s + v, 0);
                      return <td key={dsIdx} className="py-3 px-4 text-right font-bold text-gray-800 dark:text-gray-200 tabular-nums">{typeof colTotal === 'number' && colTotal % 1 !== 0 ? colTotal.toFixed(1) : colTotal}</td>;
                    })}
                  </tr>
                </tfoot>
              )}
            </table>
          )}
        </div>
      </div>
    </div>
  );
};

// ─── InspectionSummaryChartCard ───────────────────────────────────────────────
const InspectionSummaryChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
  const { t } = useTranslation();
  const [showMenu, setShowMenu] = useState(false);
  const total = React.useMemo(() => data?.datasets?.[0]?.values?.reduce((s: number, v: number) => s + v, 0) ?? 0, [data]);
  useEffect(() => {
    const h = () => setShowMenu(false);
    if (showMenu) { document.addEventListener('click', h); return () => document.removeEventListener('click', h); }
  }, [showMenu]);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <button onClick={onOpenReport} className="w-10 h-10 bg-emerald-50 dark:bg-emerald-900/20 rounded-xl flex items-center justify-center hover:bg-emerald-100 transition-colors group">
            <FaCheckCircle className="text-emerald-600 text-lg group-hover:scale-110 transition-transform" />
          </button>
          <div>
            <h3 className="text-sm font-semibold text-gray-900 dark:text-white">{title}</h3>
            <p className="text-xs text-gray-400">Total: <span className="font-semibold text-emerald-600">{total}</span></p>
          </div>
        </div>
        <div className="relative">
          <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
            <svg className="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
          </button>
          {showMenu && (
            <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
              <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
                <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport', 'View Full Report')}
              </button>
            </div>
          )}
        </div>
      </div>
      {data === null ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaCheckCircle className="text-4xl mx-auto mb-2 opacity-20" /><div className="text-sm">Loading...</div></div></div>
      ) : !data.datasets?.length ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaCheckCircle className="text-4xl mx-auto mb-2 opacity-10" /><div className="text-sm">No inspection data</div></div></div>
      ) : (
        <HorizontalBarChart data={data} valueLabel="" />
      )}
    </div>
  );
};

// ─── RejectionSummaryChartCard ────────────────────────────────────────────────
const RejectionSummaryChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
  const { t } = useTranslation();
  const [showMenu, setShowMenu] = useState(false);
  const totalRejected = React.useMemo(() => {
    if (!data?.datasets?.[0]?.values) return data?.totalRejected ?? 0;
    return data.datasets[0].values.reduce((s: number, v: number) => s + v, 0);
  }, [data]);
  useEffect(() => {
    const h = () => setShowMenu(false);
    if (showMenu) { document.addEventListener('click', h); return () => document.removeEventListener('click', h); }
  }, [showMenu]);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <button onClick={onOpenReport} className="w-10 h-10 bg-red-50 dark:bg-red-900/20 rounded-xl flex items-center justify-center hover:bg-red-100 transition-colors group">
            <FaExclamationTriangle className="text-red-500 text-lg group-hover:scale-110 transition-transform" />
          </button>
          <div>
            <h3 className="text-sm font-semibold text-gray-900 dark:text-white">{title}</h3>
            <p className="text-xs text-gray-400">Total: <span className="font-semibold text-red-600">{totalRejected}</span></p>
          </div>
        </div>
        <div className="relative">
          <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
            <svg className="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
          </button>
          {showMenu && (
            <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
              <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
                <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport', 'View Full Report')}
              </button>
            </div>
          )}
        </div>
      </div>
      {data === null ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaExclamationTriangle className="text-4xl mx-auto mb-2 opacity-20" /><div className="text-sm">Loading...</div></div></div>
      ) : !data.datasets?.length ? (
        <div className="h-64 flex items-center justify-center text-gray-400"><div className="text-center"><FaExclamationTriangle className="text-4xl mx-auto mb-2 opacity-10" /><div className="text-sm">No rejection data</div></div></div>
      ) : (
        <RejectionHorizontalBarChart data={data} />
      )}
    </div>
  );
};

// ─── InspectionSummaryReportModal ─────────────────────────────────────────────
const InspectionSummaryReportModal: React.FC<{
  isOpen: boolean; onClose: () => void; permittedIssueTypes: string[]; isAdmin: boolean; defaultWorkOrderType?: string;
}> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
  const { t } = useTranslation();
  const [reportData, setReportData] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [selectedDepartment, setSelectedDepartment] = useState('');
  const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
  const [fromDate, setFromDate] = useState('');
  const [toDate, setToDate] = useState('');
  const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);
  const [allDepartments, setAllDepartments] = useState<string[]>([]);

  useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

  useEffect(() => {
    if (!isOpen) return;
    const fetchMeta = async () => {
      try {
        const [typesRes, deptsRes] = await Promise.all([
          fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
          fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
        ]);
        const typesData = await typesRes.json();
        const deptsData = await deptsRes.json();
        if (typesData.data) setAllIssueTypes(typesData.data.map((d: any) => d.name));
        if (deptsData.data) setAllDepartments(deptsData.data.map((d: any) => d.name));
      } catch (e) { console.error(e); }
    };
    fetchMeta();
  }, [isOpen]);

  const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

  useEffect(() => {
    if (!isOpen) return;
    const fetchReport = async () => {
      setLoading(true);
      try {
        const filters: Record<string, any> = {};
        if (!isAdmin && permittedIssueTypes.length > 0) {
          filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
        } else if (selectedWorkOrderType) { filters.work_order_type = selectedWorkOrderType; }
        if (selectedDepartment) filters.department = selectedDepartment;
        if (fromDate) filters.from_date = fromDate;
        if (toDate) filters.to_date = toDate;
        const res = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'Inspection Linked Work Orders Summary', filters, ignore_prepared_report: 1 })
        });
        const data = await res.json();
        setReportData(data.message || null);
      } catch (e) { console.error(e); } finally { setLoading(false); }
    };
    fetchReport();
  }, [isOpen, selectedWorkOrderType, selectedDepartment, fromDate, toDate, permittedIssueTypes, isAdmin]);

  if (!isOpen) return null;
  const columns: any[] = reportData?.columns || [];
  const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object');
  const dataRows = rows.filter((r: any) => !r.is_total_row);
  const reportSummary: any[] = reportData?.report_summary || [];

  const totalInspections = reportSummary.find((s: any) => s.label?.toLowerCase().includes('total inspection'))?.value
    ?? dataRows.reduce((sum: number, r: any) => {
      const col = columns.find((c: any) => c.label?.toLowerCase().includes('total inspection') || c.fieldname?.toLowerCase().includes('total_inspection'));
      return sum + (col ? (parseFloat(r[col.fieldname]) || 0) : 0);
    }, 0);

  const summaryCards = reportSummary.length > 0
    ? reportSummary.map((s: any) => ({ label: s.label, value: s.value, color: s.color || 'blue' }))
    : [{ label: 'Total Inspections', value: totalInspections, color: 'blue' }];

  const colorMap: Record<string, string> = { blue: 'text-blue-600 dark:text-blue-400', teal: 'text-teal-600 dark:text-teal-400', green: 'text-emerald-600 dark:text-emerald-400', red: 'text-red-600 dark:text-red-400', orange: 'text-orange-600 dark:text-orange-400', purple: 'text-purple-600 dark:text-purple-400' };
  const hasActiveFilter = selectedDepartment || fromDate || toDate || (selectedWorkOrderType && (isAdmin || permittedIssueTypes.length === 0));

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
        <div className="bg-gradient-to-r from-emerald-500 to-teal-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-3"><FaCheckCircle className="text-white text-xl" /><h3 className="text-lg font-semibold text-white">Inspection Linked Work Orders Summary</h3></div>
          <button onClick={onClose} className="text-white/80 hover:text-white p-1 rounded-lg hover:bg-white/20 transition-colors"><svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg></button>
        </div>
        <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-col gap-2">
          <div className="flex flex-wrap items-center gap-4">
            <div className="flex items-center gap-2">
              <label className="text-xs font-medium text-gray-500 whitespace-nowrap">WO Type</label>
              <select value={selectedWorkOrderType} onChange={e => setSelectedWorkOrderType(e.target.value)} disabled={!isAdmin && permittedIssueTypes.length > 0} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[200px] disabled:opacity-60">
                <option value="">All Types</option>
                {dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}
              </select>
            </div>
            <div className="flex items-center gap-2">
              <label className="text-xs font-medium text-gray-500 whitespace-nowrap">From Date</label>
              <input type="date" value={fromDate} onChange={e => setFromDate(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white" />
            </div>
            <div className="flex items-center gap-2">
              <label className="text-xs font-medium text-gray-500 whitespace-nowrap">To Date</label>
              <input type="date" value={toDate} onChange={e => setToDate(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white" />
            </div>
          </div>
          <div className="flex flex-wrap items-center gap-4">
            <div className="flex items-center gap-2">
              <label className="text-xs font-medium text-gray-500 whitespace-nowrap">Department</label>
              <select value={selectedDepartment} onChange={e => setSelectedDepartment(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-emerald-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[300px]">
                <option value="">All Departments</option>
                {allDepartments.map(d => <option key={d} value={d}>{d}</option>)}
              </select>
            </div>
            {hasActiveFilter && <button onClick={() => { setSelectedDepartment(''); setFromDate(''); setToDate(''); if (isAdmin || permittedIssueTypes.length === 0) setSelectedWorkOrderType(''); }} className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded-lg hover:bg-red-50 transition-colors"><FaTimes size={10} /> Clear</button>}
          </div>
        </div>
        {!loading && summaryCards.length > 0 && (
          <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0">
            <div className={`grid gap-6 ${summaryCards.length === 1 ? 'grid-cols-1' : summaryCards.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
              {summaryCards.map((card: any, i: number) => (
                <div key={i} className="text-center">
                  <div className="text-xs font-medium text-gray-500 mb-1">{card.label}</div>
                  <div className={`text-2xl font-bold ${colorMap[card.color] || 'text-blue-600'}`}>{card.value}</div>
                </div>
              ))}
            </div>
          </div>
        )}
        <div className="p-6 overflow-auto flex-1">
          {loading ? <div className="flex items-center justify-center py-16"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-emerald-600"></div></div>
            : rows.length === 0 ? <div className="text-center text-gray-400 py-16">No data available</div>
              : (
                <table className="w-full text-sm border-collapse">
                  <thead>
                    <tr className="border-b border-gray-200 dark:border-gray-700">
                      {columns.map((col: any, i: number) => <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left' : 'text-right'}`}>{col.label || col.fieldname}</th>)}
                    </tr>
                  </thead>
                  <tbody>
                    {rows.map((row: any, ri: number) => (
                      <tr key={ri} className="border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors">
                        {columns.map((col: any, ci: number) => <td key={ci} className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium' : 'text-right text-gray-600 dark:text-gray-300 tabular-nums'}`}>{row[col.fieldname] ?? '—'}</td>)}
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
        </div>
      </div>
    </div>
  );
};

// ─── RejectionSummaryReportModal ──────────────────────────────────────────────
const RejectionSummaryReportModal: React.FC<{
  isOpen: boolean; onClose: () => void; permittedIssueTypes: string[]; isAdmin: boolean; defaultWorkOrderType?: string;
}> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
  const [reportData, setReportData] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [fromDate, setFromDate] = useState('');
  const [toDate, setToDate] = useState('');
  const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
  const [selectedDepartment, setSelectedDepartment] = useState('');
  const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);
  const [allDepartments, setAllDepartments] = useState<string[]>([]);

  useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

  useEffect(() => {
    if (!isOpen) return;
    const fetchMeta = async () => {
      try {
        const [typesRes, deptsRes] = await Promise.all([
          fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
          fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
        ]);
        const typesData = await typesRes.json(); const deptsData = await deptsRes.json();
        if (typesData.data) setAllIssueTypes(typesData.data.map((d: any) => d.name));
        if (deptsData.data) setAllDepartments(deptsData.data.map((d: any) => d.name));
      } catch (e) { console.error(e); }
    };
    fetchMeta();
  }, [isOpen]);

  const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

  useEffect(() => {
    if (!isOpen) return;
    const fetchReport = async () => {
      setLoading(true);
      try {
        const filters: Record<string, any> = {};
        if (!isAdmin && permittedIssueTypes.length > 0) { filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes; }
        else if (selectedWorkOrderType) { filters.work_order_type = selectedWorkOrderType; }
        if (selectedDepartment) filters.department = selectedDepartment;
        if (fromDate) filters.from_date = fromDate;
        if (toDate) filters.to_date = toDate;
        const res = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'WO Rejection Summary', filters, ignore_prepared_report: 1 })
        });
        const data = await res.json();
        setReportData(data.message || null);
      } catch (e) { console.error(e); } finally { setLoading(false); }
    };
    fetchReport();
  }, [isOpen, selectedWorkOrderType, selectedDepartment, fromDate, toDate, permittedIssueTypes, isAdmin]);

  if (!isOpen) return null;
  const columns: any[] = reportData?.columns || [];
  const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object' && r.custom_delete_status !== 'Deleted');
  const dataRows = rows.filter((r: any) => !r.is_total_row);
  const reportSummary: any[] = reportData?.report_summary || [];

  const findWoTypeLabelKey2 = (cols: any[], rows: any[]): string => {
    const byFieldname = cols.find((c: any) => c?.fieldname && (c.fieldname.toLowerCase().includes('work_order_type') || c.fieldname.toLowerCase().includes('wo_type') || c.fieldname.toLowerCase() === 'type'));
    if (byFieldname) return byFieldname.fieldname;
    if (cols[1]?.fieldname) return cols[1].fieldname;
    return cols[0]?.fieldname || '';
  };

  const labelKey = findWoTypeLabelKey2(columns, dataRows);
  const totalWoCol = columns.find((c: any) => { const s = ((c.label || '') + (c.fieldname || '')).toLowerCase(); return s.includes('total_work') || s.includes('total work'); });
  const totalRejCol = columns.find((c: any) => { const s = ((c.label || '') + (c.fieldname || '')).toLowerCase(); return s.includes('total_rejected') || s.includes('total rejected') || (s.includes('rejected') && !s.includes('%')); });
  const totalWO = totalWoCol ? dataRows.reduce((s: number, r: any) => s + (parseFloat(r[totalWoCol.fieldname]) || 0), 0) : null;
  const totalRej = totalRejCol ? dataRows.reduce((s: number, r: any) => s + (parseFloat(r[totalRejCol.fieldname]) || 0), 0) : null;
  const rejPct = (totalWO && totalRej && totalWO > 0) ? ((totalRej / totalWO) * 100).toFixed(2) + '%' : null;

  const summaryItems = reportSummary.length > 0
    ? reportSummary.map((s: any) => ({ label: s.label, value: s.value, color: s.color || 'blue' }))
    : [...(totalWO !== null ? [{ label: 'Total Work Orders', value: totalWO, color: 'blue' }] : []), ...(totalRej !== null ? [{ label: 'Total Rejected', value: totalRej, color: 'red' }] : []), ...(rejPct !== null ? [{ label: 'Rejected %', value: rejPct, color: 'orange' }] : [])];

  const colorMap: Record<string, string> = { blue: 'text-blue-600 dark:text-blue-400', red: 'text-red-600 dark:text-red-400', orange: 'text-orange-600 dark:text-orange-400', green: 'text-emerald-600 dark:text-emerald-400', purple: 'text-purple-600 dark:text-purple-400' };

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
        <div className="bg-gradient-to-r from-red-500 to-rose-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-3"><FaExclamationTriangle className="text-white text-xl" /><h3 className="text-lg font-semibold text-white">WO Rejection Summary</h3></div>
          <button onClick={onClose} className="text-white/80 hover:text-white p-1 rounded-lg hover:bg-white/20 transition-colors"><svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg></button>
        </div>
        <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-wrap items-center gap-4">
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">From Date</label><input type="date" value={fromDate} onChange={e => setFromDate(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white" /></div>
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">To Date</label><input type="date" value={toDate} onChange={e => setToDate(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white" /></div>
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">WO Type</label><select value={selectedWorkOrderType} onChange={e => setSelectedWorkOrderType(e.target.value)} disabled={!isAdmin && permittedIssueTypes.length > 0} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[160px] disabled:opacity-60"><option value="">All Types</option>{dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}</select></div>
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">Department</label><select value={selectedDepartment} onChange={e => setSelectedDepartment(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[160px]"><option value="">All Departments</option>{allDepartments.map(d => <option key={d} value={d}>{d}</option>)}</select></div>
          {(fromDate || toDate || selectedWorkOrderType || selectedDepartment) && <button onClick={() => { setFromDate(''); setToDate(''); setSelectedWorkOrderType(''); setSelectedDepartment(''); }} className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded-lg hover:bg-red-50 transition-colors"><FaTimes size={10} /> Clear</button>}
        </div>
        {!loading && summaryItems.length > 0 && (
          <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0">
            <div className={`grid gap-6 ${summaryItems.length === 1 ? 'grid-cols-1' : summaryItems.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
              {summaryItems.map((item: any, i: number) => <div key={i} className="text-center"><div className="text-xs font-medium text-gray-500 mb-1">{item.label}</div><div className={`text-2xl font-bold ${colorMap[item.color] || 'text-blue-600'}`}>{item.value}</div></div>)}
            </div>
          </div>
        )}
        <div className="p-6 overflow-auto flex-1">
          {loading
            ? <div className="flex items-center justify-center py-16"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-red-600"></div></div>
            : rows.length === 0
              ? <div className="text-center text-gray-400 py-16">No data available</div>
              : (() => {
                  // Detect key columns for redirect building
                  const woTypeCol = columns.find((c: any) => {
                    const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
                    return s.includes('work_order_type') || s.includes('wo_type') || s.includes('type');
                  });
                  const deptCol = columns.find((c: any) => {
                    const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
                    return s.includes('department') || s.includes('dept');
                  });
                  const rejCol = columns.find((c: any) => {
                    const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
                    return (s.includes('total_rejected') || s.includes('total rejected') || (s.includes('rejected') && !s.includes('%')));
                  });

                  const buildRedirectUrl = (row: any): string => {
                    const params = new URLSearchParams();
                    const woType = woTypeCol ? (row[woTypeCol.fieldname] || '') : '';
                    const dept   = deptCol   ? (row[deptCol.fieldname]   || '') : '';
                    if (woType) params.set('work_order_type', woType);
                    params.set('page', '1');
                    if (dept) params.set('department', dept);
                    params.set('status', 'Rejected');
                    return `/asm_app/work-orders?${params.toString()}`;
                  };

                  return (
                    <table className="w-full text-sm border-collapse">
                      <thead>
                        <tr className="border-b border-gray-200 dark:border-gray-700">
                          {columns.map((col: any, i: number) => (
                            <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left rounded-tl-lg' : 'text-right'} ${i === columns.length - 1 ? 'rounded-tr-lg' : ''}`}>
                              {col.label || col.fieldname}
                              {rejCol && col.fieldname === rejCol.fieldname && (
                                <span className="ml-1 text-[9px] text-red-400 font-normal normal-case">(click to view)</span>
                              )}
                            </th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {rows.map((row: any, ri: number) => (
                          <tr key={ri} className="border-b border-gray-100 dark:border-gray-700/50 hover:bg-red-50/40 dark:hover:bg-red-900/10 transition-colors">
                            {columns.map((col: any, ci: number) => {
                              const isRejCol = rejCol && col.fieldname === rejCol.fieldname;
                              const cellVal = row[col.fieldname] ?? '—';
                              const rejCount = isRejCol ? (parseFloat(row[col.fieldname]) || 0) : 0;
                              const isClickable = isRejCol && rejCount > 0;
                              const redirectUrl = isClickable ? buildRedirectUrl(row) : null;
                              return (
                                <td
                                  key={ci}
                                  className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium text-left' : 'text-right tabular-nums'} ${isClickable ? 'cursor-pointer text-red-600 dark:text-red-400 font-bold hover:text-red-800 dark:hover:text-red-200 hover:underline' : 'text-gray-600 dark:text-gray-300'}`}
                                  onClick={isClickable ? () => { window.location.href = redirectUrl!; } : undefined}
                                  title={isClickable ? `View rejected work orders` : undefined}
                                >
                                  {isClickable
                                    ? <span className="flex items-center justify-end gap-1.5">{cellVal}<FaExternalLinkAlt size={9} className="opacity-60 flex-shrink-0" /></span>
                                    : cellVal}
                                </td>
                              );
                            })}
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  );
                })()
          }
        </div>
      </div>
    </div>
  );
};

// ─── TimeToRepairCard ─────────────────────────────────────────────────────────
const TimeToRepairCard: React.FC<{ data: any; onOpenReport?: () => void }> = ({ data, onOpenReport }) => {
  const [showMenu, setShowMenu] = useState(false);
  useEffect(() => {
    const h = () => setShowMenu(false);
    if (showMenu) { document.addEventListener('click', h); return () => document.removeEventListener('click', h); }
  }, [showMenu]);

  const rawLabels: string[] = data?.labels || [];
  const rawValues: number[] = data?.datasets?.[0]?.values || [];
  const filtered = rawLabels.reduce<{ labels: string[]; values: number[] }>(
    (acc, label, i) => { if (!isNullOrUnknownLabel(label)) { acc.labels.push(label); acc.values.push(rawValues[i] ?? 0); } return acc; },
    { labels: [], values: [] }
  );
  const labels = filtered.labels;
  const values = filtered.values;
  const overallAvg: number = data?.overallAvg ?? 0;
  const typeColors = generateColors(labels.length);
  const max = Math.max(...values, 0.001);

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-3">
          <button onClick={onOpenReport} className="w-10 h-10 bg-pink-50 dark:bg-pink-900/20 rounded-xl flex items-center justify-center hover:bg-pink-100 transition-colors group">
            <FaWrench className="text-pink-600 text-base group-hover:scale-110 transition-transform" />
          </button>
          <div>
            <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Time to Repair</h3>
            <p className="text-xs text-gray-400">Overall Avg: <span className="font-bold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)} hrs</span></p>
          </div>
        </div>
        <div className="relative">
          <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
            <svg className="w-4 h-4 text-gray-400" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
          </button>
          {showMenu && <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50"><button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2"><FaExternalLinkAlt className="text-gray-400" size={12} /> View Full Report</button></div>}
        </div>
      </div>

      <div className="bg-gradient-to-r from-pink-50 to-rose-50 dark:from-pink-900/20 dark:to-rose-900/20 rounded-xl px-4 py-3 mb-4 flex items-center justify-between">
        <span className="text-xs font-semibold text-pink-700 dark:text-pink-300">Overall Avg Time to Repair</span>
        <span className="text-2xl font-bold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)} <span className="text-sm font-normal">hrs</span></span>
      </div>

      {!data || !labels.length ? (
        <div className="h-40 flex items-center justify-center text-gray-400"><div className="text-center"><FaWrench className="text-3xl mx-auto mb-1 opacity-20" /><div className="text-xs">Loading...</div></div></div>
      ) : (
        <div className="space-y-2 max-h-56 overflow-y-auto">
          {labels.map((label, i) => {
            const value = values[i] || 0;
            const pct = max > 0 ? (value / max) * 100 : 0;
            const color = typeColors[i];
            const minPct = Math.max(pct, value > 0 ? 3 : 1);
            return (
              <div key={i} className="flex items-center gap-2">
                <div className="flex-1 h-7 bg-gray-100 dark:bg-gray-700 rounded-lg overflow-hidden relative">
                  <div className="h-full rounded-lg transition-all duration-500 flex items-center justify-end pr-2" style={{ width: `${minPct}%`, backgroundColor: color, opacity: 0.88 }}>
                    {pct > 28 && <span className="text-[9px] font-bold text-white whitespace-nowrap">{value.toFixed(2)} hrs</span>}
                  </div>
                  {pct <= 28 && <span className="absolute left-[calc(max(3%,6px)+6px)] top-1/2 -translate-y-1/2 text-[9px] font-bold text-gray-600 dark:text-gray-300 whitespace-nowrap">{value.toFixed(2)} hrs</span>}
                </div>
                <div className="w-36 text-[11px] text-gray-700 dark:text-gray-200 font-medium truncate flex-shrink-0" title={label}>{label}</div>
              </div>
            );
          })}
        </div>
      )}

      {labels.length > 0 && (
        <div className="flex flex-wrap items-center gap-x-3 gap-y-1 mt-3 pt-2 border-t border-gray-100 dark:border-gray-700">
          {labels.map((label, i) => (
            <div key={i} className="flex items-center gap-1"><div className="w-2 h-2 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[i] }} /><span className="text-[9px] text-gray-400 truncate max-w-[90px]">{label.length > 14 ? label.substring(0, 12) + '…' : label}</span></div>
          ))}
        </div>
      )}
    </div>
  );
};

// ─── TimeToRepairReportModal ───────────────────────────────────────────────────
const TimeToRepairReportModal: React.FC<{
  isOpen: boolean; onClose: () => void; permittedIssueTypes: string[]; isAdmin: boolean; defaultWorkOrderType?: string;
}> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
  const [reportData, setReportData] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [selectedDepartment, setSelectedDepartment] = useState('');
  const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
  const [allDepartments, setAllDepartments] = useState<string[]>([]);
  const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);

  useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

  useEffect(() => {
    if (!isOpen) return;
    const fetchMeta = async () => {
      try {
        const [deptRes, typeRes] = await Promise.all([
          fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
          fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
        ]);
        const deptData = await deptRes.json(); const typeData = await typeRes.json();
        if (deptData.data) setAllDepartments(deptData.data.map((d: any) => d.name));
        if (typeData.data) setAllIssueTypes(typeData.data.map((d: any) => d.name));
      } catch (e) { console.error(e); }
    };
    fetchMeta();
  }, [isOpen]);

  const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

  useEffect(() => {
    if (!isOpen) return;
    const fetchReport = async () => {
      setLoading(true);
      try {
        const filters: Record<string, any> = {};
        if (!isAdmin && permittedIssueTypes.length > 0) { filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes; }
        else if (selectedWorkOrderType) { filters.work_order_type = selectedWorkOrderType; }
        if (selectedDepartment) filters.department = selectedDepartment;
        const res = await fetch('/api/method/frappe.desk.query_report.run', {
          method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
          body: JSON.stringify({ report_name: 'Time to Repair', filters, ignore_prepared_report: 1 })
        });
        const data = await res.json();
        setReportData(data.message || null);
      } catch (e) { console.error(e); } finally { setLoading(false); }
    };
    fetchReport();
  }, [isOpen, selectedDepartment, selectedWorkOrderType, permittedIssueTypes, isAdmin]);

  if (!isOpen) return null;
  const columns: any[] = reportData?.columns || [];
  const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object');
  const dataRows = rows.filter((r: any) => !r.is_total_row);
  const reportSummary: any[] = reportData?.report_summary || [];

  const timeCol = columns.find((c: any) => { const s = ((c.label || '') + (c.fieldname || '')).toLowerCase(); return s.includes('time_to_repair') || s.includes('time to repair') || s.includes('hours'); }) || columns[columns.length - 1];
  const woTypeCol = columns.find((c: any) => { const s = ((c.label || '') + (c.fieldname || '')).toLowerCase(); return s.includes('wo_type') || s.includes('wo type') || s.includes('work_order_type'); }) || columns[1];
  const summaryAvgItem = reportSummary.find((s: any) => s.label?.toLowerCase().includes('avg') || s.label?.toLowerCase().includes('overall'));
  const validDataRows = dataRows.filter((r: any) => !isNullOrUnknownLabel(woTypeCol ? r[woTypeCol.fieldname] : null));
  const overallAvg = summaryAvgItem
    ? parseFloat(summaryAvgItem.value) || 0
    : validDataRows.length > 0 && timeCol ? validDataRows.reduce((s: number, r: any) => s + (parseFloat(r[timeCol.fieldname]) || 0), 0) / validDataRows.length : 0;

  const typeMap: Record<string, { total: number; count: number }> = {};
  dataRows.forEach((r: any) => {
    const rawType = woTypeCol ? r[woTypeCol.fieldname] : null;
    if (isNullOrUnknownLabel(rawType)) return;
    const type = String(rawType);
    const time = timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0;
    if (!typeMap[type]) typeMap[type] = { total: 0, count: 0 };
    typeMap[type].total += time; typeMap[type].count += 1;
  });
  const chartLabels = Object.keys(typeMap);
  const chartValues = chartLabels.map(t => parseFloat((typeMap[t].total / typeMap[t].count).toFixed(3)));
  const chartMax = Math.max(...chartValues, 0.001);
  const chartColors = generateColors(chartLabels.length);
  const hasActiveFilter = selectedDepartment || (selectedWorkOrderType && (isAdmin || permittedIssueTypes.length === 0));

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
        <div className="bg-gradient-to-r from-pink-500 to-rose-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-3"><FaWrench className="text-white text-xl" /><h3 className="text-lg font-semibold text-white">Time to Repair</h3></div>
          <button onClick={onClose} className="text-white/80 hover:text-white p-1 rounded-lg hover:bg-white/20 transition-colors"><svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg></button>
        </div>
        <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-wrap items-center gap-4">
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">Department</label><select value={selectedDepartment} onChange={e => setSelectedDepartment(e.target.value)} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[180px]"><option value="">All Departments</option>{allDepartments.map(d => <option key={d} value={d}>{d}</option>)}</select></div>
          <div className="flex items-center gap-2"><label className="text-xs font-medium text-gray-500 whitespace-nowrap">WO Type</label><select value={selectedWorkOrderType} onChange={e => setSelectedWorkOrderType(e.target.value)} disabled={!isAdmin && permittedIssueTypes.length > 0} className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[180px] disabled:opacity-60"><option value="">All Types</option>{dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}</select></div>
          {hasActiveFilter && <button onClick={() => { setSelectedDepartment(''); setSelectedWorkOrderType(''); }} className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded-lg hover:bg-red-50 transition-colors"><FaTimes size={10} /> Clear</button>}
        </div>
        {!loading && (
          <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0 text-center">
            <div className="text-xs font-medium text-gray-500 mb-1">Overall Avg Time to Repair (Hours)</div>
            <div className="text-3xl font-bold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)}</div>
          </div>
        )}
        <div className="p-6 overflow-auto flex-1 flex flex-col gap-6">
          {loading ? <div className="flex items-center justify-center py-16"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-pink-600"></div></div>
            : rows.length === 0 ? <div className="text-center text-gray-400 py-16">No data available</div>
              : (
                <>
                  {chartLabels.length > 0 && (
                    <div className="bg-gray-50 dark:bg-gray-900/30 rounded-xl p-4">
                      <h4 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-4">Avg Time to Repair by WO Type (Hours)</h4>
                      <div className="space-y-3">
                        {chartLabels.map((label, i) => {
                          const value = chartValues[i];
                          const pct = chartMax > 0 ? (value / chartMax) * 100 : 0;
                          const color = chartColors[i];
                          const minPct = Math.max(pct, value > 0 ? 2 : 1);
                          return (
                            <div key={i} className="flex items-center gap-3">
                              <div className="flex-1 h-8 bg-white dark:bg-gray-700 rounded-lg overflow-hidden relative border border-gray-200 dark:border-gray-600">
                                <div className="h-full rounded-lg transition-all duration-500 flex items-center justify-end pr-2" style={{ width: `${minPct}%`, backgroundColor: color, opacity: 0.85 }}>
                                  {pct > 20 && <span className="text-[11px] font-semibold text-white">{value.toFixed(3)}</span>}
                                </div>
                                {pct <= 20 && <span className="absolute left-[calc(max(2%,4px)+8px)] top-1/2 -translate-y-1/2 text-[11px] font-semibold text-gray-700 dark:text-gray-200">{value.toFixed(3)}</span>}
                              </div>
                              <div className="w-52 text-xs text-gray-700 dark:text-gray-200 font-medium truncate flex-shrink-0" title={label}>{label}</div>
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  )}
                  <table className="w-full text-sm border-collapse">
                    <thead>
                      <tr className="border-b border-gray-200 dark:border-gray-700">
                        {columns.map((col: any, i: number) => <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left' : 'text-right'}`}>{col.label || col.fieldname}</th>)}
                      </tr>
                    </thead>
                    {/* <tbody>
                      {rows.map((row: any, ri: number) => (
                        <tr key={ri} className={`border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors ${row.is_total_row ? 'font-bold bg-gray-50 dark:bg-gray-900/40 border-t-2 border-gray-300 dark:border-gray-600' : ''}`}>
                          {columns.map((col: any, ci: number) => <td key={ci} className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium' : 'text-right text-gray-600 dark:text-gray-300 tabular-nums'}`}>{row[col.fieldname] ?? '—'}</td>)}
                        </tr>
                      ))}
                    </tbody> */}
                    <tbody>
                      {rows.map((row: any, ri: number) => (
                        <tr key={ri} className={`border-b border-gray-100 dark:border-gray-700/50 hover:bg-pink-50/40 dark:hover:bg-pink-900/10 transition-colors ${row.is_total_row ? 'font-bold bg-gray-50 dark:bg-gray-900/40 border-t-2 border-gray-300 dark:border-gray-600' : ''}`}>
                          {columns.map((col: any, ci: number) => {
                            const fieldLower = (col.fieldname || '').toLowerCase();
                            const labelLower = (col.label || '').toLowerCase();
                            const isWoCol = !row.is_total_row && (
                              fieldLower === 'name' ||
                              fieldLower === 'work_order' ||
                              fieldLower === 'work_order_id' ||
                              labelLower === 'work order' ||
                              labelLower === 'work order id' ||
                              labelLower === 'wo'
                            );
                            const cellVal = row[col.fieldname] ?? '—';
                            const woId = isWoCol ? String(cellVal) : '';
                            const isClickable = isWoCol && woId && woId !== '—';
                            return (
                              <td
                                key={ci}
                                className={`py-2.5 px-4 ${ci === 0 ? 'text-left font-medium' : 'text-right tabular-nums'} ${isClickable ? 'cursor-pointer text-pink-600 dark:text-pink-400 font-semibold hover:text-pink-800 dark:hover:text-pink-200 hover:underline' : 'text-gray-800 dark:text-gray-200'}`}
                                onClick={isClickable ? () => { window.location.href = `/asm_app/work-orders?work_order_id=${encodeURIComponent(woId)}`; } : undefined}
                                title={isClickable ? `Open Work Order ${woId}` : undefined}
                              >
                                {isClickable
                                  ? <span className="flex items-center gap-1.5">{cellVal}<FaExternalLinkAlt size={9} className="opacity-50 flex-shrink-0" /></span>
                                  : cellVal}
                              </td>
                            );
                          })}
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </>
              )}
        </div>
      </div>
    </div>
  );
};

function generateColors(count: number): string[] {
  const colors = ['#8B5CF6', '#6366F1', '#3B82F6', '#06B6D4', '#14B8A6', '#EC4899', '#A855F7', '#0EA5E9', '#10B981', '#F472B6', '#7C3AED', '#2DD4BF'];
  return Array.from({ length: count }, (_, i) => colors[i % colors.length]);
}

export default ModernDashboard;












// import React, { useState, useEffect } from 'react';
// import { useNumberCards, useDashboardChart } from '../hooks/useApi';
// import { useWorkOrders } from '../hooks/useWorkOrder';
// import { useAssetMaintenanceLogs } from '../hooks/useAssetMaintenance';
// import { useAssets } from '../hooks/useAsset';
// import { useTranslation } from 'react-i18next';
// import { FaShoppingCart, FaChartLine, FaBoxes, FaTools, FaCheckCircle, FaClock, FaExclamationTriangle, FaArrowUp, FaArrowDown, FaUserClock, FaHardHat, FaExternalLinkAlt, FaFilter, FaTimes, FaWrench } from 'react-icons/fa';
// import TechnicianWorkingHoursReportModal from '../components/TechnicianWorkingHoursReportModal';
// import TechnicianWorkOrderSummaryReportModal from '../components/TechnicianWorkOrderSummaryReportModal';
// import useUserPermissions from '../hooks/useUserPermissions';

// // Helper to detect null/unknown/empty labels that should be excluded from charts
// const isNullOrUnknownLabel = (val: any): boolean => {
//   if (val === null || val === undefined) return true;
//   const s = String(val).trim().toLowerCase();
//   return s === '' || s === 'null' || s === 'unknown' || s === 'undefined' || s === 'none';
// };

// const ModernDashboard: React.FC = () => {
//   const { t } = useTranslation();
//   const { data: numberCards, loading: cardsLoading } = useNumberCards();
//   // const { workOrders } = useWorkOrders({}, 0, 0);

//   const { workOrders: allWorkOrders } = useWorkOrders({}, 0, 0);
//   const workOrders = React.useMemo(
//     () => (allWorkOrders || []).filter(wo => wo.custom_delete_status !== 'Deleted'),
//     [allWorkOrders]
//   );

//   const { logs: maintenanceLogs } = useAssetMaintenanceLogs({}, 0, 0);
//   const { assets } = useAssets({}, 0, 0);
  
//   const [workOrderChartData, setWorkOrderChartData] = useState<any>(null);
//   const [workOrderGroupedChartData, setWorkOrderGroupedChartData] = useState<any>(null);
//   const [maintenanceAssetChartData, setMaintenanceAssetChartData] = useState<any>(null);
//   const [upDownTimeChartData, setUpDownTimeChartData] = useState<any>(null);
//   const [assigneesGroupedChartData, setAssigneesGroupedChartData] = useState<any>(null);
//   const [maintenanceFrequencyChartData, setMaintenanceFrequencyChartData] = useState<any>(null);
//   const [completionByTypeChartData, setCompletionByTypeChartData] = useState<any>(null);
  
//   const [realWorkOrderCounts, setRealWorkOrderCounts] = useState({
//     open: 0,
//     inProgress: 0,
//     completed: 0,
//     pendingReview: 0,
//     total: 0,
//     wfCompleted: 0,
//     wfInProgress: 0
//   });

//   const [insights, setInsights] = useState({
//     assetsDown: 0,
//     avgResponseTime: 0,
//     maintenanceEfficiency: 0,
//     overdueTasks: 0,
//     plannedMaintenance: 0
//   });

//   const { data: upDownChart } = useDashboardChart('Up & Down Time Chart');
//   const { data: workOrderChart } = useDashboardChart('Work Order Status Chart');
//   const { data: assetWiseChart } = useDashboardChart('Maintenance - Asset wise Count');
//   const { data: assigneesChart } = useDashboardChart('Asset Maintenance Assignees Status Count');
//   const { data: frequencyChart } = useDashboardChart('Asset Maintenance Frequency Chart');

//   const { restrictions, isAdmin: isWoAdmin } = useUserPermissions('Work_Order');
//   const permittedIssueTypes: string[] = React.useMemo(
//     () => restrictions['Issue Type']?.values || [],
//     [JSON.stringify(restrictions['Issue Type']?.values)]
//   );

//   // ── Role-based visibility ────────────────────────────────────────────────
//   const [userRoles, setUserRoles] = useState<string[]>([]);

//   useEffect(() => {
//     const fetchRoles = async () => {
//       try {
//         const res = await fetch('/api/method/frappe.client.get_value?doctype=User&fieldname=["roles"]&filters={"name":"__user__"}'.replace('__user__', ''), {
//           credentials: 'include',
//         });
//         // Simpler: use the logged_in_user endpoint
//         const sessionRes = await fetch('/api/method/frappe.auth.get_logged_user', {
//           credentials: 'include',
//         });
//         const sessionData = await sessionRes.json();
//         const loggedUser = sessionData.message;
//         if (loggedUser) {
//           const rolesRes = await fetch(
//             `/api/resource/User/${encodeURIComponent(loggedUser)}?fields=["roles"]`,
//             { headers: { Accept: 'application/json' }, credentials: 'include' }
//           );
//           const rolesData = await rolesRes.json();
//           const roles: string[] = (rolesData.data?.roles || []).map((r: any) => r.role);
//           setUserRoles(roles);
//         }
//       } catch (e) {
//         console.error('Error fetching user roles:', e);
//       }
//     };
//     fetchRoles();
//   }, []);

//   // Inspection + Rejection: System Manager, admin (isWoAdmin), Quality Supervisor
//   const canSeeInspectionRejection = isWoAdmin ||
//     userRoles.includes('System Manager') ||
//     userRoles.includes('Quality Supervisor');

//   // Time to Repair: System Manager, admin (isWoAdmin), Cluster Manager
//   const canSeeTimeToRepair = isWoAdmin ||
//     userRoles.includes('System Manager') ||
//     userRoles.includes('Cluster Manager');
//   // ────────────────────────────────────────────────────────────────────────

//   const [technicianHoursData, setTechnicianHoursData] = useState<any>(null);
//   const [technicianWorkedData, setTechnicianWorkedData] = useState<any>(null);

//   const [showTechnicianHoursReport, setShowTechnicianHoursReport] = useState(false);
//   const [showTechnicianWorkOrderReport, setShowTechnicianWorkOrderReport] = useState(false);

//   const [inspectionSummaryData, setInspectionSummaryData] = useState<any>(null);
//   const [rejectionSummaryData, setRejectionSummaryData] = useState<any>(null);
//   const [showInspectionReport, setShowInspectionReport] = useState(false);
//   const [showRejectionReport, setShowRejectionReport] = useState(false);
//   const [timeToRepairData, setTimeToRepairData] = useState<any>(null);
//   const [showTimeToRepairReport, setShowTimeToRepairReport] = useState(false);
//   const [chartDetail, setChartDetail] = useState<{ title: string; data: any } | null>(null);

//   const [issueTypes, setIssueTypes] = useState<string[]>([]);
//   const [selectedIssueType, setSelectedIssueType] = useState<string>('');

//   useEffect(() => {
//     const fetchIssueTypes = async () => {
//       try {
//         const response = await fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', {
//           headers: { 'Accept': 'application/json' },
//           credentials: 'include'
//         });
//         const data = await response.json();
//         if (data.data) {
//           setIssueTypes(data.data.map((d: any) => d.name));
//         }
//       } catch (error) {
//         console.error('Error fetching issue types:', error);
//       }
//     };
//     fetchIssueTypes();
//   }, []);

//   const filteredWorkOrders = React.useMemo(() => {
//     if (!workOrders) return [];
//     if (!isWoAdmin && permittedIssueTypes.length > 0) return workOrders;
//     if (!selectedIssueType) return workOrders;
//     return workOrders.filter(wo => wo.work_order_type === selectedIssueType);
//   }, [workOrders, isWoAdmin, permittedIssueTypes, selectedIssueType]);

//   useEffect(() => {
//     const fetchTechnicianHours = async () => {
//       try {
//         const filters: Record<string, any> = {};
//         if (!isWoAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1
//             ? permittedIssueTypes[0]
//             : permittedIssueTypes;
//         } else if (selectedIssueType) {
//           filters.work_order_type = selectedIssueType;
//         }

//         const response = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({
//             report_name: 'Technicians working Hours',
//             filters: filters,
//             ignore_prepared_report: 1
//           })
//         });
//         const data = await response.json();
        
//         if (data.message?.result) {
//           const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
//           const labels = rows.map((r: any) => r.technician_name || 'Unknown');
//           const values = rows.map((r: any) => parseFloat(r.total_hours) || 0);
          
//           setTechnicianHoursData({
//             labels,
//             datasets: [{
//               name: 'Total Hours',
//               values,
//               colors: ['#6366F1']
//             }],
//             type: 'Bar'
//           });
//         }
//       } catch (error) {
//         console.error('Error fetching technician hours:', error);
//       }
//     };
    
//     fetchTechnicianHours();
//   }, [permittedIssueTypes, isWoAdmin, selectedIssueType]);

//   useEffect(() => {
//     const fetchTechnicianWorked = async () => {
//       try {
//         const filters: Record<string, any> = {};
//         if (!isWoAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1
//             ? permittedIssueTypes[0]
//             : permittedIssueTypes;
//         } else if (selectedIssueType) {
//           filters.work_order_type = selectedIssueType;
//         }

//         const response = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({
//             report_name: 'Technician Work Order Summary',
//             filters: filters,
//             ignore_prepared_report: 1
//           })
//         });
//         const data = await response.json();
        
//         if (data.message?.result) {
//           const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
//           const labels = rows.map((r: any) => r.assigned_technician || 'Unknown');
//           const totals = rows.map((r: any) => parseFloat(r.total) || 0);
//           const datasets = [
//             {
//               name: 'completed',
//               values: rows.map((r: any) => parseFloat(r.completed) || 0),
//               color: '#10B981'
//             },
//             {
//               name: 'in_progress',
//               values: rows.map((r: any) => parseFloat(r.in_progress) || 0),
//               color: '#3B82F6'
//             },
//             {
//               name: 'open',
//               values: rows.map((r: any) => parseFloat(r.open) || 0),
//               color: '#F59E0B'
//             }
//           ].filter(ds => ds.values.some((v: number) => v > 0));
          
//           setTechnicianWorkedData({
//             labels,
//             datasets,
//             totals,
//             type: 'Bar'
//           });
//         }
//       } catch (error) {
//         console.error('Error fetching technician worked:', error);
//       }
//     };
    
//     fetchTechnicianWorked();
//   }, [permittedIssueTypes, isWoAdmin, selectedIssueType]);

//   const findWoTypeLabelKey = (cols: any[], rows: any[]): string => {
//     const byFieldname = cols.find((c: any) =>
//       c?.fieldname &&
//       (c.fieldname.toLowerCase().includes('work_order_type') ||
//        c.fieldname.toLowerCase().includes('wo_type') ||
//        c.fieldname.toLowerCase() === 'type')
//     );
//     if (byFieldname) return byFieldname.fieldname;

//     const byLabel = cols.find((c: any) =>
//       c?.label &&
//       (c.label.toLowerCase().includes('wo type') ||
//        c.label.toLowerCase().includes('work order type') ||
//        c.label.toLowerCase() === 'type')
//     );
//     if (byLabel) return byLabel.fieldname;

//     if (cols[1]?.fieldname) return cols[1].fieldname;
//     return cols[0]?.fieldname || Object.keys(rows[0] || {})[0] || 'name';
//   };

//   const findCountKey = (cols: any[], rows: any[], excludeKey: string): string | null => {
//     const isNumericVal = (val: any) =>
//       (typeof val === 'number' && !isNaN(val)) ||
//       (typeof val === 'string' && val !== '' && !isNaN(parseFloat(val)));

//     const numericCols = cols.filter((c: any) =>
//       c?.fieldname &&
//       c.fieldname !== excludeKey &&
//       rows.some((r: any) => isNumericVal(r[c.fieldname]))
//     );

//     const preferred = numericCols.find((c: any) => {
//       const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//       return s.includes('count') || s.includes('linked') || s.includes('inspection') ||
//              s.includes('rejection') || s.includes('total') || s.includes('wo');
//     });
//     if (preferred) return preferred.fieldname;

//     return numericCols[0]?.fieldname || null;
//   };

//   // Fetch Inspection Linked Work Orders Summary — only for permitted roles
//   useEffect(() => {
//     if (!canSeeInspectionRejection) return;
//     const fetchInspectionSummary = async () => {
//       try {
//         const filters: Record<string, any> = {};
//         if (!isWoAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1
//             ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedIssueType) {
//           filters.work_order_type = selectedIssueType;
//         }
//         const response = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({ report_name: 'Inspection Linked Work Orders Summary', filters, ignore_prepared_report: 1 })
//         });
//         const data = await response.json();
//         if (data.message?.result) {
//           const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
//           const cols: any[] = data.message?.columns || [];

//           const labelKey = findWoTypeLabelKey(cols, rows);
//           const countKey = findCountKey(cols, rows, labelKey);

//           const grouped: Record<string, number> = {};
//           rows.forEach((r: any) => {
//             const label = (r[labelKey] !== null && r[labelKey] !== undefined && r[labelKey] !== '')
//               ? String(r[labelKey])
//               : '(No Type)';
//             const val = countKey ? (parseFloat(r[countKey]) || 0) : 0;
//             grouped[label] = (grouped[label] || 0) + val;
//           });

//           const labels = Object.keys(grouped);
//           const values = Object.values(grouped);

//           const countCol = cols.find((c: any) => c?.fieldname === countKey);
//           const datasetName = countCol?.label || 'Count';

//           setInspectionSummaryData({
//             labels,
//             datasets: [{ name: datasetName, values }],
//             rawRows: rows,
//             columns: cols,
//             type: 'Bar'
//           });
//         }
//       } catch (error) {
//         console.error('Error fetching inspection summary:', error);
//       }
//     };
//     fetchInspectionSummary();
//   }, [canSeeInspectionRejection, permittedIssueTypes, isWoAdmin, selectedIssueType]);

//   // Fetch WO Rejection Summary — only for permitted roles
//   useEffect(() => {
//     if (!canSeeInspectionRejection) return;
//     const fetchRejectionSummary = async () => {
//       try {
//         const filters: Record<string, any> = {};
//         if (!isWoAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1
//             ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedIssueType) {
//           filters.work_order_type = selectedIssueType;
//         }
//         const response = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({ report_name: 'WO Rejection Summary', filters, ignore_prepared_report: 1 })
//         });
//         const data = await response.json();
//         if (data.message?.result) {
//           const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
//           const cols: any[] = data.message?.columns || [];

//           const labelKey = findWoTypeLabelKey(cols, rows);

//           const isNumericVal = (val: any) =>
//             (typeof val === 'number' && !isNaN(val)) ||
//             (typeof val === 'string' && val !== '' && !isNaN(parseFloat(val)));

//           const isNumericCol = (c: any) => {
//             if (!c?.fieldname || c.fieldname === labelKey || !rows.length) return false;
//             if (c.fieldtype && ['Int', 'Float', 'Currency', 'Percent'].includes(c.fieldtype)) return true;
//             const sample = rows.find((r: any) => r[c.fieldname] != null && r[c.fieldname] !== '');
//             if (!sample) return false;
//             return isNumericVal(sample[c.fieldname]);
//           };

//           const numericCols = cols.filter(isNumericCol);
//           const colsToUse = numericCols.length > 0 ? numericCols : cols.filter((c: any) => {
//             if (!c?.fieldname || c.fieldname === labelKey || !rows.length) return false;
//             const sample = rows.find((r: any) => r[c.fieldname] != null && r[c.fieldname] !== '');
//             if (!sample) return false;
//             return !isNaN(parseFloat(String(sample[c.fieldname])));
//           });

//           const groupedMap: Record<string, Record<string, number>> = {};
//           rows.forEach((r: any) => {
//             const label = (r[labelKey] !== null && r[labelKey] !== undefined && r[labelKey] !== '')
//               ? String(r[labelKey])
//               : '(No Type)';
//             if (!groupedMap[label]) groupedMap[label] = {};
//             colsToUse.forEach((c: any) => {
//               groupedMap[label][c.fieldname] = (groupedMap[label][c.fieldname] || 0) + (parseFloat(r[c.fieldname]) || 0);
//             });
//           });

//           const totalRejectedColKey = (() => {
//             const preferred = colsToUse.find((c: any) => {
//               const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//               return s.includes('total_rejected') || s.includes('total rejected') || s.includes('rejected');
//             });
//             return preferred?.fieldname || colsToUse[colsToUse.length - 1]?.fieldname || null;
//           })();

//           const labels = Object.keys(groupedMap);

//           const totalRejectedValues = labels.map(lbl =>
//             totalRejectedColKey ? (groupedMap[lbl][totalRejectedColKey] || 0) : 0
//           );

//           const grandTotal = totalRejectedValues.reduce((s, v) => s + v, 0);

//           setRejectionSummaryData({
//             labels,
//             datasets: [{
//               name: 'Total Rejected',
//               values: totalRejectedValues,
//             }],
//             totalRejected: grandTotal,
//             rawRows: rows,
//             columns: cols,
//             type: 'Bar'
//           });
//         }
//       } catch (error) {
//         console.error('Error fetching rejection summary:', error);
//       }
//     };
//     fetchRejectionSummary();
//   }, [canSeeInspectionRejection, permittedIssueTypes, isWoAdmin, selectedIssueType]);

//   useEffect(() => {
//     if (assets && assets.length > 0) {
//       let totalUpTime = 0;
//       let totalDownTime = 0;
      
//       assets.forEach(asset => {
//         const upTime = asset.custom_up_time || 0;
//         const downTime = asset.custom_down_time || 0;
//         totalUpTime += typeof upTime === 'number' ? upTime : 0;
//         totalDownTime += typeof downTime === 'number' ? downTime : 0;
//       });

//       const labels: string[] = [];
//       const values: number[] = [];
      
//       if (totalUpTime > 0) {
//         labels.push(t('dashboard.upTime'));
//         values.push(totalUpTime);
//       }
//       if (totalDownTime > 0) {
//         labels.push(t('dashboard.downTime'));
//         values.push(totalDownTime);
//       }

//       if (labels.length > 0 && values.length > 0) {
//         const pieColors: string[] = [];
//         if (totalUpTime > 0) pieColors.push('#6366F1');
//         if (totalDownTime > 0) pieColors.push('#8B5CF6');
        
//         setUpDownTimeChartData({
//           labels,
//           datasets: [{ name: 'Time', values, colors: pieColors }],
//           type: 'Pie'
//         });
//       } else {
//         setUpDownTimeChartData(null);
//       }
//     } else {
//       setUpDownTimeChartData(null);
//     }
//   }, [assets]);

//   useEffect(() => {
//     if (assets && assets.length > 0) {
//       const downCount = assets.filter(
//         asset => (asset.custom_device_status || '').trim().toLowerCase() === 'down'
//       ).length;
//       setInsights(prev => ({ ...prev, assetsDown: downCount }));
//     }
//   }, [assets]);

//   useEffect(() => {
//     if (filteredWorkOrders && filteredWorkOrders.length > 0) {
//       const statusCounts: Record<string, number> = {};
//       let openCount = 0;
//       let inProgressCount = 0;
//       let completedCount = 0;
//       let pendingReviewCount = 0;
      
//       filteredWorkOrders.forEach(wo => {
//         const status = wo.repair_status || 'Unknown';
//         statusCounts[status] = (statusCounts[status] || 0) + 1;
//         if (status.toLowerCase() === 'open') openCount++;
//         if (status.toLowerCase() === 'work in progress') inProgressCount++;
//         if (status.toLowerCase() === 'closed') completedCount++;
//         if (status.toLowerCase() === 'pending review') pendingReviewCount++;
//       });

//       let wfCompletedCount = 0;
//       let wfInProgressCount = 0;

//       filteredWorkOrders.forEach(wo => {
//         const wfState = (wo.workflow_state || '').toLowerCase();
//         if (wfState === 'closed' || wfState === 'sent to supervisor') {
//           wfCompletedCount++;
//         } else {
//           wfInProgressCount++;
//         }
//       });

//       const statusDisplayOrder = ['Open', 'Work In Progress', 'Pending Review', 'Closed', 'Cancelled', 'Unknown'];
//       const sortedEntries = Object.entries(statusCounts).sort(([a], [b]) => {
//         const aIdx = statusDisplayOrder.indexOf(a);
//         const bIdx = statusDisplayOrder.indexOf(b);
//         if (aIdx === -1 && bIdx === -1) return a.localeCompare(b);
//         if (aIdx === -1) return 1;
//         if (bIdx === -1) return -1;
//         return aIdx - bIdx;
//       });

//       const labels = sortedEntries.map(([label]) => label);
//       const values = sortedEntries.map(([, count]) => count);
      
//       const colorMap: Record<string, string> = {
//         'Open': '#F59E0B',
//         'Work In Progress': '#3B82F6',
//         'Pending Review': '#E11D48',
//         'Pending': '#8B5CF6',
//         'Completed': '#10B981',
//         'Closed': '#10B981',
//         'Cancelled': '#EC4899',
//         'Unknown': '#6B7280'
//       };

//       const colors = labels.map(label => colorMap[label] || '#6366F1');

//       setWorkOrderChartData({
//         labels,
//         datasets: [{ name: 'Work Orders', values, colors }],
//         type: 'bar'
//       });

//       setRealWorkOrderCounts({
//         open: openCount,
//         inProgress: inProgressCount,
//         completed: completedCount,
//         pendingReview: pendingReviewCount,
//         total: filteredWorkOrders.length,
//         wfCompleted: wfCompletedCount,
//         wfInProgress: wfInProgressCount
//       });

//       const normalizeStatus = (status: string): string => {
//         const s = status.toLowerCase().trim();
//         if (s.includes('open')) return 'Open';
//         if (s.includes('work in progress') || s.includes('in progress') || s.includes('wip')) return 'Work In Progress';
//         if (s.includes('pending review') || s.includes('pending')) return 'Pending Review';
//         if (s.includes('completed') || s.includes('complete')) return 'Completed';
//         if (s.includes('closed')) return 'Closed';
//         return status;
//       };

//       const groupedData: Record<string, Record<string, number>> = {};
//       const allStatuses = new Set<string>();

//       filteredWorkOrders.forEach(wo => {
//         // FIX: Skip work orders with null/unknown/empty work_order_type
//         const rawType = wo.work_order_type;
//         if (isNullOrUnknownLabel(rawType)) return;
//         const workOrderType = String(rawType);
//         const repairStatus = normalizeStatus(wo.repair_status || 'Unknown');
//         allStatuses.add(repairStatus);
//         if (!groupedData[workOrderType]) groupedData[workOrderType] = {};
//         groupedData[workOrderType][repairStatus] = (groupedData[workOrderType][repairStatus] || 0) + 1;
//       });

//       const workOrderTypeLabels = Object.keys(groupedData);
//       const statusOrder = ['Open', 'Work In Progress', 'Pending Review', 'Completed', 'Closed'];
//       const statusList = Array.from(allStatuses).sort((a, b) => {
//         const aI = statusOrder.indexOf(a);
//         const bI = statusOrder.indexOf(b);
//         if (aI !== -1 && bI !== -1) return aI - bI;
//         if (aI !== -1) return -1;
//         if (bI !== -1) return 1;
//         return a.localeCompare(b);
//       });

//       const datasets = statusList.map(status => ({
//         name: status,
//         values: workOrderTypeLabels.map(type => groupedData[type][status] || 0)
//       }));

//       setWorkOrderGroupedChartData({
//         labels: workOrderTypeLabels,
//         datasets,
//         type: 'Bar'
//       });

//       const typeStatMap: Record<string, {
//         total: number;
//         wfCompleted: number;
//         closed: number;
//         pendingReview: number;
//         open: number;
//         inProgress: number;
//       }> = {};

//       filteredWorkOrders.forEach(wo => {
//         // FIX: Skip null/unknown/empty work_order_type entries for completion chart
//         const rawType = wo.work_order_type;
//         if (isNullOrUnknownLabel(rawType)) return;
//         const type = String(rawType);
//         if (!typeStatMap[type]) {
//           typeStatMap[type] = { total: 0, wfCompleted: 0, closed: 0, pendingReview: 0, open: 0, inProgress: 0 };
//         }
//         typeStatMap[type].total++;

//         const wfState = (wo.workflow_state || '').toLowerCase();
//         if (wfState === 'closed' || wfState === 'sent to supervisor') {
//           typeStatMap[type].wfCompleted++;
//         }

//         const rs = (wo.repair_status || '').toLowerCase();
//         if (rs === 'closed') typeStatMap[type].closed++;
//         if (rs === 'pending review') typeStatMap[type].pendingReview++;
//         if (rs === 'open') typeStatMap[type].open++;
//         if (rs === 'work in progress') typeStatMap[type].inProgress++;
//       });

//       // FIX: Use only typeStatMap keys (already null-filtered) for completion chart labels
//       const completionTypeLabels = Object.keys(typeStatMap);

//       const completionRateByType = completionTypeLabels.map(type => {
//         const s = typeStatMap[type] || { total: 0, wfCompleted: 0, closed: 0, pendingReview: 0, open: 0, inProgress: 0 };
//         const rate = s.total > 0 ? (s.wfCompleted / s.total) * 100 : 0;
//         return { type, ...s, rate };
//       });

//       setCompletionByTypeChartData({
//         labels: completionTypeLabels,
//         rates: completionRateByType,
//       });

//     } else {
//       setWorkOrderGroupedChartData(null);
//       setCompletionByTypeChartData(null);
//     }
//   }, [filteredWorkOrders]);

//   useEffect(() => {
//     if (maintenanceLogs && maintenanceLogs.length > 0) {
//       const assetCounts: Record<string, number> = {};
//       let completedMaintenance = 0;
//       let plannedMaintenance = 0;
//       let overdueMaintenance = 0;
//       const today = new Date();
      
//       maintenanceLogs.forEach(log => {
//         const assetName = log.asset_name || 'Unknown';
//         assetCounts[assetName] = (assetCounts[assetName] || 0) + 1;
//         if (log.maintenance_status?.toLowerCase() === 'completed') completedMaintenance++;
//         if (log.maintenance_status?.toLowerCase() === 'planned') plannedMaintenance++;
//         if (log.due_date && new Date(log.due_date) < today && log.maintenance_status !== 'Completed') {
//           overdueMaintenance++;
//         }
//       });

//       const sorted = Object.entries(assetCounts).sort(([, a], [, b]) => b - a).slice(0, 10);
//       const labels = sorted.map(([name]) => name);
//       const values = sorted.map(([, count]) => count);
//       const barColors = generateColors(labels.length);
      
//       setMaintenanceAssetChartData({
//         labels,
//         datasets: [{ name: 'Maintenance Count', values, colors: barColors }],
//         type: 'bar'
//       });

//       const maintenanceEfficiency = maintenanceLogs.length > 0
//         ? ((completedMaintenance / maintenanceLogs.length) * 100)
//         : 0;

//       setInsights(prev => ({
//         ...prev,
//         maintenanceEfficiency,
//         overdueTasks: overdueMaintenance,
//         plannedMaintenance
//       }));

//       const groupedData: Record<string, Record<string, number>> = {};
//       const allStatuses = new Set<string>();
      
//       const normalizeStatus = (status: string, log: any): string => {
//         const statusLower = status.toLowerCase().trim();
//         const today = new Date();
//         const dueDate = log.due_date ? new Date(log.due_date) : null;
//         if (dueDate && dueDate < today && statusLower !== 'completed' && statusLower !== 'cancelled') return 'Overdue';
//         if (statusLower.includes('completed on time') || statusLower === 'completed on time') return 'Completed On Time';
//         if (statusLower.includes('completed within') || statusLower.includes('within sla') || statusLower === 'completed') return 'Completed Within SLA';
//         if (statusLower.includes('delay') || statusLower.includes('late')) return 'Delay In Completion';
//         if (statusLower.includes('pending') || statusLower === 'planned') return 'Pending';
//         if (statusLower.includes('overdue')) return 'Overdue';
//         if (statusLower.includes('cancelled') || statusLower === 'cancelled') return 'Cancelled';
//         return status;
//       };
      
//       maintenanceLogs.forEach(log => {
//         const assignee = log.assign_to_name || 'null';
//         const normalizedStatus = normalizeStatus(log.maintenance_status || 'Unknown', log);
//         allStatuses.add(normalizedStatus);
//         if (!groupedData[assignee]) groupedData[assignee] = {};
//         groupedData[assignee][normalizedStatus] = (groupedData[assignee][normalizedStatus] || 0) + 1;
//       });

//       const assigneeLabels = Object.keys(groupedData);
//       const statusOrder = ['Completed On Time', 'Completed Within SLA', 'Delay In Completion', 'Pending', 'Overdue', 'Cancelled'];
//       const statusList = Array.from(allStatuses).sort((a, b) => {
//         const aI = statusOrder.indexOf(a);
//         const bI = statusOrder.indexOf(b);
//         if (aI !== -1 && bI !== -1) return aI - bI;
//         if (aI !== -1) return -1;
//         if (bI !== -1) return 1;
//         return a.localeCompare(b);
//       });
      
//       const datasets = statusList.map(status => ({
//         name: status,
//         values: assigneeLabels.map(assignee => groupedData[assignee][status] || 0)
//       }));

//       setAssigneesGroupedChartData({
//         labels: assigneeLabels,
//         datasets,
//         type: 'Bar'
//       });

//       const frequencyCounts: Record<string, number> = {};
//       maintenanceLogs.forEach(log => {
//         const frequency = log.periodicity || log.maintenance_type || 'Other';
//         frequencyCounts[frequency] = (frequencyCounts[frequency] || 0) + 1;
//       });

//       const sortedFrequencies = Object.entries(frequencyCounts).sort(([, a], [, b]) => b - a);
//       const frequencyLabels = sortedFrequencies.map(([name]) => name);
//       const frequencyValues = sortedFrequencies.map(([, count]) => count);
//       const frequencyColors = generateColors(frequencyLabels.length);
      
//       setMaintenanceFrequencyChartData({
//         labels: frequencyLabels,
//         datasets: [{ name: 'Frequency', values: frequencyValues, colors: frequencyColors }],
//         type: 'bar'
//       });
//     } else {
//       setAssigneesGroupedChartData(null);
//       setMaintenanceFrequencyChartData(null);
//     }
//   }, [maintenanceLogs]);

//   useEffect(() => {
//     if (workOrders && workOrders.length > 0) {
//       let totalResponseHours = 0;
//       let responseCount = 0;
      
//       workOrders.forEach(wo => {
//         if (wo.creation && wo.first_responded_on) {
//           const created = new Date(wo.creation);
//           const responded = new Date(wo.first_responded_on);
//           const hours = (responded.getTime() - created.getTime()) / (1000 * 60 * 60);
//           if (hours >= 0) {
//             totalResponseHours += hours;
//             responseCount++;
//           }
//         }
//       });

//       const avgResponseTime = responseCount > 0 ? totalResponseHours / responseCount : 0;
//       setInsights(prev => ({ ...prev, avgResponseTime }));
//     }
//   }, [workOrders]);

//   // Fetch Time to Repair report — only for permitted roles
//   useEffect(() => {
//     if (!canSeeTimeToRepair) return;
//     const fetchTimeToRepair = async () => {
//       try {
//         const filters: Record<string, any> = {};
//         if (!isWoAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1
//             ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedIssueType) {
//           filters.work_order_type = selectedIssueType;
//         }
//         const response = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({ report_name: 'Time to Repair', filters, ignore_prepared_report: 1 })
//         });
//         const data = await response.json();
//         if (data.message?.result) {
//           const rows = data.message.result.filter((r: any) => r && typeof r === 'object' && !r.is_total_row);
//           const cols: any[] = data.message?.columns || [];

//           // Find the WO Type column and Time to Repair column
//           const woTypeCol = cols.find((c: any) => {
//             const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//             return s.includes('wo_type') || s.includes('wo type') || s.includes('work_order_type') || s.includes('work order type');
//           }) || cols[1];

//           const timeCol = cols.find((c: any) => {
//             const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//             return s.includes('time_to_repair') || s.includes('time to repair') || s.includes('repair_time') || s.includes('hours');
//           }) || cols[cols.length - 1];

//           // FIX: Group by WO Type, skip null/unknown types
//           const typeMap: Record<string, { total: number; count: number }> = {};
//           rows.forEach((r: any) => {
//             const rawWoType = woTypeCol ? r[woTypeCol.fieldname] : null;
//             // Skip null/unknown/empty WO types
//             if (isNullOrUnknownLabel(rawWoType)) return;
//             const woType = String(rawWoType);
//             const time = timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0;
//             if (!typeMap[woType]) typeMap[woType] = { total: 0, count: 0 };
//             typeMap[woType].total += time;
//             typeMap[woType].count += 1;
//           });

//           const typeLabels = Object.keys(typeMap);
//           const avgByType = typeLabels.map(t => parseFloat((typeMap[t].total / typeMap[t].count).toFixed(3)));

//           // Compute overall avg from all (non-null) rows
//           const validRows = rows.filter((r: any) => {
//             const rawWoType = woTypeCol ? r[woTypeCol.fieldname] : null;
//             return !isNullOrUnknownLabel(rawWoType);
//           });
//           const overallAvg = validRows.length > 0
//             ? parseFloat((validRows.reduce((s: number, r: any) => s + (timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0), 0) / validRows.length).toFixed(3))
//             : 0;

//           // Report summary
//           const reportSummary = data.message?.report_summary || [];
//           const summaryAvg = reportSummary.find((s: any) =>
//             s.label?.toLowerCase().includes('avg') || s.label?.toLowerCase().includes('overall')
//           );

//           setTimeToRepairData({
//             labels: typeLabels,
//             datasets: [{ name: 'Avg Time to Repair (hrs)', values: avgByType }],
//             overallAvg: summaryAvg ? parseFloat(summaryAvg.value) || overallAvg : overallAvg,
//             rawRows: rows,
//             columns: cols,
//             reportSummary,
//             type: 'Bar'
//           });
//         }
//       } catch (error) {
//         console.error('Error fetching time to repair:', error);
//       }
//     };
//     fetchTimeToRepair();
//   }, [canSeeTimeToRepair, permittedIssueTypes, isWoAdmin, selectedIssueType]);

//   if (cardsLoading) {
//     return (
//       <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900">
//         <div className="text-center">
//           <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600 mx-auto mb-4"></div>
//           <div className="text-gray-600 dark:text-gray-400">{t('dashboard.loading')}</div>
//         </div>
//       </div>
//     );
//   }

//   return (
//     <div className="min-h-screen bg-gray-50 dark:bg-gray-900 p-6">
//       <div className="max-w-[1600px] mx-auto">

//         {/* Global Dashboard Filter Bar */}
//         {(isWoAdmin || permittedIssueTypes.length === 0) && (
//           <div className="bg-white dark:bg-gray-800 rounded-lg shadow border border-gray-200 dark:border-gray-700 px-4 py-3 mb-4 flex items-center gap-4 flex-wrap">
//             <div className="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400">
//               <FaFilter className="text-indigo-500" />
//               <span className="font-medium">{t('dashboard.dashboardFilter', 'Dashboard Filter')}</span>
//             </div>
//             <div className="flex items-center gap-2">
//               <label className="text-xs font-medium text-gray-500 dark:text-gray-400">
//                 Technical Department
//               </label>
//               <select
//                 value={selectedIssueType}
//                 onChange={(e) => setSelectedIssueType(e.target.value)}
//                 className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[200px]"
//               >
//                 <option value="">{t('dashboard.allDepartments', 'All Departments')}</option>
//                 {issueTypes.map(type => (
//                   <option key={type} value={type}>{type}</option>
//                 ))}
//               </select>
//             </div>
//             {selectedIssueType && (
//               <button
//                 onClick={() => setSelectedIssueType('')}
//                 className="text-xs text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 flex items-center gap-1 px-2 py-1 rounded hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
//               >
//                 <FaTimes size={10} />
//                 {t('dashboard.clearFilter', 'Clear Filter')}
//               </button>
//             )}
//             {selectedIssueType && (
//               <span className="text-xs text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-900/30 px-2 py-1 rounded-full">
//                 Filtering: {selectedIssueType}
//               </span>
//             )}
//           </div>
//         )}

//         {/* Top Section */}
//         <div className="grid grid-cols-1 lg:grid-cols-12 gap-3 mb-6 items-start">
          
//           <div className="lg:col-span-7 space-y-2">
//             <div className="bg-white dark:bg-gray-800 rounded-lg shadow border border-gray-200 dark:border-gray-700 px-4 py-4">
//               <div className="grid grid-cols-12 gap-0 w-full">
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaBoxes className="text-indigo-600" />}
//                     // value={numberCards?.total_assets ?? 0}
//                     value={assets?.length ?? numberCards?.total_assets ?? 0}
//                     label={t('dashboard.totalAssets')}
//                     bgColor="bg-indigo-50 dark:bg-indigo-900/20"
//                   />
//                 </div>
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaShoppingCart className="text-purple-600" />}
//                     value={realWorkOrderCounts.open || (numberCards?.work_orders_open ?? 0)}
//                     label={t('dashboard.openWorkOrders')}
//                     bgColor="bg-purple-50 dark:bg-purple-900/20"
//                   />
//                 </div>
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaClock className="text-blue-600" />}
//                     value={realWorkOrderCounts.inProgress || (numberCards?.work_orders_in_progress ?? 0)}
//                     label={t('dashboard.workOrdersInProgress')}
//                     bgColor="bg-blue-50 dark:bg-blue-900/20"
//                   />
//                 </div>
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaExclamationTriangle className="text-orange-600" />}
//                     value={realWorkOrderCounts.pendingReview}
//                     label={t('dashboard.pendingReviewWorkOrders', 'Pending Review')}
//                     bgColor="bg-orange-50 dark:bg-orange-900/20"
//                   />
//                 </div>
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaCheckCircle className="text-pink-600" />}
//                     value={realWorkOrderCounts.completed || (numberCards?.work_orders_completed ?? 0)}
//                     label={t('dashboard.closedWorkOrders')}
//                     bgColor="bg-pink-50 dark:bg-pink-900/20"
//                   />
//                 </div>
//                 <div className="col-span-2">
//                   <StatCard
//                     icon={<FaChartLine className="text-purple-600" />}
//                     value={realWorkOrderCounts.total}
//                     label={t('dashboard.totalWorkOrders')}
//                     bgColor="bg-purple-50 dark:bg-purple-900/20"
//                   />
//                 </div>
//               </div>
//             </div>

//             <CompletionRateCard
//               totalWorkOrders={realWorkOrderCounts.total}
//               completedWorkOrders={realWorkOrderCounts.wfCompleted}
//               inProgressWorkOrders={realWorkOrderCounts.wfInProgress}
//               byTypeChartData={completionByTypeChartData}
//               onOpenReport={() => {
//                 const rates = completionByTypeChartData?.rates || [];
//                 setChartDetail({
//                   title: t('dashboard.completionRate', 'Completion Rate by Department'),
//                   data: {
//                     labels: rates.map((r: any) => r.type),
//                     datasets: [
//                       { name: 'Completion Rate (%)', values: rates.map((r: any) => parseFloat(r.rate.toFixed(2))) },
//                       { name: 'WF Completed', values: rates.map((r: any) => r.wfCompleted) },
//                       { name: 'Closed WOs', values: rates.map((r: any) => r.closed) },
//                       { name: 'Pending Review', values: rates.map((r: any) => r.pendingReview) },
//                       { name: 'Open', values: rates.map((r: any) => r.open) },
//                       { name: 'In Progress', values: rates.map((r: any) => r.inProgress) },
//                       { name: 'Total', values: rates.map((r: any) => r.total) },
//                     ],
//                     hideFooterTotal: true
//                   }
//                 });
//               }}
//             />
//           </div>

//           <div className="lg:col-span-5">
//             <GroupedChartCard
//               title={t('dashboard.assigneesStatus')}
//               data={assigneesGroupedChartData || assigneesChart}
//               onOpenReport={() => setChartDetail({ title: t('dashboard.assigneesStatus'), data: assigneesGroupedChartData || assigneesChart })}
//               showSummary
//             />
//           </div>
//         </div>

//         {/* Insights Row */}
//         <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
//           <InsightCard
//             icon={<FaExclamationTriangle className="text-red-500" />}
//             title={t('dashboard.assetsDown', 'Assets Down')}
//             value={insights.assetsDown}
//             trend={insights.assetsDown === 0 ? 'All Operational' : insights.assetsDown <= 3 ? 'Low' : 'High Priority'}
//             trendUp={insights.assetsDown === 0}
//             bgColor="bg-red-50 dark:bg-red-900/20"
//           />
//           <InsightCard
//             icon={<FaClock className="text-blue-500" />}
//             title={t('dashboard.avgResponseTime')}
//             value={insights.avgResponseTime > 0 ? `${insights.avgResponseTime.toFixed(1)} hrs` : 'N/A'}
//             trend={insights.avgResponseTime > 0 && insights.avgResponseTime < 4 ? 'Fast Response' : 'Monitor'}
//             trendUp={insights.avgResponseTime > 0 && insights.avgResponseTime < 4}
//             bgColor="bg-blue-50 dark:bg-blue-900/20"
//           />
//           <InsightCard
//             icon={<FaTools className="text-orange-500" />}
//             title={t('dashboard.maintenanceEfficiency')}
//             value={`${insights.maintenanceEfficiency.toFixed(1)}%`}
//             trend={insights.maintenanceEfficiency >= 70 ? 'On Track' : 'Needs Attention'}
//             trendUp={insights.maintenanceEfficiency >= 70}
//             bgColor="bg-orange-50 dark:bg-orange-900/20"
//           />
//           <InsightCard
//             icon={<FaExclamationTriangle className="text-red-500" />}
//             title={t('dashboard.overdueMaintenance')}
//             value={insights.overdueTasks}
//             trend={insights.overdueTasks === 0 ? 'All Clear' : insights.overdueTasks <= 3 ? 'Low' : 'High Priority'}
//             trendUp={insights.overdueTasks <= 3}
//             bgColor="bg-red-50 dark:bg-red-900/20"
//           />
//         </div>

//         {/* Additional Charts Section */}
//         <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6">
//           <DepartmentSalesCard 
//             data={workOrderChartData || workOrderChart}
//             totalWorkOrders={realWorkOrderCounts.total}
//             completedWorkOrders={realWorkOrderCounts.completed}
//             onOpenReport={() => setChartDetail({ title: 'Work Order Status Distribution', data: workOrderChartData || workOrderChart })}
//           />
//           <GroupedChartCard 
//             title={t('dashboard.workOrderStatus')} 
//             data={workOrderGroupedChartData || workOrderChart} 
//             onOpenReport={() => setChartDetail({ title: t('dashboard.workOrderStatus'), data: workOrderGroupedChartData || workOrderChart })}
//           />
//         </div>

//         {/* Technician Charts Section */}
//         <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6">
//           <TechnicianHoursChartCard 
//             title={t('dashboard.technicianWorkingHours', 'Technicians Working Hours')} 
//             data={technicianHoursData}
//             onOpenReport={() => setShowTechnicianHoursReport(true)}
//           />
//           <TechnicianWorkedChartCard 
//             title={t('dashboard.techniciansWorked', 'Technicians Work Summary')} 
//             data={technicianWorkedData}
//             onOpenReport={() => setShowTechnicianWorkOrderReport(true)}
//           />
//         </div>

//         {/* Inspection & Rejection Summary Section — System Manager / admin / Quality Supervisor only */}
//         {canSeeInspectionRejection && (
//         <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6">
//           <InspectionSummaryChartCard
//             title={t('dashboard.inspectionLinkedWOSummary', 'Inspection Linked Work Orders Summary')}
//             data={inspectionSummaryData}
//             onOpenReport={() => setShowInspectionReport(true)}
//           />
//           <RejectionSummaryChartCard
//             title={t('dashboard.woRejectionSummary', 'WO Rejection Summary')}
//             data={rejectionSummaryData}
//             onOpenReport={() => setShowRejectionReport(true)}
//           />
//         </div>
//         )}

//         {/* Time to Repair Section — System Manager / admin / Cluster Manager only */}
//         {canSeeTimeToRepair && (
//         <div className="grid grid-cols-1 gap-4 mb-6">
//           <TimeToRepairCard
//             data={timeToRepairData}
//             onOpenReport={() => setShowTimeToRepairReport(true)}
//           />
//         </div>
//         )}

//         {/* ← ADD HERE ↓ */}
//         <div className="grid grid-cols-1 gap-4 mb-6">
//           <RepairStatusCompletionCard
//             totalWorkOrders={realWorkOrderCounts.total}
//             closedWorkOrders={realWorkOrderCounts.completed}
//             byTypeChartData={completionByTypeChartData}
//           />
//         </div>
//         {/* ← ADD HERE ↑ */}

//       </div>
      
//       <TechnicianWorkingHoursReportModal
//         isOpen={showTechnicianHoursReport}
//         onClose={() => setShowTechnicianHoursReport(false)}
//         permittedIssueTypes={permittedIssueTypes}
//         isAdmin={isWoAdmin}
//         defaultWorkOrderType={selectedIssueType}
//       />
//       <TechnicianWorkOrderSummaryReportModal
//         isOpen={showTechnicianWorkOrderReport}
//         onClose={() => setShowTechnicianWorkOrderReport(false)}
//         permittedIssueTypes={permittedIssueTypes}
//         isAdmin={isWoAdmin}
//         defaultWorkOrderType={selectedIssueType}
//       />
//       {canSeeInspectionRejection && (
//         <InspectionSummaryReportModal
//           isOpen={showInspectionReport}
//           onClose={() => setShowInspectionReport(false)}
//           permittedIssueTypes={permittedIssueTypes}
//           isAdmin={isWoAdmin}
//           defaultWorkOrderType={selectedIssueType}
//         />
//       )}
//       {canSeeInspectionRejection && (
//         <RejectionSummaryReportModal
//           isOpen={showRejectionReport}
//           onClose={() => setShowRejectionReport(false)}
//           permittedIssueTypes={permittedIssueTypes}
//           isAdmin={isWoAdmin}
//           defaultWorkOrderType={selectedIssueType}
//         />
//       )}
//       {canSeeTimeToRepair && (
//         <TimeToRepairReportModal
//           isOpen={showTimeToRepairReport}
//           onClose={() => setShowTimeToRepairReport(false)}
//           permittedIssueTypes={permittedIssueTypes}
//           isAdmin={isWoAdmin}
//           defaultWorkOrderType={selectedIssueType}
//         />
//       )}
//       <ChartDetailModal
//         isOpen={!!chartDetail}
//         onClose={() => setChartDetail(null)}
//         title={chartDetail?.title || ''}
//         data={chartDetail?.data}
//       />
//     </div>
//   );
// };

// // ─── StatCard ────────────────────────────────────────────────────────────────
// const StatCard: React.FC<{ icon: React.ReactNode; value: string | number; label: string; bgColor: string }> = ({
//   icon, value, label, bgColor
// }) => (
//   <div className="text-center py-2 px-1 border-r border-gray-200 dark:border-gray-700 last:border-r-0">
//     <div className={`w-10 h-10 ${bgColor} rounded-lg flex items-center justify-center text-base mx-auto mb-1.5`}>
//       {icon}
//     </div>
//     <div className="text-lg font-semibold text-gray-900 dark:text-white leading-none mb-1">{value}</div>
//     <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide leading-tight px-1">{label}</div>
//   </div>
// );

// // ─── InsightCard ─────────────────────────────────────────────────────────────
// const InsightCard: React.FC<{
//   icon: React.ReactNode;
//   title: string;
//   value: string | number;
//   trend: string;
//   trendUp: boolean;
//   bgColor: string;
// }> = ({ icon, title, value, trend, trendUp, bgColor }) => (
//   <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-4 border border-gray-200 dark:border-gray-700">
//     <div className="flex items-start justify-between mb-3">
//       <div className={`w-10 h-10 ${bgColor} rounded-lg flex items-center justify-center text-lg`}>
//         {icon}
//       </div>
//       <div className={`flex items-center gap-1 text-xs font-medium ${trendUp ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'}`}>
//         {trendUp ? <FaArrowUp className="text-[10px]" /> : <FaArrowDown className="text-[10px]" />}
//         {trend}
//       </div>
//     </div>
//     <div className="text-2xl font-semibold text-gray-900 dark:text-white mb-1">{value}</div>
//     <div className="text-xs font-medium text-gray-600 dark:text-gray-400">{title}</div>
//   </div>
// );

// // ─── CompletionRateCard ───────────────────────────────────────────────────────
// const CompletionRateCard: React.FC<{
//   totalWorkOrders: number;
//   completedWorkOrders: number;
//   inProgressWorkOrders: number;
//   byTypeChartData: any;
//   onOpenReport?: () => void;
// }> = ({ totalWorkOrders, completedWorkOrders, inProgressWorkOrders, byTypeChartData, onOpenReport }) => {
//   const { t } = useTranslation();
//   const completionRate = totalWorkOrders > 0
//     ? ((completedWorkOrders / totalWorkOrders) * 100).toFixed(2)
//     : '0.00';

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all px-5 py-4 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-3">
//         <div>
//           <div className="text-2xl font-semibold text-gray-900 dark:text-white">{completionRate}%</div>
//           <div className="text-sm font-medium text-indigo-600 dark:text-indigo-400">{t('dashboard.completionRate', 'Completion Rate')}</div>
//         </div>
//       </div>

//       {byTypeChartData && byTypeChartData.rates?.length > 0 ? (
//         <CompletionByTypeBarChart data={byTypeChartData} />
//       ) : (
//         <div className="h-32 flex items-center justify-center text-gray-400 text-xs">
//           {t('dashboard.noDataAvailable', 'No data available')}
//         </div>
//       )}

//       <div className="grid grid-cols-3 gap-3 mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
//         <div className="text-center">
//           <div className="text-lg font-semibold text-indigo-600 dark:text-indigo-400">{totalWorkOrders}</div>
//           <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Total</div>
//         </div>
//         <div className="text-center">
//           <div className="text-lg font-semibold text-blue-600 dark:text-blue-400">{inProgressWorkOrders}</div>
//           <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">In Progress</div>
//         </div>
//         <div className="text-center">
//           <div className="text-lg font-semibold text-green-600 dark:text-green-400">{completedWorkOrders}</div>
//           <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Completed</div>
//         </div>
//       </div>
//     </div>
//   );
// };

// // ─── CompletionByTypeBarChart ─────────────────────────────────────────────────
// const CompletionByTypeBarChart: React.FC<{ data: any }> = ({ data }) => {
//   const { t } = useTranslation();
//   const [hoveredIdx, setHoveredIdx] = React.useState<number | null>(null);
//   const containerRef = React.useRef<HTMLDivElement>(null);
//   const [tooltipPos, setTooltipPos] = React.useState<{ x: number; y: number } | null>(null);

//   // FIX: Filter out null/unknown type entries before rendering
//   const allRates: Array<{
//     type: string;
//     total: number;
//     wfCompleted: number;
//     closed: number;
//     pendingReview: number;
//     open: number;
//     inProgress: number;
//     rate: number;
//   }> = data?.rates || [];

//   const rates = allRates.filter(item => !isNullOrUnknownLabel(item.type));

//   if (!rates.length) {
//     return (
//       <div className="h-32 flex items-center justify-center text-gray-400 text-xs">
//         {t('dashboard.noDataAvailable', 'No data available')}
//       </div>
//     );
//   }

//   const typeColors = generateColors(rates.length);

//   const chartH = 120;
//   const paddingLeft = 32;
//   const paddingRight = 12;
//   const paddingTop = 12;
//   const paddingBottom = 30;
//   const innerH = chartH - paddingTop - paddingBottom;
//   const numBars = rates.length;
//   const svgW = Math.max(260, numBars * 72 + paddingLeft + paddingRight);
//   const innerW = svgW - paddingLeft - paddingRight;
//   const groupW = innerW / numBars;
//   const barW = Math.min(44, groupW * 0.55);

//   const gridRatios = [0, 0.25, 0.5, 0.75, 1];

//   const handleMouseEnter = (idx: number, e: React.MouseEvent<SVGGElement>) => {
//     setHoveredIdx(idx);
//     if (containerRef.current) {
//       const containerRect = containerRef.current.getBoundingClientRect();
//       const svgEl = e.currentTarget.ownerSVGElement as SVGSVGElement;
//       const svgRect = svgEl.getBoundingClientRect();
//       const scaleX = svgRect.width / svgW;
//       const barCentreViewBox = paddingLeft + idx * groupW + groupW / 2;
//       const barCentrePixel = svgRect.left - containerRect.left + barCentreViewBox * scaleX;
//       setTooltipPos({ x: barCentrePixel, y: 0 });
//     }
//   };

//   return (
//     <div className="w-full relative" ref={containerRef}>
//       <div className="overflow-x-auto">
//         <svg
//           width="100%"
//           height={chartH}
//           viewBox={`0 0 ${svgW} ${chartH}`}
//           preserveAspectRatio="xMidYMid meet"
//           className="w-full"
//           onMouseLeave={() => { setHoveredIdx(null); setTooltipPos(null); }}
//         >
//           {gridRatios.map((ratio, i) => {
//             const y = paddingTop + innerH - ratio * innerH;
//             return (
//               <g key={i}>
//                 <line x1={paddingLeft} y1={y} x2={svgW - paddingRight} y2={y} stroke="#E5E7EB" strokeWidth="1" className="dark:stroke-gray-700" />
//                 <text x={paddingLeft - 3} y={y + 3} textAnchor="end" fontSize="7" fill="#9CA3AF">
//                   {Math.round(ratio * 100)}%
//                 </text>
//               </g>
//             );
//           })}
//           <line x1={paddingLeft} y1={paddingTop + innerH} x2={svgW - paddingRight} y2={paddingTop + innerH} stroke="#D1D5DB" strokeWidth="1" />

//           {rates.map((item, idx) => {
//             const barH = Math.max(0, (item.rate / 100) * innerH);
//             const cx = paddingLeft + idx * groupW + groupW / 2;
//             const bX = cx - barW / 2;
//             const bY = paddingTop + innerH - barH;
//             const color = typeColors[idx];
//             const isHovered = hoveredIdx === idx;

//             return (
//               <g key={idx} onMouseEnter={(e) => handleMouseEnter(idx, e)} style={{ cursor: 'pointer' }}>
//                 <rect x={paddingLeft + idx * groupW} y={paddingTop} width={groupW} height={innerH} fill="transparent" />
//                 <rect
//                   x={bX} y={barH > 0 ? bY : paddingTop + innerH - 1}
//                   width={barW} height={barH > 0 ? barH : 1}
//                   fill={color} rx="4" ry="4"
//                   opacity={isHovered ? 1 : 0.80}
//                   style={{ transition: 'opacity 0.15s, filter 0.15s', filter: isHovered ? 'brightness(1.15)' : 'none' }}
//                 />
//                 {barH > 14 && (
//                   <text x={cx} y={bY - 3} textAnchor="middle" fontSize="7.5" fontWeight="700" fill={color}>
//                     {item.rate.toFixed(1)}%
//                   </text>
//                 )}
//                 <text
//                   x={cx} y={paddingTop + innerH + 13}
//                   textAnchor="middle" fontSize="6.5"
//                   fill={isHovered ? color : '#6B7280'}
//                   fontWeight={isHovered ? '700' : '400'}
//                 >
//                   {(item.type || '').length > 11 ? (item.type || '').substring(0, 9) + '…' : (item.type || '')}
//                 </text>
//               </g>
//             );
//           })}
//         </svg>
//       </div>

//       {hoveredIdx !== null && tooltipPos && rates[hoveredIdx] && (() => {
//         const item = rates[hoveredIdx];
//         const color = typeColors[hoveredIdx];
//         return (
//           <div className="absolute pointer-events-none z-30" style={{ left: tooltipPos.x, top: 4, transform: 'translateX(-50%)', minWidth: 160 }}>
//             <div className="bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-xl shadow-2xl px-3 py-2">
//               <div className="flex items-center gap-1.5 mb-1 pb-1 border-b border-white/20">
//                 <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: color }} />
//                 <span className="font-semibold text-[11px] leading-tight truncate max-w-[130px]">{item.type || 'Unknown'}</span>
//               </div>
//               <div className="text-green-400 font-bold text-sm text-center">{item.rate.toFixed(2)}% Completion Rate</div>
//             </div>
//             <div className="w-2.5 h-2.5 bg-gray-900 dark:bg-gray-700 rotate-45 mx-auto -mt-1.5" />
//           </div>
//         );
//       })()}

//       <div className="flex flex-wrap items-center gap-x-4 gap-y-1 mt-2 pt-2 border-t border-gray-100 dark:border-gray-700">
//         {rates.map((item, idx) => (
//           <div key={idx} className="flex items-center gap-1.5">
//             <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[idx] }} />
//             <span className="text-[10px] text-gray-600 dark:text-gray-400 leading-tight">
//               {(item.type || '').length > 22 ? (item.type || '').substring(0, 20) + '…' : (item.type || '')}
//             </span>
//           </div>
//         ))}
//       </div>
//     </div>
//   );
// };

// // ─── RepairStatusCompletionCard ───────────────────────────────────────────────
// const RepairStatusCompletionCard: React.FC<{
//   totalWorkOrders: number;
//   closedWorkOrders: number;
//   byTypeChartData: any;
// }> = ({ totalWorkOrders, closedWorkOrders, byTypeChartData }) => {
//   const { t } = useTranslation();

//   const completionRate = totalWorkOrders > 0
//     ? ((closedWorkOrders / totalWorkOrders) * 100).toFixed(2)
//     : '0.00';

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all px-5 py-4 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-3">
//         <div>
//           <div className="text-2xl font-semibold text-gray-900 dark:text-white">{completionRate}%</div>
//           <div className="text-sm font-medium text-emerald-600 dark:text-emerald-400">
//             Overall Completion Rate
//           </div>
//         </div>
//       </div>

//       {byTypeChartData && byTypeChartData.rates?.length > 0 ? (
//         <RepairStatusCompletionBarChart data={byTypeChartData} />
//       ) : (
//         <div className="h-32 flex items-center justify-center text-gray-400 text-xs">
//           {t('dashboard.noDataAvailable', 'No data available')}
//         </div>
//       )}

//       <div className="grid grid-cols-2 gap-3 mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
//         <div className="text-center">
//           <div className="text-lg font-semibold text-emerald-600 dark:text-emerald-400">{totalWorkOrders}</div>
//           <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Total</div>
//         </div>
//         <div className="text-center">
//           <div className="text-lg font-semibold text-green-600 dark:text-green-400">{closedWorkOrders}</div>
//           <div className="text-[9px] font-medium text-gray-500 dark:text-gray-400 uppercase">Closed</div>
//         </div>
//       </div>
//     </div>
//   );
// };

// // ─── RepairStatusCompletionBarChart ───────────────────────────────────────────
// const RepairStatusCompletionBarChart: React.FC<{ data: any }> = ({ data }) => {
//   const { t } = useTranslation();
//   const [hoveredIdx, setHoveredIdx] = React.useState<number | null>(null);
//   const containerRef = React.useRef<HTMLDivElement>(null);
//   const [tooltipPos, setTooltipPos] = React.useState<{ x: number; y: number } | null>(null);

//   const allRates: Array<{
//     type: string;
//     total: number;
//     closed: number;
//   }> = (data?.rates || []).filter((item: any) => !isNullOrUnknownLabel(item.type));

//   if (!allRates.length) {
//     return (
//       <div className="h-32 flex items-center justify-center text-gray-400 text-xs">
//         {t('dashboard.noDataAvailable', 'No data available')}
//       </div>
//     );
//   }

//   // Recalculate rate using repair_status closed (not wfCompleted)
//   const rates = allRates.map(item => ({
//     type: item.type,
//     total: item.total,
//     closed: item.closed,
//     rate: item.total > 0 ? (item.closed / item.total) * 100 : 0,
//   }));

//   const typeColors = generateColors(rates.length);

//   const chartH = 120;
//   const paddingLeft = 32;
//   const paddingRight = 12;
//   const paddingTop = 12;
//   const paddingBottom = 30;
//   const innerH = chartH - paddingTop - paddingBottom;
//   const numBars = rates.length;
//   const svgW = Math.max(260, numBars * 72 + paddingLeft + paddingRight);
//   const innerW = svgW - paddingLeft - paddingRight;
//   const groupW = innerW / numBars;
//   const barW = Math.min(44, groupW * 0.55);
//   const gridRatios = [0, 0.25, 0.5, 0.75, 1];

//   const handleMouseEnter = (idx: number, e: React.MouseEvent<SVGGElement>) => {
//     setHoveredIdx(idx);
//     if (containerRef.current) {
//       const containerRect = containerRef.current.getBoundingClientRect();
//       const svgEl = e.currentTarget.ownerSVGElement as SVGSVGElement;
//       const svgRect = svgEl.getBoundingClientRect();
//       const scaleX = svgRect.width / svgW;
//       const barCentreViewBox = paddingLeft + idx * groupW + groupW / 2;
//       const barCentrePixel = svgRect.left - containerRect.left + barCentreViewBox * scaleX;
//       setTooltipPos({ x: barCentrePixel, y: 0 });
//     }
//   };

//   return (
//     <div className="w-full relative" ref={containerRef}>
//       <div className="overflow-x-auto">
//         <svg
//           width="100%"
//           height={chartH}
//           viewBox={`0 0 ${svgW} ${chartH}`}
//           preserveAspectRatio="xMidYMid meet"
//           className="w-full"
//           onMouseLeave={() => { setHoveredIdx(null); setTooltipPos(null); }}
//         >
//           {gridRatios.map((ratio, i) => {
//             const y = paddingTop + innerH - ratio * innerH;
//             return (
//               <g key={i}>
//                 <line x1={paddingLeft} y1={y} x2={svgW - paddingRight} y2={y} stroke="#E5E7EB" strokeWidth="1" className="dark:stroke-gray-700" />
//                 <text x={paddingLeft - 3} y={y + 3} textAnchor="end" fontSize="7" fill="#9CA3AF">
//                   {Math.round(ratio * 100)}%
//                 </text>
//               </g>
//             );
//           })}
//           <line x1={paddingLeft} y1={paddingTop + innerH} x2={svgW - paddingRight} y2={paddingTop + innerH} stroke="#D1D5DB" strokeWidth="1" />

//           {rates.map((item, idx) => {
//             const barH = Math.max(0, (item.rate / 100) * innerH);
//             const cx = paddingLeft + idx * groupW + groupW / 2;
//             const bX = cx - barW / 2;
//             const bY = paddingTop + innerH - barH;
//             const color = typeColors[idx];
//             const isHovered = hoveredIdx === idx;

//             return (
//               <g key={idx} onMouseEnter={(e) => handleMouseEnter(idx, e)} style={{ cursor: 'pointer' }}>
//                 <rect x={paddingLeft + idx * groupW} y={paddingTop} width={groupW} height={innerH} fill="transparent" />
//                 <rect
//                   x={bX} y={barH > 0 ? bY : paddingTop + innerH - 1}
//                   width={barW} height={barH > 0 ? barH : 1}
//                   fill={color} rx="4" ry="4"
//                   opacity={isHovered ? 1 : 0.80}
//                   style={{ transition: 'opacity 0.15s, filter 0.15s', filter: isHovered ? 'brightness(1.15)' : 'none' }}
//                 />
//                 {barH > 14 && (
//                   <text x={cx} y={bY - 3} textAnchor="middle" fontSize="7.5" fontWeight="700" fill={color}>
//                     {item.rate.toFixed(1)}%
//                   </text>
//                 )}
//                 <text
//                   x={cx} y={paddingTop + innerH + 13}
//                   textAnchor="middle" fontSize="6.5"
//                   fill={isHovered ? color : '#6B7280'}
//                   fontWeight={isHovered ? '700' : '400'}
//                 >
//                   {(item.type || '').length > 11 ? (item.type || '').substring(0, 9) + '…' : (item.type || '')}
//                 </text>
//               </g>
//             );
//           })}
//         </svg>
//       </div>

//       {hoveredIdx !== null && tooltipPos && rates[hoveredIdx] && (() => {
//         const item = rates[hoveredIdx];
//         const color = typeColors[hoveredIdx];
//         return (
//           <div className="absolute pointer-events-none z-30" style={{ left: tooltipPos.x, top: 4, transform: 'translateX(-50%)', minWidth: 160 }}>
//             <div className="bg-gray-900 dark:bg-gray-700 text-white text-xs rounded-xl shadow-2xl px-3 py-2">
//               <div className="flex items-center gap-1.5 mb-1 pb-1 border-b border-white/20">
//                 <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: color }} />
//                 <span className="font-semibold text-[11px] leading-tight truncate max-w-[130px]">{item.type}</span>
//               </div>
//               <div className="text-green-400 font-bold text-sm text-center mb-1">{item.rate.toFixed(2)}% Closed</div>
//               <div className="text-gray-300 text-[10px] text-center">{item.closed} closed / {item.total} total</div>
//             </div>
//             <div className="w-2.5 h-2.5 bg-gray-900 dark:bg-gray-700 rotate-45 mx-auto -mt-1.5" />
//           </div>
//         );
//       })()}

//       <div className="flex flex-wrap items-center gap-x-4 gap-y-1 mt-2 pt-2 border-t border-gray-100 dark:border-gray-700">
//         {rates.map((item, idx) => (
//           <div key={idx} className="flex items-center gap-1.5">
//             <div className="w-2.5 h-2.5 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[idx] }} />
//             <span className="text-[10px] text-gray-600 dark:text-gray-400 leading-tight">
//               {(item.type || '').length > 22 ? (item.type || '').substring(0, 20) + '…' : (item.type || '')}
//             </span>
//           </div>
//         ))}
//       </div>
//     </div>
//   );
// };


// // ─── DepartmentSalesCard ──────────────────────────────────────────────────────
// const DepartmentSalesCard: React.FC<{ data: any; totalWorkOrders: number; completedWorkOrders: number; onOpenReport?: () => void }> = ({
//   data, totalWorkOrders, completedWorkOrders, onOpenReport
// }) => {
//   const { t } = useTranslation();
//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all px-5 py-5 border border-gray-200 dark:border-gray-700 flex flex-col" style={{ minHeight: '100%' }}>
//       <div className="flex items-center justify-between mb-4 flex-shrink-0">
//         <div>
//           <h3 className="text-base font-semibold text-gray-900 dark:text-white">Work Order Status Distribution</h3>
//           <div className="flex items-center gap-3 mt-1">
//             <div className="text-xl font-semibold text-gray-900 dark:text-white">{totalWorkOrders} Total</div>
//           </div>
//         </div>
//         <div className="flex items-center gap-2">
//           <button onClick={onOpenReport} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg" title={t('dashboard.viewFullReport')}>
//             <FaExternalLinkAlt className="w-4 h-4 text-gray-500" />
//           </button>
//         </div>
//       </div>
//       <div className="flex-1">
//         {data && (data?.labels?.length || data?.datasets?.[0]?.values?.length) ? (
//           <PieChart data={data} />
//         ) : (
//           <div className="h-64 flex items-center justify-center text-gray-400">{t('dashboard.noDataAvailable')}</div>
//         )}
//       </div>
//     </div>
//   );
// };

// // ─── GroupedBarChart ──────────────────────────────────────────────────────────
// const GroupedBarChart: React.FC<{ data: any }> = ({ data }) => {
//   const { t } = useTranslation();
//   const labels = data?.labels || [];
//   const datasets = data?.datasets || [];

//   if (!datasets.length) {
//     return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
//   }

//   const allValues = datasets.flatMap((ds: any) => ds.values || []);
//   const max = Math.max(...allValues, 1);
//   const chartHeight = 240;
//   const width = Math.max(800, labels.length * 100);
//   const groupWidth = Math.min(120, (width - 100) / labels.length);
//   const barSpacing = 4;
//   const numBars = datasets.length;
//   const barWidth = Math.max(12, (groupWidth - barSpacing * (numBars + 1)) / numBars);

//   const statusColors: Record<string, string> = {
//     'Completed On Time': '#6366F1',
//     'Completed Within SLA': '#3B82F6',
//     'Delay In Completion': '#8B5CF6',
//     'Pending': '#A855F7',
//     'Overdue': '#EC4899',
//     'Cancelled': '#0EA5E9',
//     'Open': '#6366F1',
//     'Work In Progress': '#3B82F6',
//     'Pending Review': '#8B5CF6',
//     'Completed': '#6366F1',
//     'Closed': '#A855F7',
//   };

//   const getDatasetColor = (datasetName: string, index: number): string => {
//     for (const [key, color] of Object.entries(statusColors)) {
//       if (datasetName.toLowerCase().includes(key.toLowerCase())) return color;
//     }
//     return generateColors(numBars)[index];
//   };

//   return (
//     <div className="relative w-full overflow-x-auto">
//       <svg width="100%" height={chartHeight + 40} viewBox={`0 0 ${width} ${chartHeight + 40}`} className="w-full" preserveAspectRatio="xMidYMid meet">
//         <defs>
//           {datasets.map((ds: any, i: number) => {
//             const color = getDatasetColor(ds.name || '', i);
//             return (
//               <linearGradient key={i} id={`groupedBarGradient${i}`} x1="0%" y1="0%" x2="0%" y2="100%">
//                 <stop offset="0%" style={{ stopColor: color, stopOpacity: 0.9 }} />
//                 <stop offset="100%" style={{ stopColor: color, stopOpacity: 0.7 }} />
//               </linearGradient>
//             );
//           })}
//         </defs>
//         {[0, 0.25, 0.5, 0.75, 1].map((ratio, i) => (
//           <line key={i} x1="60" y1={chartHeight - (ratio * chartHeight)} x2={width - 20} y2={chartHeight - (ratio * chartHeight)} stroke="#E5E7EB" strokeWidth="1" className="dark:stroke-gray-700" />
//         ))}
//         {[0, 0.25, 0.5, 0.75, 1].map((ratio, i) => (
//           <text key={i} x="45" y={chartHeight - (ratio * chartHeight) + 4} textAnchor="end" className="text-xs fill-gray-400 dark:fill-gray-500">
//             {(max * ratio).toFixed(ratio === 0 ? 0 : max < 5 ? 1 : 0)}
//           </text>
//         ))}
//         <text x="15" y={chartHeight / 2} textAnchor="middle" transform={`rotate(-90, 15, ${chartHeight / 2})`} className="text-xs fill-gray-600 dark:fill-gray-400 font-medium">Count</text>
//         {labels.map((label: string, labelIndex: number) => {
//           const groupX = 80 + (labelIndex * groupWidth);
//           return (
//             <g key={labelIndex}>
//               {datasets.map((dataset: any, dsIndex: number) => {
//                 const value = dataset.values?.[labelIndex] || 0;
//                 const barHeight = (value / max) * chartHeight;
//                 const x = groupX + barSpacing + (dsIndex * (barWidth + barSpacing));
//                 const y = chartHeight - barHeight;
//                 const color = getDatasetColor(dataset.name || '', dsIndex);
//                 return (
//                   <g key={dsIndex}>
//                     <rect x={x} y={y} width={barWidth} height={barHeight} fill={color} rx="4" ry="4" className="hover:opacity-80 cursor-pointer transition-opacity">
//                       <title>{`${label || 'Unknown'} — ${dataset.name || 'Series'}: ${value}`}</title>
//                     </rect>
//                   </g>
//                 );
//               })}
//               <text x={groupX + groupWidth / 2} y={chartHeight + 15} textAnchor="middle" className="text-xs fill-gray-600 dark:fill-gray-400">
//                 {label && label.length > 12 ? label.substring(0, 10) + '...' : label || 'null'}
//               </text>
//             </g>
//           );
//         })}
//       </svg>
//       <div className="flex flex-wrap items-center justify-center gap-2 mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
//         {datasets.map((dataset: any, i: number) => {
//           const color = getDatasetColor(dataset.name || '', i);
//           return (
//             <div key={i} className="flex items-center gap-1.5">
//               <div className="w-2.5 h-2.5 rounded" style={{ backgroundColor: color }}></div>
//               <span className="text-xs text-gray-600 dark:text-gray-400">
//                 {dataset.name && dataset.name.length > 20 ? dataset.name.substring(0, 18) + '...' : dataset.name || `Series ${i + 1}`}
//               </span>
//             </div>
//           );
//         })}
//       </div>
//     </div>
//   );
// };

// // ─── StackedBarChart ──────────────────────────────────────────────────────────
// const StackedBarChart: React.FC<{ data: any }> = ({ data }) => {
//   const { t } = useTranslation();
//   const labels = data?.labels || [];
//   const datasets = data?.datasets || [];

//   if (!datasets.length) {
//     return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
//   }

//   const totalsProvided = Array.isArray(data?.totals) && data.totals.length === labels.length;
//   const stackedTotals = totalsProvided
//     ? data.totals
//     : labels.map((_: string, labelIndex: number) =>
//         datasets.reduce((sum: number, ds: any) => sum + (ds.values?.[labelIndex] || 0), 0)
//       );

//   const maxTotal = Math.max(...stackedTotals, 1);

//   const stackColors: Record<string, string> = {
//     total: '#6366F1',
//     completed: '#10B981',
//     in_progress: '#3B82F6',
//     open: '#F59E0B',
//   };

//   const getStackColor = (datasetName: string, index: number): string => {
//     const nameLower = datasetName.toLowerCase();
//     for (const [key, color] of Object.entries(stackColors)) {
//       if (nameLower.includes(key)) return color;
//     }
//     return generateColors(datasets.length)[index];
//   };

//   const getRowTooltip = (labelIndex: number) => {
//     const total = stackedTotals[labelIndex];
//     const parts = datasets
//       .map((ds: any) => {
//         const value = ds.values?.[labelIndex] || 0;
//         if (value === 0) return null;
//         const name = (ds.name || '').replace(/_/g, ' ');
//         return `${name}: ${value}`;
//       })
//       .filter(Boolean);
//     return [...parts, `Total: ${total}`].join('  •  ');
//   };

//   return (
//     <div className="space-y-2 max-h-72 overflow-y-auto">
//       {labels.map((label: string, labelIndex: number) => {
//         const total = stackedTotals[labelIndex];
//         return (
//           <div key={labelIndex} className="flex items-center gap-2">
//             <div className="w-32 text-xs text-gray-700 dark:text-gray-200 truncate" title={label}>{label}</div>
//             <div className="flex-1 h-4 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden flex cursor-default" title={getRowTooltip(labelIndex)}>
//               {datasets.map((ds: any, dsIndex: number) => {
//                 const value = ds.values?.[labelIndex] || 0;
//                 if (!value) return null;
//                 const widthPercent = (value / maxTotal) * 100;
//                 const color = getStackColor(ds.name || '', dsIndex);
//                 return <div key={ds.name} className="h-full" style={{ width: `${widthPercent}%`, backgroundColor: color }} />;
//               })}
//             </div>
//             <div className="w-10 text-xs text-right text-gray-500 dark:text-gray-400">{total}</div>
//           </div>
//         );
//       })}
//       <div className="flex flex-wrap items-center gap-3 pt-2 border-t border-gray-200 dark:border-gray-700 mt-2">
//         {datasets.map((dataset: any, index: number) => (
//           <div key={dataset.name || index} className="flex items-center gap-1 text-[11px] text-gray-600 dark:text-gray-300">
//             <span className="inline-block w-3 h-3 rounded-sm" style={{ backgroundColor: getStackColor(dataset.name || '', index) }} />
//             <span>{(dataset.name || `Series ${index + 1}`).replace(/_/g, ' ')}</span>
//           </div>
//         ))}
//       </div>
//     </div>
//   );
// };

// // ─── TechnicianHoursChartCard ─────────────────────────────────────────────────
// const TechnicianHoursChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
//   const { t } = useTranslation();
//   const [showMenu, setShowMenu] = useState(false);

//   const totalHours = React.useMemo(() => {
//     if (!data?.datasets?.[0]?.values) return 0;
//     return data.datasets[0].values.reduce((sum: number, val: number) => sum + val, 0);
//   }, [data]);

//   useEffect(() => {
//     const handleClickOutside = () => setShowMenu(false);
//     if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
//   }, [showMenu]);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-4">
//         <div className="flex items-center gap-3">
//           <button onClick={onOpenReport} className="w-10 h-10 bg-indigo-50 dark:bg-indigo-900/20 rounded-lg flex items-center justify-center hover:bg-indigo-100 dark:hover:bg-indigo-900/40 transition-colors cursor-pointer group" title={t('dashboard.viewFullReport')}>
//             <FaUserClock className="text-indigo-600 text-lg group-hover:scale-110 transition-transform" />
//           </button>
//           <div>
//             <h3 className="text-base font-semibold text-gray-900 dark:text-white">{title}</h3>
//             <p className="text-xs text-gray-500 dark:text-gray-400">Total: {totalHours.toFixed(1)} hours</p>
//           </div>
//         </div>
//         <div className="relative">
//           <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
//             <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
//           </button>
//           {showMenu && (
//             <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
//               <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
//                 <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport')}
//               </button>
//             </div>
//           )}
//         </div>
//       </div>
//       {!data || !data.datasets || !data.datasets.length ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaUserClock className="text-4xl mx-auto mb-2 opacity-50" /><div className="text-sm">{t('dashboard.loadingTechnicianHours', 'Loading...')}</div></div>
//         </div>
//       ) : (
//         <HorizontalBarChart data={data} valueLabel="hrs" />
//       )}
//     </div>
//   );
// };

// // ─── TechnicianWorkedChartCard ────────────────────────────────────────────────
// const TechnicianWorkedChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
//   const { t } = useTranslation();
//   const [showMenu, setShowMenu] = useState(false);

//   const totals = React.useMemo(() => {
//     if (!data?.datasets) return { total: 0, completed: 0, inProgress: 0, open: 0 };
//     const result = { total: 0, completed: 0, inProgress: 0, open: 0 };
//     data.datasets.forEach((ds: any) => {
//       const sum = ds.values?.reduce((s: number, v: number) => s + v, 0) || 0;
//       if (ds.name === 'total') result.total = sum;
//       else if (ds.name === 'completed') result.completed = sum;
//       else if (ds.name === 'in_progress') result.inProgress = sum;
//       else if (ds.name === 'open') result.open = sum;
//     });
//     return result;
//   }, [data]);

//   useEffect(() => {
//     const handleClickOutside = () => setShowMenu(false);
//     if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
//   }, [showMenu]);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-4">
//         <div className="flex items-center gap-3">
//           <button onClick={onOpenReport} className="w-10 h-10 bg-purple-50 dark:bg-purple-900/20 rounded-lg flex items-center justify-center hover:bg-purple-100 dark:hover:bg-purple-900/40 transition-colors cursor-pointer group" title={t('dashboard.viewFullReport')}>
//             <FaHardHat className="text-purple-600 text-lg group-hover:scale-110 transition-transform" />
//           </button>
//           <div>
//             <h3 className="text-base font-semibold text-gray-900 dark:text-white">{title}</h3>
//             <div className="flex items-center gap-2 text-xs text-gray-500 dark:text-gray-400">
//               <span className="text-green-600">{totals.completed} completed</span>
//               <span>•</span>
//               <span className="text-blue-600">{totals.inProgress} in progress</span>
//               <span>•</span>
//               <span className="text-amber-600">{totals.open} open</span>
//             </div>
//           </div>
//         </div>
//         <div className="relative">
//           <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
//             <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
//           </button>
//           {showMenu && (
//             <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
//               <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
//                 <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport')}
//               </button>
//             </div>
//           )}
//         </div>
//       </div>
//       {!data || !data.datasets || !data.datasets.length ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaHardHat className="text-4xl mx-auto mb-2 opacity-50" /><div className="text-sm">{t('dashboard.loadingTechnicianWorkData', 'Loading...')}</div></div>
//         </div>
//       ) : (
//         <StackedBarChart data={data} />
//       )}
//     </div>
//   );
// };

// // ─── HorizontalBarChart (NO legend – legend removed as requested) ──────────────
// const HorizontalBarChart: React.FC<{ data: any; valueLabel?: string }> = ({ data, valueLabel = '' }) => {
//   const { t } = useTranslation();
//   const labels = data?.labels || [];
//   const values = data?.datasets?.[0]?.values || [];

//   if (!values.length) {
//     return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
//   }

//   const max = Math.max(...values, 1);

//   return (
//     <div className="space-y-3">
//       {labels.map((label: string, i: number) => {
//         const value = values[i] || 0;
//         const percentage = (value / max) * 100;
//         return (
//           <div key={i} className="flex items-center gap-3">
//             <div className="w-28 text-xs text-gray-600 dark:text-gray-400 truncate text-right" title={label || '(No Type)'}>
//               {label || '(No Type)'}
//             </div>
//             <div className="flex-1 h-6 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
//               <div className="h-full bg-gradient-to-r from-indigo-500 to-purple-500 rounded-full transition-all duration-500" style={{ width: `${percentage}%` }} />
//             </div>
//             <div className="w-10 text-xs font-semibold text-gray-800 dark:text-gray-200 text-right">
//               {typeof value === 'number' ? (Number.isInteger(value) ? value : value.toFixed(1)) : value}{valueLabel ? ` ${valueLabel}` : ''}
//             </div>
//           </div>
//         );
//       })}
//     </div>
//   );
// };

// // ─── RejectionHorizontalBarChart (NO legend – legend removed as requested) ────
// const RejectionHorizontalBarChart: React.FC<{ data: any }> = ({ data }) => {
//   const { t } = useTranslation();
//   const labels = data?.labels || [];
//   const values = data?.datasets?.[0]?.values || [];

//   if (!values.length) {
//     return <div className="text-center text-gray-400 py-4 text-sm">{t('dashboard.noDataAvailable')}</div>;
//   }

//   const max = Math.max(...values, 1);

//   return (
//     <div className="space-y-3">
//       {labels.map((label: string, i: number) => {
//         const value = values[i] || 0;
//         const percentage = (value / max) * 100;
//         return (
//           <div key={i} className="flex items-center gap-3">
//             <div className="w-32 text-xs text-gray-600 dark:text-gray-400 truncate text-right" title={label || '(No Type)'}>
//               {label || '(No Type)'}
//             </div>
//             <div className="flex-1 h-6 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
//               <div
//                 className="h-full rounded-full transition-all duration-500"
//                 style={{ width: `${percentage}%`, background: 'linear-gradient(to right, #EF4444, #F87171)' }}
//               />
//             </div>
//             <div className="w-10 text-xs font-semibold text-red-600 dark:text-red-400 text-right">
//               {typeof value === 'number' ? (Number.isInteger(value) ? value : value.toFixed(1)) : value}
//             </div>
//           </div>
//         );
//       })}
//     </div>
//   );
// };

// // ─── PieChart ─────────────────────────────────────────────────────────────────
// const PieChart: React.FC<{ data: any }> = ({ data }) => {
//   const labels = data?.labels || [];
//   const values = data?.datasets?.[0]?.values || [];

//   const isUpDownTimeChart = labels.some((label: string) =>
//     label.toLowerCase().includes('up time') || label.toLowerCase().includes('down time') ||
//     label.toLowerCase().includes('uptime') || label.toLowerCase().includes('downtime')
//   );

//   let colors: string[] = [];
//   if (isUpDownTimeChart && labels.length >= 1) {
//     colors = labels.map((label: string) => {
//       const labelLower = label.toLowerCase();
//       if (labelLower.includes('up time') || labelLower.includes('uptime')) return '#6366F1';
//       if (labelLower.includes('down time') || labelLower.includes('downtime')) return '#8B5CF6';
//       const index = labels.indexOf(label);
//       return index === 0 ? '#6366F1' : '#8B5CF6';
//     });
//   } else {
//     const datasetColors = data?.datasets?.[0]?.colors;
//     colors = datasetColors && datasetColors.length === values.length ? datasetColors : generateColors(values.length);
//   }

//   const total = values.reduce((sum: number, val: number) => sum + val, 0);
//   const radius = 100;
//   const cx = radius + 10;
//   const cy = radius + 10;

//   let cumulative = 0;
//   const slices = values.map((value: number, i: number) => {
//     const startAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
//     cumulative += value;
//     const endAngle = (cumulative / total) * 2 * Math.PI - Math.PI / 2;
//     const largeArc = endAngle - startAngle > Math.PI ? 1 : 0;
//     const x1 = cx + radius * Math.cos(startAngle);
//     const y1 = cy + radius * Math.sin(startAngle);
//     const x2 = cx + radius * Math.cos(endAngle);
//     const y2 = cy + radius * Math.sin(endAngle);
//     return {
//       path: `M ${cx} ${cy} L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2} Z`,
//       color: colors[i], label: labels[i], value,
//       percentage: ((value / total) * 100).toFixed(1)
//     };
//   });

//   return (
//     <div className="flex flex-col md:flex-row items-center justify-around">
//       <svg width={cx * 2} height={cy * 2} viewBox={`0 0 ${cx * 2} ${cy * 2}`} className="max-w-xs">
//         {slices.map((slice: any, i: number) => (
//           <path key={i} d={slice.path} fill={slice.color} className="hover:opacity-80 transition-opacity cursor-pointer drop-shadow-lg">
//             <title>{`${slice.label}: ${slice.value} (${slice.percentage}%)`}</title>
//           </path>
//         ))}
//       </svg>
//       <div className="flex flex-col gap-3 mt-4 md:mt-0">
//         {slices.map((slice: any, i: number) => (
//           <div key={i} className="flex items-center gap-3">
//             <div className="w-3 h-3 rounded-full" style={{ backgroundColor: slice.color }}></div>
//             <span className="text-sm text-gray-700 dark:text-gray-300">{slice.label}</span>
//             <span className="text-sm font-bold text-gray-900 dark:text-white">{slice.value}</span>
//           </div>
//         ))}
//       </div>
//     </div>
//   );
// };

// // ─── GroupedChartCard ─────────────────────────────────────────────────────────
// const GroupedChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void; showSummary?: boolean }> = ({ title, data, onOpenReport, showSummary }) => {
//   const { t } = useTranslation();
//   const labels = data?.labels || [];
//   const datasets = data?.datasets || [];
//   const totalAssignees = labels.length;
//   const totalTasks = datasets.reduce((sum: number, ds: any) => sum + (ds.values || []).reduce((a: number, b: number) => a + b, 0), 0);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-3 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-2">
//         <h3 className="text-sm font-semibold text-gray-800 dark:text-white">{title}</h3>
//         <button onClick={onOpenReport} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg" title={t('dashboard.viewFullReport')}>
//           <FaExternalLinkAlt className="w-3.5 h-3.5 text-gray-500" />
//         </button>
//       </div>
//       {!data || !datasets.length ? (
//         <div className="h-48 flex items-center justify-center text-gray-400"><div className="text-xs">No chart data available</div></div>
//       ) : (
//         <>
//           <GroupedBarChart data={data} />
//           {showSummary && totalAssignees > 0 && (
//             <div className="grid grid-cols-2 gap-2 mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
//               <div className="bg-indigo-50 dark:bg-indigo-900/20 rounded-lg px-3 py-2 text-center">
//                 <div className="text-lg font-bold text-indigo-600 dark:text-indigo-400">{totalAssignees}</div>
//                 <div className="text-[10px] text-gray-600 dark:text-gray-400 uppercase tracking-wide">Assignees</div>
//               </div>
//               <div className="bg-purple-50 dark:bg-purple-900/20 rounded-lg px-3 py-2 text-center">
//                 <div className="text-lg font-bold text-purple-600 dark:text-purple-400">{totalTasks}</div>
//                 <div className="text-[10px] text-gray-600 dark:text-gray-400 uppercase tracking-wide">Tasks Assigned</div>
//               </div>
//             </div>
//           )}
//         </>
//       )}
//     </div>
//   );
// };

// // ─── ChartDetailModal ─────────────────────────────────────────────────────────
// const ChartDetailModal: React.FC<{ isOpen: boolean; onClose: () => void; title: string; data: any }> = ({ isOpen, onClose, title, data }) => {
//   const { t } = useTranslation();
//   if (!isOpen) return null;

//   const labels = data?.labels || [];
//   const datasets = data?.datasets || [];
//   const hideFooterTotal = data?.hideFooterTotal === true;

//   return (
//     <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
//       <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-hidden">
//         <div className="bg-gradient-to-r from-indigo-500 to-purple-600 px-6 py-4 flex items-center justify-between">
//           <h3 className="text-lg font-semibold text-white">{title}</h3>
//           <button onClick={onClose} className="text-white/80 hover:text-white transition-colors">
//             <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
//           </button>
//         </div>
//         <div className="p-6 overflow-auto max-h-[calc(90vh-120px)]">
//           {labels.length === 0 || datasets.length === 0 ? (
//             <div className="text-center text-gray-400 py-8">{t('dashboard.noDataAvailable')}</div>
//           ) : (
//             <table className="w-full text-sm border-collapse">
//               <thead>
//                 <tr className="border-b border-gray-200 dark:border-gray-700">
//                   <th className="text-left py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 rounded-tl-lg">Label</th>
//                   {datasets.map((ds: any, i: number) => (
//                     <th key={i} className="text-right py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 last:rounded-tr-lg">
//                       {(ds.name || `Series ${i + 1}`).replace(/_/g, ' ')}
//                     </th>
//                   ))}
//                 </tr>
//               </thead>
//               <tbody>
//                 {labels.map((label: string, labelIdx: number) => (
//                   <tr key={labelIdx} className="border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors">
//                     <td className="py-2.5 px-4 text-gray-800 dark:text-gray-200 font-medium">{label || 'Unknown'}</td>
//                     {datasets.map((ds: any, dsIdx: number) => (
//                       <td key={dsIdx} className="py-2.5 px-4 text-right text-gray-600 dark:text-gray-300 tabular-nums">{ds.values?.[labelIdx] ?? 0}</td>
//                     ))}
//                   </tr>
//                 ))}
//               </tbody>
//               {!hideFooterTotal && (
//                 <tfoot>
//                   <tr className="border-t-2 border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-900/50">
//                     <td className="py-3 px-4 font-bold text-gray-800 dark:text-gray-200">Total</td>
//                     {datasets.map((ds: any, dsIdx: number) => {
//                       const colTotal = (ds.values || []).reduce((s: number, v: number) => s + v, 0);
//                       return (
//                         <td key={dsIdx} className="py-3 px-4 text-right font-bold text-gray-800 dark:text-gray-200 tabular-nums">
//                           {typeof colTotal === 'number' && colTotal % 1 !== 0 ? colTotal.toFixed(1) : colTotal}
//                         </td>
//                       );
//                     })}
//                   </tr>
//                 </tfoot>
//               )}
//             </table>
//           )}
//         </div>
//       </div>
//     </div>
//   );
// };

// // ─── InspectionSummaryChartCard ───────────────────────────────────────────────
// const InspectionSummaryChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
//   const { t } = useTranslation();
//   const [showMenu, setShowMenu] = useState(false);

//   const total = React.useMemo(() => {
//     if (!data?.datasets?.[0]?.values) return 0;
//     return data.datasets[0].values.reduce((s: number, v: number) => s + v, 0);
//   }, [data]);

//   useEffect(() => {
//     const handleClickOutside = () => setShowMenu(false);
//     if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
//   }, [showMenu]);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-4">
//         <div className="flex items-center gap-3">
//           <button onClick={onOpenReport} className="w-10 h-10 bg-green-50 dark:bg-green-900/20 rounded-lg flex items-center justify-center hover:bg-green-100 dark:hover:bg-green-900/40 transition-colors cursor-pointer group" title={t('dashboard.viewFullReport', 'View Full Report')}>
//             <FaCheckCircle className="text-green-600 text-lg group-hover:scale-110 transition-transform" />
//           </button>
//           <div>
//             <h3 className="text-base font-semibold text-gray-900 dark:text-white">{title}</h3>
//             <p className="text-xs text-gray-500 dark:text-gray-400">Total: {total}</p>
//           </div>
//         </div>
//         <div className="relative">
//           <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
//             <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
//           </button>
//           {showMenu && (
//             <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
//               <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
//                 <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport', 'View Full Report')}
//               </button>
//             </div>
//           )}
//         </div>
//       </div>
//       {data === null ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaCheckCircle className="text-4xl mx-auto mb-2 opacity-30" /><div className="text-sm">Loading inspection data...</div></div>
//         </div>
//       ) : !data.datasets?.length ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaCheckCircle className="text-4xl mx-auto mb-2 opacity-20" /><div className="text-sm">No inspection data available</div></div>
//         </div>
//       ) : (
//         <HorizontalBarChart data={data} valueLabel="" />
//       )}
//     </div>
//   );
// };

// // ─── RejectionSummaryChartCard ────────────────────────────────────────────────
// const RejectionSummaryChartCard: React.FC<{ title: string; data: any; onOpenReport?: () => void }> = ({ title, data, onOpenReport }) => {
//   const { t } = useTranslation();
//   const [showMenu, setShowMenu] = useState(false);

//   const totalRejected = React.useMemo(() => {
//     if (!data?.datasets?.[0]?.values) return data?.totalRejected ?? 0;
//     return data.datasets[0].values.reduce((s: number, v: number) => s + v, 0);
//   }, [data]);

//   useEffect(() => {
//     const handleClickOutside = () => setShowMenu(false);
//     if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
//   }, [showMenu]);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-5 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-4">
//         <div className="flex items-center gap-3">
//           <button onClick={onOpenReport} className="w-10 h-10 bg-red-50 dark:bg-red-900/20 rounded-lg flex items-center justify-center hover:bg-red-100 dark:hover:bg-red-900/40 transition-colors cursor-pointer group" title={t('dashboard.viewFullReport', 'View Full Report')}>
//             <FaExclamationTriangle className="text-red-500 text-lg group-hover:scale-110 transition-transform" />
//           </button>
//           <div>
//             <h3 className="text-base font-semibold text-gray-900 dark:text-white">{title}</h3>
//             <p className="text-xs text-gray-500 dark:text-gray-400">Total: {totalRejected}</p>
//           </div>
//         </div>
//         <div className="relative">
//           <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
//             <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
//           </button>
//           {showMenu && (
//             <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
//               <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
//                 <FaExternalLinkAlt className="text-gray-400" size={12} />{t('dashboard.viewFullReport', 'View Full Report')}
//               </button>
//             </div>
//           )}
//         </div>
//       </div>
//       {data === null ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaExclamationTriangle className="text-4xl mx-auto mb-2 opacity-30" /><div className="text-sm">Loading rejection data...</div></div>
//         </div>
//       ) : !data.datasets?.length ? (
//         <div className="h-64 flex items-center justify-center text-gray-400">
//           <div className="text-center"><FaExclamationTriangle className="text-4xl mx-auto mb-2 opacity-20" /><div className="text-sm">No rejection data available</div></div>
//         </div>
//       ) : (
//         <RejectionHorizontalBarChart data={data} />
//       )}
//     </div>
//   );
// };

// // ─── InspectionSummaryReportModal ─────────────────────────────────────────────
// const InspectionSummaryReportModal: React.FC<{
//   isOpen: boolean; onClose: () => void; permittedIssueTypes: string[]; isAdmin: boolean; defaultWorkOrderType?: string;
// }> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
//   const { t } = useTranslation();
//   const [reportData, setReportData] = useState<any>(null);
//   const [loading, setLoading] = useState(false);

//   // Filters — Department, Work Order Type, From Date, To Date
//   const [selectedDepartment, setSelectedDepartment] = useState('');
//   const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
//   const [fromDate, setFromDate] = useState('');
//   const [toDate, setToDate] = useState('');
//   const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);
//   const [allDepartments, setAllDepartments] = useState<string[]>([]);

//   useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchMeta = async () => {
//       try {
//         const [typesRes, deptsRes] = await Promise.all([
//           fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
//           fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
//         ]);
//         const typesData = await typesRes.json();
//         const deptsData = await deptsRes.json();
//         if (typesData.data) setAllIssueTypes(typesData.data.map((d: any) => d.name));
//         if (deptsData.data) setAllDepartments(deptsData.data.map((d: any) => d.name));
//       } catch (e) { console.error(e); }
//     };
//     fetchMeta();
//   }, [isOpen]);

//   const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchReport = async () => {
//       setLoading(true);
//       try {
//         const filters: Record<string, any> = {};
//         if (!isAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedWorkOrderType) {
//           filters.work_order_type = selectedWorkOrderType;
//         }
//         if (selectedDepartment) filters.department = selectedDepartment;
//         if (fromDate) filters.from_date = fromDate;
//         if (toDate) filters.to_date = toDate;

//         const res = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
//           body: JSON.stringify({ report_name: 'Inspection Linked Work Orders Summary', filters, ignore_prepared_report: 1 })
//         });
//         const data = await res.json();
//         setReportData(data.message || null);
//       } catch (e) { console.error(e); } finally { setLoading(false); }
//     };
//     fetchReport();
//   }, [isOpen, selectedWorkOrderType, selectedDepartment, fromDate, toDate, permittedIssueTypes, isAdmin]);

//   if (!isOpen) return null;

//   const columns: any[] = reportData?.columns || [];
//   const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object');
//   const dataRows = rows.filter((r: any) => !r.is_total_row);

//   const reportSummary: any[] = reportData?.report_summary || [];

//   const totalInspections = reportSummary.find((s: any) => s.label?.toLowerCase().includes('total inspection'))?.value
//     ?? dataRows.reduce((sum: number, r: any) => {
//         const col = columns.find((c: any) => c.label?.toLowerCase().includes('total inspection') || c.fieldname?.toLowerCase().includes('total_inspection'));
//         return sum + (col ? (parseFloat(r[col.fieldname]) || 0) : 0);
//       }, 0);

//   const woLinkedCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('linked') || s.includes('wo linked') || s.includes('wo_linked');
//   });
//   const woLinked = reportSummary.find((s: any) => s.label?.toLowerCase().includes('linked'))?.value
//     ?? (woLinkedCol ? dataRows.reduce((sum: number, r: any) => sum + (parseFloat(r[woLinkedCol.fieldname]) || 0), 0) : null);

//   const overallPctCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('%') || s.includes('percent') || s.includes('overall');
//   });
//   const overallPct = reportSummary.find((s: any) => s.label?.toLowerCase().includes('%') || s.label?.toLowerCase().includes('percent'))?.value
//     ?? (overallPctCol
//         ? (dataRows.length > 0
//             ? (dataRows.reduce((sum: number, r: any) => sum + (parseFloat(r[overallPctCol.fieldname]) || 0), 0) / dataRows.length).toFixed(2) + '%'
//             : '0%')
//         : null);

//   const summaryCards = reportSummary.length > 0
//     ? reportSummary.map((s: any) => ({ label: s.label, value: s.value, color: s.color || 'blue' }))
//     : [
//         { label: 'Total Inspections', value: totalInspections, color: 'blue' },
//         ...(woLinked !== null ? [{ label: 'WO Linked To Inspection', value: woLinked, color: 'teal' }] : []),
//         ...(overallPct !== null ? [{ label: 'Overall Created %', value: overallPct, color: 'purple' }] : []),
//       ];

//   const colorMap: Record<string, string> = {
//     blue: 'text-blue-600 dark:text-blue-400',
//     teal: 'text-teal-600 dark:text-teal-400',
//     green: 'text-green-600 dark:text-green-400',
//     red: 'text-red-600 dark:text-red-400',
//     orange: 'text-orange-600 dark:text-orange-400',
//     purple: 'text-purple-600 dark:text-purple-400',
//   };

//   const hasActiveFilter =
//     selectedDepartment ||
//     fromDate ||
//     toDate ||
//     (selectedWorkOrderType && (isAdmin || permittedIssueTypes.length === 0));

//   const clearAllFilters = () => {
//     setSelectedDepartment('');
//     setFromDate('');
//     setToDate('');
//     if (isAdmin || permittedIssueTypes.length === 0) setSelectedWorkOrderType('');
//   };

//   return (
//     <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
//       <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">

//         {/* Header */}
//         <div className="bg-gradient-to-r from-green-500 to-teal-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
//           <div className="flex items-center gap-3">
//             <FaCheckCircle className="text-white text-xl" />
//             <h3 className="text-lg font-semibold text-white">Inspection Linked Work Orders Summary</h3>
//           </div>
//           <button onClick={onClose} className="text-white/80 hover:text-white transition-colors">
//             <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
//           </button>
//         </div>

//         {/* Filters — Row 1: WO Type · From Date · To Date  |  Row 2: Department */}
//         <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-col gap-2">

//           {/* Row 1: WO Type, From Date, To Date */}
//           <div className="flex flex-wrap items-center gap-4">

//             {/* Work Order Type */}
//             <div className="flex items-center gap-2">
//               <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">WO Type</label>
//               <select
//                 value={selectedWorkOrderType}
//                 onChange={e => setSelectedWorkOrderType(e.target.value)}
//                 disabled={!isAdmin && permittedIssueTypes.length > 0}
//                 className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[200px] disabled:opacity-60"
//               >
//                 <option value="">All Types</option>
//                 {dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}
//               </select>
//             </div>

//             {/* From Date */}
//             <div className="flex items-center gap-2">
//               <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">From Date</label>
//               <input
//                 type="date"
//                 value={fromDate}
//                 onChange={e => setFromDate(e.target.value)}
//                 className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
//               />
//             </div>

//             {/* To Date */}
//             <div className="flex items-center gap-2">
//               <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">To Date</label>
//               <input
//                 type="date"
//                 value={toDate}
//                 onChange={e => setToDate(e.target.value)}
//                 className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
//               />
//             </div>

//           </div>

//           {/* Row 2: Department (full width) + active badges + clear */}
//           <div className="flex flex-wrap items-center gap-4">

//             {/* Department */}
//             <div className="flex items-center gap-2">
//               <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">Department</label>
//               <select
//                 value={selectedDepartment}
//                 onChange={e => setSelectedDepartment(e.target.value)}
//                 className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-green-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[300px]"
//               >
//                 <option value="">All Departments</option>
//                 {allDepartments.map(d => <option key={d} value={d}>{d}</option>)}
//               </select>
//             </div>

//             {/* Clear all */}
//             {hasActiveFilter && (
//               <button
//                 onClick={clearAllFilters}
//                 className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
//               >
//                 <FaTimes size={10} /> Clear Filters
//               </button>
//             )}

//             {/* Active filter badges */}
//             {selectedWorkOrderType && (
//               <span className="text-xs text-green-600 dark:text-green-400 bg-green-50 dark:bg-green-900/30 px-2 py-1 rounded-full">{selectedWorkOrderType}</span>
//             )}
//             {selectedDepartment && (
//               <span className="text-xs text-teal-600 dark:text-teal-400 bg-teal-50 dark:bg-teal-900/30 px-2 py-1 rounded-full">{selectedDepartment}</span>
//             )}

//           </div>
//         </div>

//         {/* Summary cards */}
//         {!loading && summaryCards.length > 0 && (
//           <div className="px-6 py-5 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0">
//             <div className={`grid gap-6 ${summaryCards.length === 1 ? 'grid-cols-1' : summaryCards.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
//               {summaryCards.map((card, i) => (
//                 <div key={i} className="text-center">
//                   <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{card.label}</div>
//                   <div className={`text-2xl font-bold ${colorMap[card.color] || 'text-blue-600 dark:text-blue-400'}`}>{card.value}</div>
//                 </div>
//               ))}
//             </div>
//           </div>
//         )}

//         {/* Table */}
//         <div className="p-6 overflow-auto flex-1">
//           {loading ? (
//             <div className="flex items-center justify-center py-16"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-green-600"></div></div>
//           ) : rows.length === 0 ? (
//             <div className="text-center text-gray-400 py-16">No data available</div>
//           ) : (
//             <table className="w-full text-sm border-collapse">
//               <thead>
//                 <tr className="border-b border-gray-200 dark:border-gray-700">
//                   {columns.map((col: any, i: number) => (
//                     <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left' : 'text-right'}`}>
//                       {col.label || col.fieldname}
//                     </th>
//                   ))}
//                 </tr>
//               </thead>
//               <tbody>
//                 {rows.map((row: any, ri: number) => (
//                   <tr key={ri} className="border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors">
//                     {columns.map((col: any, ci: number) => (
//                       <td key={ci} className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium' : 'text-right text-gray-600 dark:text-gray-300 tabular-nums'}`}>
//                         {row[col.fieldname] ?? '—'}
//                       </td>
//                     ))}
//                   </tr>
//                 ))}
//               </tbody>
//             </table>
//           )}
//         </div>
//       </div>
//     </div>
//   );
// };

// // ─── RejectionSummaryReportModal ──────────────────────────────────────────────
// const RejectionSummaryReportModal: React.FC<{
//   isOpen: boolean; onClose: () => void; permittedIssueTypes: string[]; isAdmin: boolean; defaultWorkOrderType?: string;
// }> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
//   const { t } = useTranslation();
//   const [reportData, setReportData] = useState<any>(null);
//   const [loading, setLoading] = useState(false);

//   const [fromDate, setFromDate] = useState('');
//   const [toDate, setToDate] = useState('');
//   const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
//   const [selectedDepartment, setSelectedDepartment] = useState('');
//   const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);
//   const [allDepartments, setAllDepartments] = useState<string[]>([]);

//   useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchMeta = async () => {
//       try {
//         const [typesRes, deptsRes] = await Promise.all([
//           fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
//           fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
//         ]);
//         const typesData = await typesRes.json();
//         const deptsData = await deptsRes.json();
//         if (typesData.data) setAllIssueTypes(typesData.data.map((d: any) => d.name));
//         if (deptsData.data) setAllDepartments(deptsData.data.map((d: any) => d.name));
//       } catch (e) { console.error(e); }
//     };
//     fetchMeta();
//   }, [isOpen]);

//   const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchReport = async () => {
//       setLoading(true);
//       try {
//         const filters: Record<string, any> = {};
//         if (!isAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedWorkOrderType) {
//           filters.work_order_type = selectedWorkOrderType;
//         }
//         if (selectedDepartment) filters.department = selectedDepartment;
//         if (fromDate) filters.from_date = fromDate;
//         if (toDate) filters.to_date = toDate;

//         const res = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include',
//           body: JSON.stringify({ report_name: 'WO Rejection Summary', filters, ignore_prepared_report: 1 })
//         });
//         const data = await res.json();
//         setReportData(data.message || null);
//       } catch (e) { console.error(e); } finally { setLoading(false); }
//     };
//     fetchReport();
//   }, [isOpen, selectedWorkOrderType, selectedDepartment, fromDate, toDate, permittedIssueTypes, isAdmin]);

//   if (!isOpen) return null;

//   const columns: any[] = reportData?.columns || [];
//   const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object');
//   const dataRows = rows.filter((r: any) => !r.is_total_row);
//   const reportSummary: any[] = reportData?.report_summary || [];

//   const totalWoCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('total_work') || s.includes('total work');
//   });
//   const totalRejCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('total_rejected') || s.includes('total rejected') || (s.includes('rejected') && !s.includes('%') && !s.includes('percent'));
//   });
//   const rejPctCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('%') || s.includes('percent') || s.includes('rate');
//   });

//   const totalWO = totalWoCol
//     ? dataRows.reduce((s: number, r: any) => s + (parseFloat(r[totalWoCol.fieldname]) || 0), 0)
//     : null;
//   const totalRej = totalRejCol
//     ? dataRows.reduce((s: number, r: any) => s + (parseFloat(r[totalRejCol.fieldname]) || 0), 0)
//     : null;
//   const rejPct = (totalWO && totalRej && totalWO > 0)
//     ? ((totalRej / totalWO) * 100).toFixed(2) + '%'
//     : rejPctCol
//       ? dataRows.reduce((s: number, r: any) => s + (parseFloat(r[rejPctCol.fieldname]) || 0), 0).toFixed(2) + '%'
//       : null;

//   const summaryItems: Array<{ label: string; value: string | number; color: string }> =
//     reportSummary.length > 0
//       ? reportSummary.map((s: any) => ({ label: s.label, value: s.value, color: s.color || 'blue' }))
//       : [
//           ...(totalWO !== null ? [{ label: 'Total Work Orders', value: totalWO, color: 'blue' }] : []),
//           ...(totalRej !== null ? [{ label: 'Total Rejected', value: totalRej, color: 'red' }] : []),
//           ...(rejPct !== null ? [{ label: 'Rejected %', value: rejPct, color: 'orange' }] : []),
//         ];

//   const colorMap: Record<string, string> = {
//     blue: 'text-blue-600 dark:text-blue-400',
//     teal: 'text-teal-600 dark:text-teal-400',
//     green: 'text-green-600 dark:text-green-400',
//     red: 'text-red-600 dark:text-red-400',
//     orange: 'text-orange-600 dark:text-orange-400',
//     purple: 'text-purple-600 dark:text-purple-400',
//   };

//   return (
//     <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
//       <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
//         <div className="bg-gradient-to-r from-red-500 to-rose-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
//           <div className="flex items-center gap-3">
//             <FaExclamationTriangle className="text-white text-xl" />
//             <h3 className="text-lg font-semibold text-white">WO Rejection Summary</h3>
//           </div>
//           <button onClick={onClose} className="text-white/80 hover:text-white transition-colors">
//             <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
//           </button>
//         </div>

//         <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-wrap items-center gap-4">
//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">From Date</label>
//             <input
//               type="date"
//               value={fromDate}
//               onChange={e => setFromDate(e.target.value)}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
//             />
//           </div>

//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">To Date</label>
//             <input
//               type="date"
//               value={toDate}
//               onChange={e => setToDate(e.target.value)}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
//             />
//           </div>

//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">Work Order Type</label>
//             <select
//               value={selectedWorkOrderType}
//               onChange={e => setSelectedWorkOrderType(e.target.value)}
//               disabled={!isAdmin && permittedIssueTypes.length > 0}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[160px] disabled:opacity-60"
//             >
//               <option value="">All Types</option>
//               {dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}
//             </select>
//           </div>

//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">Department</label>
//             <select
//               value={selectedDepartment}
//               onChange={e => setSelectedDepartment(e.target.value)}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[160px]"
//             >
//               <option value="">All Departments</option>
//               {allDepartments.map(d => <option key={d} value={d}>{d}</option>)}
//             </select>
//           </div>

//           {(fromDate || toDate || selectedWorkOrderType || selectedDepartment) && (
//             <button
//               onClick={() => { setFromDate(''); setToDate(''); setSelectedWorkOrderType(''); setSelectedDepartment(''); }}
//               className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
//             >
//               <FaTimes size={10} /> Clear Filters
//             </button>
//           )}
//         </div>

//         {!loading && summaryItems.length > 0 && (
//           <div className="px-6 py-5 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0">
//             <div className={`grid gap-6 ${summaryItems.length === 1 ? 'grid-cols-1' : summaryItems.length === 2 ? 'grid-cols-2' : 'grid-cols-3'}`}>
//               {summaryItems.map((item, i) => (
//                 <div key={i} className="text-center">
//                   <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{item.label}</div>
//                   <div className={`text-2xl font-bold ${colorMap[item.color] || 'text-blue-600 dark:text-blue-400'}`}>{item.value}</div>
//                 </div>
//               ))}
//             </div>
//           </div>
//         )}

//         <div className="p-6 overflow-auto flex-1">
//           {loading ? (
//             <div className="flex items-center justify-center py-16"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-red-600"></div></div>
//           ) : rows.length === 0 ? (
//             <div className="text-center text-gray-400 py-16">No data available</div>
//           ) : (
//             <table className="w-full text-sm border-collapse">
//               <thead>
//                 <tr className="border-b border-gray-200 dark:border-gray-700">
//                   {columns.map((col: any, i: number) => (
//                     <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left' : 'text-right'}`}>
//                       {col.label || col.fieldname}
//                     </th>
//                   ))}
//                 </tr>
//               </thead>
//               <tbody>
//                 {rows.map((row: any, ri: number) => (
//                   <tr key={ri} className="border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors">
//                     {columns.map((col: any, ci: number) => (
//                       <td key={ci} className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium' : 'text-right text-gray-600 dark:text-gray-300 tabular-nums'}`}>
//                         {row[col.fieldname] ?? '—'}
//                       </td>
//                     ))}
//                   </tr>
//                 ))}
//               </tbody>
//             </table>
//           )}
//         </div>
//       </div>
//     </div>
//   );
// };

// // ─── TimeToRepairCard ─────────────────────────────────────────────────────────
// const TimeToRepairCard: React.FC<{ data: any; onOpenReport?: () => void }> = ({ data, onOpenReport }) => {
//   const [showMenu, setShowMenu] = useState(false);

//   useEffect(() => {
//     const handleClickOutside = () => setShowMenu(false);
//     if (showMenu) { document.addEventListener('click', handleClickOutside); return () => document.removeEventListener('click', handleClickOutside); }
//   }, [showMenu]);

//   // FIX: Filter out null/unknown labels from the time to repair chart
//   const rawLabels: string[] = data?.labels || [];
//   const rawValues: number[] = data?.datasets?.[0]?.values || [];
//   const filtered = rawLabels.reduce<{ labels: string[]; values: number[] }>(
//     (acc, label, i) => {
//       if (!isNullOrUnknownLabel(label)) {
//         acc.labels.push(label);
//         acc.values.push(rawValues[i] ?? 0);
//       }
//       return acc;
//     },
//     { labels: [], values: [] }
//   );
//   const labels = filtered.labels;
//   const values = filtered.values;

//   const overallAvg: number = data?.overallAvg ?? 0;
//   const typeColors = generateColors(labels.length);
//   const max = Math.max(...values, 0.001);

//   return (
//     <div className="bg-white dark:bg-gray-800 rounded-lg shadow hover:shadow-md transition-all p-4 border border-gray-200 dark:border-gray-700">
//       <div className="flex items-center justify-between mb-3">
//         <div className="flex items-center gap-2">
//           <button
//             onClick={onOpenReport}
//             className="w-8 h-8 bg-pink-50 dark:bg-pink-900/20 rounded-lg flex items-center justify-center hover:bg-pink-100 dark:hover:bg-pink-900/40 transition-colors cursor-pointer group"
//             title="View Full Report"
//           >
//             <FaWrench className="text-pink-600 text-sm group-hover:scale-110 transition-transform" />
//           </button>
//           <div>
//             <h3 className="text-sm font-semibold text-gray-900 dark:text-white">Time to Repair</h3>
//             <p className="text-[11px] text-gray-500 dark:text-gray-400">
//               Overall Avg: <span className="font-semibold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)} hrs</span>
//             </p>
//           </div>
//         </div>
//         <div className="relative">
//           <button onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }} className="p-1.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg">
//             <svg className="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20"><path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" /></svg>
//           </button>
//           {showMenu && (
//             <div className="absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1 z-50">
//               <button onClick={(e) => { e.stopPropagation(); setShowMenu(false); onOpenReport?.(); }} className="w-full px-4 py-2 text-left text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2">
//                 <FaExternalLinkAlt className="text-gray-400" size={12} /> View Full Report
//               </button>
//             </div>
//           )}
//         </div>
//       </div>

//       <div className="bg-pink-50 dark:bg-pink-900/20 rounded-lg px-4 py-2 mb-3 flex items-center justify-between">
//         <span className="text-xs font-medium text-pink-700 dark:text-pink-300">Overall Avg Time to Repair (Hours)</span>
//         <span className="text-xl font-bold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)}</span>
//       </div>

//       {!data || !labels.length ? (
//         <div className="h-32 flex items-center justify-center text-gray-400">
//           <div className="text-center">
//             <FaWrench className="text-3xl mx-auto mb-1 opacity-30" />
//             <div className="text-xs">Loading time to repair data...</div>
//           </div>
//         </div>
//       ) : (
//         <div className="space-y-2 max-h-64 overflow-y-auto">
//           {labels.map((label, i) => {
//             const value = values[i] || 0;
//             const pct = max > 0 ? (value / max) * 100 : 0;
//             const color = typeColors[i];
//             const minPct = Math.max(pct, value > 0 ? 3 : 1);
//             return (
//               <div key={i} className="flex items-center gap-2">
//                 <div className="flex-1 h-6 bg-gray-100 dark:bg-gray-700 rounded-md overflow-hidden relative">
//                   <div
//                     className="h-full rounded-md transition-all duration-500 flex items-center justify-end pr-1.5"
//                     style={{ width: `${minPct}%`, backgroundColor: color, opacity: 0.88 }}
//                   >
//                     {pct > 28 && (
//                       <span className="text-[9px] font-semibold text-white whitespace-nowrap">{value.toFixed(2)} hrs</span>
//                     )}
//                   </div>
//                   {pct <= 28 && (
//                     <span className="absolute left-[calc(max(3%,6px)+4px)] top-1/2 -translate-y-1/2 text-[9px] font-semibold text-gray-600 dark:text-gray-300 whitespace-nowrap">{value.toFixed(2)} hrs</span>
//                   )}
//                 </div>
//                 <div className="w-40 text-[11px] text-gray-700 dark:text-gray-200 font-medium truncate flex-shrink-0" title={label}>
//                   {label}
//                 </div>
//               </div>
//             );
//           })}
//         </div>
//       )}

//       {labels.length > 0 && (
//         <div className="flex flex-wrap items-center gap-x-3 gap-y-1 mt-3 pt-2 border-t border-gray-100 dark:border-gray-700">
//           {labels.map((label, i) => (
//             <div key={i} className="flex items-center gap-1">
//               <div className="w-2 h-2 rounded-sm flex-shrink-0" style={{ backgroundColor: typeColors[i] }} />
//               <span className="text-[9px] text-gray-500 dark:text-gray-400 truncate max-w-[100px]">
//                 {label.length > 16 ? label.substring(0, 14) + '…' : label}
//               </span>
//             </div>
//           ))}
//         </div>
//       )}
//     </div>
//   );
// };

// // ─── TimeToRepairReportModal ───────────────────────────────────────────────────
// const TimeToRepairReportModal: React.FC<{
//   isOpen: boolean;
//   onClose: () => void;
//   permittedIssueTypes: string[];
//   isAdmin: boolean;
//   defaultWorkOrderType?: string;
// }> = ({ isOpen, onClose, permittedIssueTypes, isAdmin, defaultWorkOrderType }) => {
//   const [reportData, setReportData] = useState<any>(null);
//   const [loading, setLoading] = useState(false);
//   const [selectedDepartment, setSelectedDepartment] = useState('');
//   const [selectedWorkOrderType, setSelectedWorkOrderType] = useState(defaultWorkOrderType || '');
//   const [allDepartments, setAllDepartments] = useState<string[]>([]);
//   const [allIssueTypes, setAllIssueTypes] = useState<string[]>([]);

//   useEffect(() => { setSelectedWorkOrderType(defaultWorkOrderType || ''); }, [defaultWorkOrderType]);

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchMeta = async () => {
//       try {
//         const [deptRes, typeRes] = await Promise.all([
//           fetch('/api/resource/Department?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' }),
//           fetch('/api/resource/Issue Type?fields=["name"]&limit_page_length=0&order_by=name asc', { headers: { 'Accept': 'application/json' }, credentials: 'include' })
//         ]);
//         const deptData = await deptRes.json();
//         const typeData = await typeRes.json();
//         if (deptData.data) setAllDepartments(deptData.data.map((d: any) => d.name));
//         if (typeData.data) setAllIssueTypes(typeData.data.map((d: any) => d.name));
//       } catch (e) { console.error(e); }
//     };
//     fetchMeta();
//   }, [isOpen]);

//   const dropdownTypes = isAdmin ? allIssueTypes : permittedIssueTypes;

//   useEffect(() => {
//     if (!isOpen) return;
//     const fetchReport = async () => {
//       setLoading(true);
//       try {
//         const filters: Record<string, any> = {};
//         if (!isAdmin && permittedIssueTypes.length > 0) {
//           filters.work_order_type = permittedIssueTypes.length === 1 ? permittedIssueTypes[0] : permittedIssueTypes;
//         } else if (selectedWorkOrderType) {
//           filters.work_order_type = selectedWorkOrderType;
//         }
//         if (selectedDepartment) filters.department = selectedDepartment;

//         const res = await fetch('/api/method/frappe.desk.query_report.run', {
//           method: 'POST',
//           headers: { 'Content-Type': 'application/json' },
//           credentials: 'include',
//           body: JSON.stringify({ report_name: 'Time to Repair', filters, ignore_prepared_report: 1 })
//         });
//         const data = await res.json();
//         setReportData(data.message || null);
//       } catch (e) { console.error(e); } finally { setLoading(false); }
//     };
//     fetchReport();
//   }, [isOpen, selectedDepartment, selectedWorkOrderType, permittedIssueTypes, isAdmin]);

//   if (!isOpen) return null;

//   const columns: any[] = reportData?.columns || [];
//   const rows: any[] = (reportData?.result || []).filter((r: any) => r && typeof r === 'object');
//   const dataRows = rows.filter((r: any) => !r.is_total_row);
//   const reportSummary: any[] = reportData?.report_summary || [];

//   const timeCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('time_to_repair') || s.includes('time to repair') || s.includes('hours');
//   }) || columns[columns.length - 1];

//   const woTypeCol = columns.find((c: any) => {
//     const s = ((c.label || '') + (c.fieldname || '')).toLowerCase();
//     return s.includes('wo_type') || s.includes('wo type') || s.includes('work_order_type');
//   }) || columns[1];

//   const summaryAvgItem = reportSummary.find((s: any) =>
//     s.label?.toLowerCase().includes('avg') || s.label?.toLowerCase().includes('overall')
//   );

//   // FIX: Only count valid (non-null/unknown) rows for overall avg in modal
//   const validDataRows = dataRows.filter((r: any) => {
//     const rawType = woTypeCol ? r[woTypeCol.fieldname] : null;
//     return !isNullOrUnknownLabel(rawType);
//   });

//   const overallAvg = summaryAvgItem
//     ? parseFloat(summaryAvgItem.value) || 0
//     : (validDataRows.length > 0 && timeCol
//         ? validDataRows.reduce((s: number, r: any) => s + (parseFloat(r[timeCol.fieldname]) || 0), 0) / validDataRows.length
//         : 0);

//   // FIX: Build chart data excluding null/unknown types
//   const typeMap: Record<string, { total: number; count: number }> = {};
//   dataRows.forEach((r: any) => {
//     const rawType = woTypeCol ? r[woTypeCol.fieldname] : null;
//     if (isNullOrUnknownLabel(rawType)) return;
//     const type = String(rawType);
//     const time = timeCol ? (parseFloat(r[timeCol.fieldname]) || 0) : 0;
//     if (!typeMap[type]) typeMap[type] = { total: 0, count: 0 };
//     typeMap[type].total += time;
//     typeMap[type].count += 1;
//   });
//   const chartLabels = Object.keys(typeMap);
//   const chartValues = chartLabels.map(t => parseFloat((typeMap[t].total / typeMap[t].count).toFixed(3)));
//   const chartMax = Math.max(...chartValues, 0.001);
//   const chartColors = generateColors(chartLabels.length);

//   const hasActiveFilter = selectedDepartment || (selectedWorkOrderType && (isAdmin || permittedIssueTypes.length === 0));

//   return (
//     <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[70] p-4">
//       <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-5xl w-full max-h-[90vh] overflow-hidden flex flex-col">
//         <div className="bg-gradient-to-r from-pink-500 to-rose-600 px-6 py-4 flex items-center justify-between flex-shrink-0">
//           <div className="flex items-center gap-3">
//             <FaWrench className="text-white text-xl" />
//             <h3 className="text-lg font-semibold text-white">Time to Repair</h3>
//           </div>
//           <button onClick={onClose} className="text-white/80 hover:text-white transition-colors">
//             <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
//           </button>
//         </div>

//         <div className="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/30 flex-shrink-0 flex flex-wrap items-center gap-4">
//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">Department</label>
//             <select
//               value={selectedDepartment}
//               onChange={e => setSelectedDepartment(e.target.value)}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[180px]"
//             >
//               <option value="">All Departments</option>
//               {allDepartments.map(d => <option key={d} value={d}>{d}</option>)}
//             </select>
//           </div>

//           <div className="flex items-center gap-2">
//             <label className="text-xs font-medium text-gray-500 dark:text-gray-400 whitespace-nowrap">Work Order Type</label>
//             <select
//               value={selectedWorkOrderType}
//               onChange={e => setSelectedWorkOrderType(e.target.value)}
//               disabled={!isAdmin && permittedIssueTypes.length > 0}
//               className="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-white min-w-[180px] disabled:opacity-60"
//             >
//               <option value="">All Types</option>
//               {dropdownTypes.map(opt => <option key={opt} value={opt}>{opt}</option>)}
//             </select>
//           </div>

//           {hasActiveFilter && (
//             <button
//               onClick={() => { setSelectedDepartment(''); setSelectedWorkOrderType(''); }}
//               className="text-xs text-red-500 hover:text-red-700 flex items-center gap-1 px-2 py-1 rounded hover:bg-red-50 dark:hover:bg-red-900/20 transition-colors"
//             >
//               <FaTimes size={10} /> Clear Filters
//             </button>
//           )}
//           {selectedWorkOrderType && (
//             <span className="text-xs text-pink-600 dark:text-pink-400 bg-pink-50 dark:bg-pink-900/30 px-2 py-1 rounded-full">{selectedWorkOrderType}</span>
//           )}
//           {selectedDepartment && (
//             <span className="text-xs text-rose-600 dark:text-rose-400 bg-rose-50 dark:bg-rose-900/30 px-2 py-1 rounded-full">{selectedDepartment}</span>
//           )}
//         </div>

//         {!loading && (
//           <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40 flex-shrink-0">
//             <div className="text-center">
//               <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Overall Avg Time to Repair (Hours)</div>
//               <div className="text-3xl font-bold text-pink-600 dark:text-pink-400">{overallAvg.toFixed(3)}</div>
//             </div>
//           </div>
//         )}

//         <div className="p-6 overflow-auto flex-1 flex flex-col gap-6">
//           {loading ? (
//             <div className="flex items-center justify-center py-16">
//               <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-pink-600"></div>
//             </div>
//           ) : rows.length === 0 ? (
//             <div className="text-center text-gray-400 py-16">No data available</div>
//           ) : (
//             <>
//               {/* Bar Chart — only valid (non-null) types */}
//               {chartLabels.length > 0 && (
//                 <div className="bg-gray-50 dark:bg-gray-900/30 rounded-lg p-4">
//                   <h4 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-4">Avg Time to Repair by WO Type (Hours)</h4>
//                   <div className="space-y-3">
//                     {chartLabels.map((label, i) => {
//                       const value = chartValues[i];
//                       const pct = chartMax > 0 ? (value / chartMax) * 100 : 0;
//                       const color = chartColors[i];
//                       const minPct = Math.max(pct, value > 0 ? 2 : 1);
//                       return (
//                         <div key={i} className="flex items-center gap-3">
//                           <div className="flex-1 h-8 bg-white dark:bg-gray-700 rounded-lg overflow-hidden relative border border-gray-200 dark:border-gray-600">
//                             <div
//                               className="h-full rounded-lg transition-all duration-500 flex items-center justify-end pr-2"
//                               style={{ width: `${minPct}%`, backgroundColor: color, opacity: 0.85 }}
//                             >
//                               {pct > 20 && (
//                                 <span className="text-[11px] font-semibold text-white">{value.toFixed(3)}</span>
//                               )}
//                             </div>
//                             {pct <= 20 && (
//                               <span className="absolute left-[calc(max(2%,4px)+8px)] top-1/2 -translate-y-1/2 text-[11px] font-semibold text-gray-700 dark:text-gray-200">{value.toFixed(3)}</span>
//                             )}
//                           </div>
//                           <div className="w-52 text-xs text-gray-700 dark:text-gray-200 font-medium truncate flex-shrink-0" title={label}>{label}</div>
//                         </div>
//                       );
//                     })}
//                   </div>
//                   <div className="flex flex-wrap gap-3 mt-3 pt-3 border-t border-gray-200 dark:border-gray-600">
//                     {chartLabels.map((label, i) => (
//                       <div key={i} className="flex items-center gap-1.5">
//                         <div className="w-2.5 h-2.5 rounded-sm" style={{ backgroundColor: chartColors[i] }} />
//                         <span className="text-[10px] text-gray-600 dark:text-gray-400">{label.length > 20 ? label.substring(0, 18) + '…' : label}</span>
//                       </div>
//                     ))}
//                   </div>
//                 </div>
//               )}

//               {/* Full table — show all raw rows as-is from the API */}
//               <table className="w-full text-sm border-collapse">
//                 <thead>
//                   <tr className="border-b border-gray-200 dark:border-gray-700">
//                     {columns.map((col: any, i: number) => (
//                       <th key={i} className={`py-3 px-4 font-semibold text-gray-700 dark:text-gray-300 bg-gray-50 dark:bg-gray-900/50 ${i === 0 ? 'text-left' : 'text-right'}`}>
//                         {col.label || col.fieldname}
//                       </th>
//                     ))}
//                   </tr>
//                 </thead>
//                 <tbody>
//                   {rows.map((row: any, ri: number) => (
//                     <tr key={ri} className={`border-b border-gray-100 dark:border-gray-700/50 hover:bg-gray-50 dark:hover:bg-gray-700/30 transition-colors ${row.is_total_row ? 'font-bold bg-gray-50 dark:bg-gray-900/40 border-t-2 border-gray-300 dark:border-gray-600' : ''}`}>
//                       {columns.map((col: any, ci: number) => (
//                         <td key={ci} className={`py-2.5 px-4 ${ci === 0 ? 'text-gray-800 dark:text-gray-200 font-medium' : 'text-right text-gray-600 dark:text-gray-300 tabular-nums'}`}>
//                           {row[col.fieldname] ?? '—'}
//                         </td>
//                       ))}
//                     </tr>
//                   ))}
//                 </tbody>
//               </table>
//             </>
//           )}
//         </div>
//       </div>
//     </div>
//   );
// };

// function generateColors(count: number): string[] {
//   const colors = [
//     '#8B5CF6', '#6366F1', '#3B82F6', '#06B6D4', '#14B8A6',
//     '#EC4899', '#A855F7', '#0EA5E9', '#10B981', '#F472B6',
//     '#7C3AED', '#2DD4BF',
//   ];
//   return Array.from({ length: count }, (_, i) => colors[i % colors.length]);
// }

// export default ModernDashboard;
