import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FaSync, FaTimes } from 'react-icons/fa';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import apiService from '../services/apiService';
import {
  buildAssigneesStatusChartData,
  getAssigneeCancelled,
  getAssigneeCompleted,
  getAssigneeName,
  getAssigneeOverdue,
  getAssigneePlanned,
  getAssigneeTotal,
  runAssigneesStatusReport,
} from '../services/assigneesStatusService';
import { buildMaintenanceUrl } from '../utils/buildMaintenanceUrl';
import { buildWoUrl } from '../utils/buildWoUrl';
import { getRepairCompletionRate } from '../utils/chartLabelUtils';
import type { DashboardLocationFilters } from '../utils/hospitalUtils';

type ChartDataset = {
  name?: string;
  values?: number[];
  colors?: string[];
};

type ChartData = {
  labels?: string[];
  datasets?: ChartDataset[];
  hideFooterTotal?: boolean;
  rawRows?: Record<string, unknown>[];
};

type ChartDetailModalProps = {
  isOpen: boolean;
  onClose: () => void;
  title: string;
  initialData?: ChartData | null;
  redirectContext?: 'wo_status' | 'wo_type' | 'assignees_status' | null;
  defaultFromDate?: string;
  defaultToDate?: string;
  locationFilters?: DashboardLocationFilters;
  workOrderType?: string;
};

const APP_BASE = '/asm_app';

