import { getYearToDateRange } from '../utils/dateUtils';

export const TECHNICIAN_WORKING_HOURS_REPORT = 'Technicians working Hours';

export type TechnicianWorkingHoursRow = {
  engineer?: string;
  technician_name?: string;
  total_hours?: number | string;
  is_total_row?: number | boolean;
};

export type TechnicianWorkingHoursFilters = {
  work_order_type?: string;
  from_date?: string;
  to_date?: string;
  company?: string;
  site_name?: string;
};

export type TechnicianWorkingHoursChartData = {
  labels: string[];
  datasets: Array<{ name: string; values: number[]; colors?: string[] }>;
  totalHours: number;
  rows: TechnicianWorkingHoursRow[];
};

export const getDefaultTechnicianHoursDateRange = () => getYearToDateRange();

export const getTechnicianHoursLabel = (row: TechnicianWorkingHoursRow): string =>
  (row.technician_name || row.engineer || 'Unknown').trim() || 'Unknown';

export const parseTechnicianHours = (value: unknown): number => {
  if (value == null || value === '') return 0;
  const parsed = Number(value);
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
};

export const buildTechnicianWorkingHoursChartData = (
  rows: TechnicianWorkingHoursRow[]
): TechnicianWorkingHoursChartData | null => {
  const dataRows = rows.filter(row => row && !row.is_total_row);
  if (!dataRows.length) return null;

  const labels = dataRows.map(getTechnicianHoursLabel);
  const values = dataRows.map(row => parseTechnicianHours(row.total_hours));
  const totalHours = values.reduce((sum, value) => sum + value, 0);

  return {
    labels,
    datasets: [{ name: 'Total Hours', values, colors: ['#6366F1'] }],
    totalHours,
    rows: dataRows,
  };
};

export const runTechnicianWorkingHoursReport = async (
  filters: TechnicianWorkingHoursFilters
): Promise<TechnicianWorkingHoursRow[]> => {
  const csrfToken =
    typeof window !== 'undefined' && (window as any).csrf_token && (window as any).csrf_token !== 'None'
      ? (window as any).csrf_token
      : null;

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    Accept: 'application/json',
  };
  if (csrfToken) {
    headers['X-Frappe-CSRF-Token'] = csrfToken;
  }

  const cleanedFilters: Record<string, string> = {};
  Object.entries(filters).forEach(([key, value]) => {
    if (value) cleanedFilters[key] = value;
  });

  const response = await fetch('/api/method/frappe.desk.query_report.run', {
    method: 'POST',
    headers,
    credentials: 'include',
    body: JSON.stringify({
      report_name: TECHNICIAN_WORKING_HOURS_REPORT,
      filters: cleanedFilters,
      ignore_prepared_report: 1,
    }),
  });

  const payload = await response.json();
  if (!response.ok) {
    throw new Error(payload?.message || payload?.exc || 'Failed to load technician working hours');
  }

  const result = payload?.message?.result || payload?.message?.message?.result || [];
  if (!Array.isArray(result)) return [];

  return result.filter(row => row && !row.is_total_row);
};

export const fetchTechnicianWorkingHoursChart = async (
  filters: TechnicianWorkingHoursFilters
): Promise<TechnicianWorkingHoursChartData | null> => {
  const rows = await runTechnicianWorkingHoursReport(filters);
  return buildTechnicianWorkingHoursChartData(rows);
};