const ChartDetailModal: React.FC<ChartDetailModalProps> = ({
  isOpen,
  onClose,
  title,
  initialData = null,
  redirectContext = null,
  defaultFromDate = '',
  defaultToDate = '',
  locationFilters,
  workOrderType = '',
}) => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const [fromDate, setFromDate] = useState(defaultFromDate);
  const [toDate, setToDate] = useState(defaultToDate);
  const [chartData, setChartData] = useState<ChartData | null>(initialData);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const buildMetricsFilters = useCallback(
    (from: string, to: string) => {
      const filters: Record<string, string> = {};
      if (from) filters.from_date = from;
      if (to) filters.to_date = to;
      if (locationFilters?.company) filters.company = locationFilters.company;
      if (locationFilters?.site_name) filters.site_name = locationFilters.site_name;
      if (workOrderType) filters.work_order_type = workOrderType;
      return filters;
    },
    [locationFilters, workOrderType]
  );

  const loadData = useCallback(
    async (from: string, to: string) => {
      if (redirectContext === 'wo_status') {
        setLoading(true);
        setError(null);
        try {
          const result = await apiService.getDashboardWorkOrderMetrics(buildMetricsFilters(from, to));
          setChartData(result.work_order_chart);
        } catch (err) {
          setChartData(null);
          setError(err instanceof Error ? err.message : 'Failed to load report data');
        } finally {
          setLoading(false);
        }
        return;
      }

      if (redirectContext === 'wo_type') {
        setLoading(true);
        setError(null);
        try {
          const result = await apiService.getDashboardWorkOrderMetrics(buildMetricsFilters(from, to));
          const rates = result.completion_by_type?.rates || [];
          setChartData({
            labels: rates.map(item => item.type),
            datasets: [
              {
                name: 'Completion Rate (%)',
                values: rates.map(item => getRepairCompletionRate(item)),
              },
              {
                name: 'Completed WOs',
                values: rates.map(
                  item => item.completedCombined ?? (item.completed || 0) + (item.closed || 0)
                ),
              },
              {
                name: 'In Progress',
                values: rates.map(item => item.inProgress || 0),
              },
              {
                name: 'Rejected',
                values: rates.map(item => item.rejected || 0),
              },
              {
                name: 'Total WOs',
                values: rates.map(item => item.total || 0),
              },
            ],
            hideFooterTotal: true,
          });
        } catch (err) {
          setChartData(null);
          setError(err instanceof Error ? err.message : 'Failed to load report data');
        } finally {
          setLoading(false);
        }
        return;
      }

      if (redirectContext === 'assignees_status') {
        setLoading(true);
        setError(null);
        try {
          const rows = await runAssigneesStatusReport(buildMetricsFilters(from, to));
          setChartData(buildAssigneesStatusChartData(rows));
        } catch (err) {
          setChartData(null);
          setError(err instanceof Error ? err.message : 'Failed to load report data');
        } finally {
          setLoading(false);
        }
        return;
      }

      setChartData(initialData);
    },
    [redirectContext, initialData, buildMetricsFilters]
  );

  useEffect(() => {
    if (!isOpen) return;
    setFromDate(defaultFromDate);
    setToDate(defaultToDate);
    loadData(defaultFromDate, defaultToDate);
  }, [isOpen, defaultFromDate, defaultToDate, loadData]);

  useEffect(() => {
    if (!isOpen) return;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [isOpen]);

  useEffect(() => {
    if (!isOpen) return;
    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') onClose();
    };
    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, [isOpen, onClose]);

  const statusRows = useMemo(() => {
    const labels = chartData?.labels || [];
    const values = chartData?.datasets?.[0]?.values || [];
    const colors = chartData?.datasets?.[0]?.colors || [];
    return labels.map((label, index) => ({
      label,
      value: Number(values[index]) || 0,
      color: colors[index] || '#6366F1',
    }));
  }, [chartData]);

  const typeRows = useMemo(() => {
    const labels = chartData?.labels || [];
    const datasets = chartData?.datasets || [];
    return labels.map((label, rowIndex) => ({
      label,
      cells: datasets.map(dataset => Number(dataset.values?.[rowIndex]) || 0),
    }));
  }, [chartData]);

  const typeColumns = chartData?.datasets?.map(dataset => dataset.name || '') || [];
  const statusTotal = useMemo(() => statusRows.reduce((sum, row) => sum + row.value, 0), [statusRows]);

  const assigneeRows = useMemo(() => {
    const rawRows = chartData?.rawRows || [];
    return rawRows.map(row => ({
      assignee: getAssigneeName(row),
      planned: getAssigneePlanned(row),
      completed: getAssigneeCompleted(row),
      cancelled: getAssigneeCancelled(row),
      overdue: getAssigneeOverdue(row),
      total: getAssigneeTotal(row),
    }));
  }, [chartData?.rawRows]);

  const assigneeTotals = useMemo(
    () =>
      assigneeRows.reduce(
        (acc, row) => {
          acc.planned += row.planned;
          acc.completed += row.completed;
          acc.cancelled += row.cancelled;
          acc.overdue += row.overdue;
          acc.total += row.total;
          return acc;
        },
        { planned: 0, completed: 0, cancelled: 0, overdue: 0, total: 0 }
      ),
    [assigneeRows]
  );

  const handleApply = () => {
    loadData(fromDate, toDate);
  };

  const handleClearDates = () => {
    setFromDate('');
    setToDate('');
    loadData('', '');
  };

  const navigateToWorkOrders = (params: {
    work_order_type?: string;
    status?: string;
  }) => {
    const path = buildWoUrl(
      {
        work_order_type: params.work_order_type,
        status: params.status,
        company: locationFilters?.company,
        site_name: locationFilters?.site_name,
      },
      fromDate || undefined,
      toDate || undefined,
      locationFilters
    );
    onClose();
    window.location.href = `${APP_BASE}${path}`;
  };

  const navigateToMaintenance = (assignee: string, status: string) => {
    const path = buildMaintenanceUrl(
      { assignee, status },
      fromDate || undefined,
      toDate || undefined,
      locationFilters
    );
    onClose();
    window.location.href = `${APP_BASE}${path}`;
  };

  const handleAssigneeCellClick = (assignee: string, status: string, value: number) => {
    if (redirectContext !== 'assignees_status' || value <= 0) return;
    navigateToMaintenance(assignee, status);
  };

  const handleStatusRowClick = (status: string) => {
    if (redirectContext !== 'wo_status') return;
    onClose();
    navigate(
      buildWoUrl({ status }, fromDate || undefined, toDate || undefined, locationFilters)
    );
  };

  const handleTypeCellClick = (rowLabel: string, columnName: string) => {
    if (redirectContext !== 'wo_type') return;

    if (columnName === 'Rejected') {
      navigateToWorkOrders({ work_order_type: rowLabel, status: 'Rejected' });
      return;
    }

    if (columnName === 'In Progress') {
      navigateToWorkOrders({ work_order_type: rowLabel, status: 'Work In Progress' });
      return;
    }

    if (columnName === 'Completed WOs' || columnName === 'Completion Rate (%)') {
      navigateToWorkOrders({ work_order_type: rowLabel, status: 'Completed,Closed' });
      return;
    }

    navigateToWorkOrders({ work_order_type: rowLabel });
  };

  const dateRangeLabel =
    fromDate || toDate
      ? t('dashboard.activeDateRange', {
          defaultValue: 'Date range: {{from}} to {{to}}',
          from: fromDate || '—',
          to: toDate || '—',
        })
      : t('dashboard.allDates', { defaultValue: 'Showing all dates' });

  if (!isOpen) return null;

  const isTypeMode = redirectContext === 'wo_type';
  const isAssigneeMode = redirectContext === 'assignees_status' || !!(chartData?.rawRows?.length);

  return (
    <div className="fixed inset-0 z-[70] flex items-center justify-center p-4 bg-black/50 backdrop-blur-sm">
      <div className="w-full max-w-4xl max-h-[90vh] overflow-hidden rounded-xl bg-white dark:bg-gray-900 shadow-2xl border border-gray-200 dark:border-gray-700 flex flex-col">
        <div
          className={`px-5 py-4 border-b border-gray-200 dark:border-gray-700 ${
            isTypeMode || isAssigneeMode
              ? 'bg-gradient-to-r from-indigo-600 to-purple-600 text-white'
              : ''
          }`}
        >
          <div className="flex items-center justify-between gap-3">
            <div>
              <h3 className={`text-lg font-semibold ${isTypeMode || isAssigneeMode ? 'text-white' : 'text-gray-900 dark:text-white'}`}>
                {title}
              </h3>
              <p
                className={`text-xs mt-1 ${
                  isTypeMode || isAssigneeMode ? 'text-white/85' : 'text-indigo-600 dark:text-indigo-300'
                }`}
              >
                {isTypeMode
                  ? t('dashboard.clickRowToFilter', {
                      defaultValue: 'Click a row or value to view filtered work orders',
                    })
                  : dateRangeLabel}
              </p>
            </div>
            <button
              type="button"
              onClick={onClose}
              className={`p-2 rounded-lg ${
                isTypeMode || isAssigneeMode
                  ? 'hover:bg-white/10 text-white'
                  : 'hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-500'
              }`}
              aria-label="Close"
            >
              <FaTimes />
            </button>
          </div>
        </div>

        <div className="px-5 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50">
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 items-end">
            <div>
              <label className="block text-xs font-medium text-gray-600 dark:text-gray-300 mb-1">
                {t('dashboard.fromDate', { defaultValue: 'From Date' })}
              </label>
              <input
                type="date"
                value={fromDate}
                onChange={e => setFromDate(e.target.value)}
                className="w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm"
              />
            </div>
            <div>
              <label className="block text-xs font-medium text-gray-600 dark:text-gray-300 mb-1">
                {t('dashboard.toDate', { defaultValue: 'To Date' })}
              </label>
              <input
                type="date"
                value={toDate}
                onChange={e => setToDate(e.target.value)}
                className="w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-3 py-2 text-sm"
              />
            </div>
            <div className="flex flex-wrap gap-2 lg:col-span-2">
              <button
                type="button"
                onClick={handleApply}
                disabled={loading}
                className="inline-flex items-center gap-2 px-3 py-2 rounded-md bg-indigo-600 hover:bg-indigo-700 text-white text-sm disabled:opacity-60"
              >
                <FaSync className={loading ? 'animate-spin' : ''} />
                {t('dashboard.applyFilters', { defaultValue: 'Apply' })}
              </button>
              <button
                type="button"
                onClick={handleClearDates}
                disabled={loading}
                className="px-3 py-2 rounded-md border border-gray-300 dark:border-gray-600 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 disabled:opacity-60"
              >
                {t('dashboard.clearDates', { defaultValue: 'Clear dates' })}
              </button>
            </div>
          </div>
          {isTypeMode && (
            <p className="text-xs text-gray-500 dark:text-gray-400 mt-2">{dateRangeLabel}</p>
          )}
        </div>

        <div className="overflow-y-auto flex-1">
          {error && (
            <div className="mx-5 mt-4 rounded-md border border-red-200 bg-red-50 text-red-700 px-4 py-3 text-sm">
              {error}
            </div>
          )}

          {isTypeMode ? (
            <table className="min-w-full text-sm">
              <thead className="bg-gray-50 dark:bg-gray-800/80 sticky top-0">
                <tr>
                  <th className="px-4 py-3 text-left font-semibold text-gray-700 dark:text-gray-200">
                    {t('dashboard.woType', { defaultValue: 'WO Type' })}
                  </th>
                  {typeColumns.map(column => (
                    <th
                      key={column}
                      className="px-4 py-3 text-right font-semibold text-gray-700 dark:text-gray-200 whitespace-nowrap"
                    >
                      {column}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {loading ? (
                  <tr>
                    <td colSpan={typeColumns.length + 1} className="px-5 py-10 text-center text-gray-500">
                      {t('common.loading', { defaultValue: 'Loading...' })}
                    </td>
                  </tr>
                ) : typeRows.length === 0 ? (
                  <tr>
                    <td colSpan={typeColumns.length + 1} className="px-5 py-10 text-center text-gray-500">
                      {t('common.noData', { defaultValue: 'No data' })}
                    </td>
                  </tr>
                ) : (
                  typeRows.map(row => (
                    <tr key={row.label} className="border-t border-gray-100 dark:border-gray-800">
                      <td className="px-4 py-3">
                        <button
                          type="button"
                          onClick={() => handleTypeCellClick(row.label, 'Total WOs')}
                          className="text-left font-medium text-indigo-700 dark:text-indigo-300 hover:underline"
                        >
                          {row.label}
                        </button>
                      </td>
                      {row.cells.map((value, index) => (
                        <td key={`${row.label}-${typeColumns[index]}`} className="px-4 py-3 text-right">
                          <button
                            type="button"
                            onClick={() => handleTypeCellClick(row.label, typeColumns[index])}
                            className="font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-300"
                          >
                            {typeColumns[index] === 'Completion Rate (%)'
                              ? `${value.toFixed(2)}%`
                              : value}
                          </button>
                        </td>
                      ))}
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          ) : isAssigneeMode ? (
            <table className="min-w-full text-sm">
              <thead className="bg-gray-50 dark:bg-gray-800/80 sticky top-0">
                <tr>
                  <th className="px-4 py-3 text-left font-semibold text-gray-700 dark:text-gray-200">
                    {t('dashboard.assignedTo', { defaultValue: 'Assigned To' })}
                  </th>
                  <th className="px-4 py-3 text-right font-semibold text-indigo-600 dark:text-indigo-300">
                    {t('dashboard.plannedTasks', { defaultValue: 'Planned' })}
                  </th>
                  <th className="px-4 py-3 text-right font-semibold text-green-600 dark:text-green-400">
                    {t('dashboard.completedTasks', { defaultValue: 'Completed' })}
                  </th>
                  <th className="px-4 py-3 text-right font-semibold text-amber-600 dark:text-amber-400">
                    {t('dashboard.cancelledTasks', { defaultValue: 'Cancelled' })}
                  </th>
                  <th className="px-4 py-3 text-right font-semibold text-red-600 dark:text-red-400">
                    {t('dashboard.overdueTasks', { defaultValue: 'Overdue' })}
                  </th>
                  <th className="px-4 py-3 text-right font-semibold text-gray-700 dark:text-gray-200">
                    {t('dashboard.totalTasks', { defaultValue: 'Total' })}
                  </th>
                </tr>
              </thead>
              <tbody>
                {loading ? (
                  <tr>
                    <td colSpan={6} className="px-5 py-10 text-center text-gray-500">
                      {t('common.loading', { defaultValue: 'Loading...' })}
                    </td>
                  </tr>
                ) : assigneeRows.length === 0 ? (
                  <tr>
                    <td colSpan={6} className="px-5 py-10 text-center text-gray-500">
                      {t('common.noData', { defaultValue: 'No data' })}
                    </td>
                  </tr>
                ) : (
                  assigneeRows.map(row => (
                    <tr key={row.assignee} className="border-t border-gray-100 dark:border-gray-800">
                      <td className="px-4 py-3 text-gray-800 dark:text-gray-100">{row.assignee}</td>
                      <td className="px-4 py-3 text-right">
                        <AssigneeCountButton
                          value={row.planned}
                          onClick={() => handleAssigneeCellClick(row.assignee, 'Planned', row.planned)}
                        />
                      </td>
                      <td className="px-4 py-3 text-right">
                        <AssigneeCountButton
                          value={row.completed}
                          onClick={() => handleAssigneeCellClick(row.assignee, 'Completed', row.completed)}
                        />
                      </td>
                      <td className="px-4 py-3 text-right">
                        <AssigneeCountButton
                          value={row.cancelled}
                          onClick={() => handleAssigneeCellClick(row.assignee, 'Cancelled', row.cancelled)}
                        />
                      </td>
                      <td className="px-4 py-3 text-right">
                        <AssigneeCountButton
                          value={row.overdue}
                          onClick={() => handleAssigneeCellClick(row.assignee, 'Overdue', row.overdue)}
                        />
                      </td>
                      <td className="px-4 py-3 text-right font-semibold text-gray-900 dark:text-white">
                        {row.total}
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
              {!loading && assigneeRows.length > 0 && (
                <tfoot>
                  <tr className="border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/80">
                    <td className="px-4 py-3 font-semibold text-gray-800 dark:text-gray-100">
                      {t('dashboard.totalTasks', { defaultValue: 'Total' })}
                    </td>
                    <td className="px-4 py-3 text-right font-semibold text-indigo-600 dark:text-indigo-300">
                      {assigneeTotals.planned}
                    </td>
                    <td className="px-4 py-3 text-right font-semibold text-green-600 dark:text-green-400">
                      {assigneeTotals.completed}
                    </td>
                    <td className="px-4 py-3 text-right font-semibold text-amber-600 dark:text-amber-400">
                      {assigneeTotals.cancelled}
                    </td>
                    <td className="px-4 py-3 text-right font-semibold text-red-600 dark:text-red-400">
                      {assigneeTotals.overdue}
                    </td>
                    <td className="px-4 py-3 text-right font-semibold text-gray-900 dark:text-white">
                      {assigneeTotals.total}
                    </td>
                  </tr>
                </tfoot>
              )}
            </table>
          ) : (
            <table className="min-w-full text-sm">
              <thead className="bg-gray-50 dark:bg-gray-800/80 sticky top-0">
                <tr>
                  <th className="px-5 py-3 text-left font-semibold text-gray-700 dark:text-gray-200">
                    {t('commonFields.status', { defaultValue: 'Status' })}
                  </th>
                  <th className="px-5 py-3 text-right font-semibold text-gray-700 dark:text-gray-200">
                    {t('dashboard.workOrders', { defaultValue: 'Work Orders' })}
                  </th>
                </tr>
              </thead>
              <tbody>
                {loading ? (
                  <tr>
                    <td colSpan={2} className="px-5 py-10 text-center text-gray-500">
                      {t('common.loading', { defaultValue: 'Loading...' })}
                    </td>
                  </tr>
                ) : statusRows.length === 0 ? (
                  <tr>
                    <td colSpan={2} className="px-5 py-10 text-center text-gray-500">
                      {t('common.noData', { defaultValue: 'No data' })}
                    </td>
                  </tr>
                ) : (
                  statusRows.map(row => (
                    <tr
                      key={row.label}
                      className={`border-t border-gray-100 dark:border-gray-800 ${
                        redirectContext === 'wo_status'
                          ? 'cursor-pointer hover:bg-indigo-50 dark:hover:bg-indigo-900/20'
                          : ''
                      }`}
                      onClick={() => handleStatusRowClick(row.label)}
                    >
                      <td className="px-5 py-3">
                        <div className="flex items-center gap-2">
                          <span
                            className="w-2.5 h-2.5 rounded-full flex-shrink-0"
                            style={{ backgroundColor: row.color }}
                          />
                          <span className="text-gray-800 dark:text-gray-100">{row.label}</span>
                        </div>
                      </td>
                      <td className="px-5 py-3 text-right font-semibold text-gray-900 dark:text-white">
                        {row.value}
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
              {!loading && statusRows.length > 0 && !chartData?.hideFooterTotal && (
                <tfoot>
                  <tr className="border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/80">
                    <td className="px-5 py-3 font-semibold text-gray-800 dark:text-gray-100">
                      {t('dashboard.totalWorkOrders', { defaultValue: 'Total Work Orders' })}
                    </td>
                    <td className="px-5 py-3 text-right font-semibold text-gray-900 dark:text-white">
                      {statusTotal}
                    </td>
                  </tr>
                </tfoot>
              )}
            </table>
          )}
        </div>
      </div>
    </div>
  );
};

export default ChartDetailModal;

const AssigneeCountButton: React.FC<{ value: number; onClick: () => void }> = ({ value, onClick }) => {
  if (value <= 0) {
    return <span className="text-gray-400">0</span>;
  }

  return (
    <button
      type="button"
      onClick={onClick}
      className="font-semibold text-gray-900 dark:text-white hover:text-indigo-600 dark:hover:text-indigo-300"
    >
      {value}
    </button>
  );
};
