import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
  ArrowUpDown,
  Calendar,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  ChevronUp,
  Plus,
  Trash2,
  User
} from 'lucide-react';
import { useTranslation } from '../../i18n/LanguageContext';

const toIsoDate = (date) => {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
};

const parseIsoDate = (value) => {
  if (!value || !value.includes('-')) return null;

  const [year, month, day] = value.split('-').map(Number);
  return new Date(year, month - 1, day);
};

const getCalendarDays = (monthDate) => {
  const startOfMonth = new Date(monthDate.getFullYear(), monthDate.getMonth(), 1);
  const offset = (startOfMonth.getDay() + 6) % 7;
  const calendarStart = new Date(startOfMonth.getFullYear(), startOfMonth.getMonth(), 1 - offset);

  return Array.from({ length: 42 }, (_, index) => {
    const day = new Date(calendarStart.getFullYear(), calendarStart.getMonth(), calendarStart.getDate() + index);

    return {
      key: toIsoDate(day),
      date: day,
      isoValue: toIsoDate(day),
      isCurrentMonth: day.getMonth() === monthDate.getMonth()
    };
  });
};

const PatList = ({
  patTypes,
  assessments,
  overview,
  assessmentShareTokens = {},
  testsVisible = true,
  onCreate,
  onEdit,
  onDelete,
  getPatTypeColor,
  getAchievement
}) => {
  const t = useTranslation();
  const datePickerRef = useRef(null);
  const [showCreateMenu, setShowCreateMenu] = useState(false);
  const [activeDatePicker, setActiveDatePicker] = useState(null);
  const [sortConfig, setSortConfig] = useState({ key: 'datum', direction: 'desc' });
  const [filters, setFilters] = useState({ name: '', datum: '' });
  const [visibleMonth, setVisibleMonth] = useState(() => {
    const today = new Date();
    return new Date(today.getFullYear(), today.getMonth(), 1);
  });
  const patTypeOptions = Object.keys(patTypes || {});
  const openAssessments = assessments.filter((assessment) => !assessment.isFinalized);
  const finalizedAssessments = assessments.filter((assessment) => assessment.isFinalized);

  const getResultValue = (assessment) =>
    assessment.exercises.reduce((sum, ex) => sum + (ex.points || 0), 0);

  const normalize = (value) => String(value || '').toLowerCase().trim();
  const formatDateForFilter = (value) => {
    if (!value || !value.includes('-')) return '';
    const [year, month, day] = value.split('-');
    return `${day}.${month}.${year}`;
  };
  const formatDateForRow = (value) => {
    if (!value || !value.includes('-')) return value || '';
    const [year, month, day] = value.split('-');
    return `${year}.${month}.${day}`;
  };
  const monthLabel = useMemo(
    () =>
      new Intl.DateTimeFormat('de-DE', {
        month: 'long',
        year: 'numeric'
      }).format(visibleMonth),
    [visibleMonth]
  );
  const calendarDays = useMemo(() => getCalendarDays(visibleMonth), [visibleMonth]);

  useEffect(() => {
    if (!activeDatePicker) return undefined;

    const handlePointerDown = (event) => {
      if (datePickerRef.current && !datePickerRef.current.contains(event.target)) {
        setActiveDatePicker(null);
      }
    };

    const handleKeyDown = (event) => {
      if (event.key === 'Escape') {
        setActiveDatePicker(null);
      }
    };

    document.addEventListener('mousedown', handlePointerDown);
    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('mousedown', handlePointerDown);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [activeDatePicker]);

  const matchesFilters = (assessment) => {
    const matchesName = !filters.name || normalize(assessment.name).includes(normalize(filters.name));
    const matchesDate = !filters.datum || normalize(assessment.datum).includes(normalize(filters.datum));

    return matchesName && matchesDate;
  };

  const getSortValue = (assessment, key) => {
    if (key === 'name') return (assessment.name || '').toLowerCase();
    if (key === 'datum') return assessment.datum || '';
    if (key === 'result') return getResultValue(assessment);
    return '';
  };

  const sortAssessments = (entries) =>
    [...entries].sort((left, right) => {
      const leftValue = getSortValue(left, sortConfig.key);
      const rightValue = getSortValue(right, sortConfig.key);

      if (leftValue < rightValue) return sortConfig.direction === 'asc' ? -1 : 1;
      if (leftValue > rightValue) return sortConfig.direction === 'asc' ? 1 : -1;
      return 0;
    });

  const sortedOpenAssessments = useMemo(
    () => sortAssessments(openAssessments.filter(matchesFilters)),
    [openAssessments, sortConfig, filters]
  );
  const sortedFinalizedAssessments = useMemo(
    () => sortAssessments(finalizedAssessments.filter(matchesFilters)),
    [finalizedAssessments, sortConfig, filters]
  );

  const handleSort = (key) => {
    setSortConfig((current) =>
      current.key === key
        ? { key, direction: current.direction === 'asc' ? 'desc' : 'asc' }
        : { key, direction: key === 'datum' ? 'desc' : 'asc' }
    );
  };

  const renderSortIcon = (key) => {
    if (sortConfig.key !== key) {
      return <ArrowUpDown className="w-4 h-4 text-gray-400 dark:text-gray-500" aria-hidden="true" />;
    }

    return sortConfig.direction === 'asc' ? (
      <ChevronUp className="w-4 h-4" aria-hidden="true" />
    ) : (
      <ChevronDown className="w-4 h-4" aria-hidden="true" />
    );
  };

  const handleFilterChange = (key, value) => {
    setFilters((current) => ({
      ...current,
      [key]: value
    }));
  };

  const syncVisibleMonth = (value) => {
    const parsedDate = parseIsoDate(value);
    const baseDate = parsedDate || new Date();
    setVisibleMonth(new Date(baseDate.getFullYear(), baseDate.getMonth(), 1));
  };

  const toggleDatePicker = (tableKey) => {
    setActiveDatePicker((current) => {
      if (current !== tableKey) {
        syncVisibleMonth(filters.datum);
        return tableKey;
      }
      return null;
    });
  };

  const selectDate = (value) => {
    handleFilterChange('datum', value);
    syncVisibleMonth(value);
    setActiveDatePicker(null);
  };

  const clearDate = () => {
    handleFilterChange('datum', '');
    syncVisibleMonth('');
    setActiveDatePicker(null);
  };

  const selectToday = () => {
    selectDate(toIsoDate(new Date()));
  };

  const renderAssessmentTable = (tableKey, title, entries, totalEntries, emptyMessage) => {
    const isDatePickerOpen = activeDatePicker === tableKey;

    return (
      <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg border border-gray-100 dark:border-gray-800 overflow-hidden">
      <div className="px-6 py-4 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-800/70">
        <h2 className="text-lg font-bold text-gray-800 dark:text-gray-100">{title}</h2>
        <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
          {t('patlist.count', { count: entries.length })}
          {entries.length !== totalEntries ? ` von ${totalEntries}` : ''}
        </p>
      </div>

      {totalEntries === 0 ? (
        <div className="px-6 py-8 text-sm text-gray-500 dark:text-gray-400">{emptyMessage}</div>
      ) : (
        <div className="overflow-x-auto">
          <table className="w-full">
            <thead className="bg-gray-100 dark:bg-gray-800 text-left">
              <tr>
                <th className="px-6 py-3 text-sm font-semibold text-gray-700 dark:text-gray-200">
                  <div className="flex items-center gap-3">
                    <button
                      type="button"
                      onClick={() => handleSort('name')}
                      className="inline-flex items-center gap-2 hover:text-gray-900 dark:hover:text-white transition"
                    >
                      {t('patlist.col_name')}
                      {renderSortIcon('name')}
                    </button>
                    <input
                      type="text"
                      value={filters.name}
                      onChange={(event) => handleFilterChange('name', event.target.value)}
                      aria-label={t('patlist.filter_name')}
                      className="w-40 rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-sm font-normal text-gray-700 dark:text-gray-200"
                    />
                  </div>
                </th>
                <th className="px-6 py-3 text-sm font-semibold text-gray-700 dark:text-gray-200">
                  <div className="flex items-center gap-3">
                    <button
                      type="button"
                      onClick={() => handleSort('datum')}
                      className="inline-flex items-center gap-2 hover:text-gray-900 dark:hover:text-white transition"
                    >
                      {t('patlist.col_date')}
                      {renderSortIcon('datum')}
                    </button>
                    <div ref={isDatePickerOpen ? datePickerRef : null} className="relative">
                      <button
                        type="button"
                        onClick={() => toggleDatePicker(tableKey)}
                        aria-label={t('patlist.filter_date')}
                        aria-expanded={isDatePickerOpen}
                        className="flex w-36 items-center justify-between rounded border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-950 px-3 py-2 text-left text-sm font-normal text-gray-700 dark:text-gray-200"
                      >
                        <span>{formatDateForFilter(filters.datum) || t('patlist.date_placeholder')}</span>
                        <Calendar className="h-4 w-4 text-gray-500 dark:text-gray-400" aria-hidden="true" />
                      </button>

                      {isDatePickerOpen && (
                        <div className="absolute left-0 top-full z-20 mt-2 w-80 rounded-xl border border-gray-200 bg-white p-3 shadow-2xl dark:border-gray-700 dark:bg-gray-900">
                          <div className="mb-3 flex items-center justify-between">
                            <button
                              type="button"
                              onClick={() =>
                                setVisibleMonth(
                                  (current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
                                )
                              }
                              className="rounded-lg p-2 text-gray-500 transition hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-white"
                              aria-label={t('patlist.prev_month')}
                            >
                              <ChevronLeft className="h-4 w-4" aria-hidden="true" />
                            </button>
                            <span className="text-sm font-semibold capitalize text-gray-800 dark:text-gray-100">
                              {monthLabel}
                            </span>
                            <button
                              type="button"
                              onClick={() =>
                                setVisibleMonth(
                                  (current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
                                )
                              }
                              className="rounded-lg p-2 text-gray-500 transition hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-white"
                              aria-label={t('patlist.next_month')}
                            >
                              <ChevronRight className="h-4 w-4" aria-hidden="true" />
                            </button>
                          </div>

                          <div className="grid grid-cols-7 gap-1 text-center text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                            {t('patlist.days').split(' ').map((label, index) => (
                              <span key={`${label}-${index}`}>{label}</span>
                            ))}
                          </div>

                          <div className="mt-2 grid grid-cols-7 gap-1">
                            {calendarDays.map((day) => {
                              const isSelected = day.isoValue === filters.datum;

                              return (
                                <button
                                  key={day.key}
                                  type="button"
                                  onClick={() => selectDate(day.isoValue)}
                                  className={`flex h-10 items-center justify-center rounded-lg text-sm transition ${
                                    isSelected
                                      ? 'bg-indigo-600 text-white'
                                      : day.isCurrentMonth
                                        ? 'text-gray-800 hover:bg-gray-100 dark:text-gray-100 dark:hover:bg-gray-800'
                                        : 'text-gray-400 hover:bg-gray-100 dark:text-gray-600 dark:hover:bg-gray-800'
                                  }`}
                                >
                                  {day.date.getDate()}
                                </button>
                              );
                            })}
                          </div>

                          <div className="mt-3 flex items-center justify-between border-t border-gray-200 pt-3 dark:border-gray-700">
                            <button
                              type="button"
                              onClick={selectToday}
                              className="rounded-lg bg-gray-100 px-3 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700"
                            >
                              {t('patlist.today')}
                            </button>
                            <button
                              type="button"
                              onClick={clearDate}
                              className="rounded-lg bg-gray-100 px-3 py-2 text-sm font-medium text-gray-700 transition hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700"
                            >
                              {t('patlist.delete')}
                            </button>
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                </th>
                <th className="px-6 py-3 text-sm font-semibold text-gray-700 dark:text-gray-200">
                  <div className="flex items-center gap-3">
                    <button
                      type="button"
                      onClick={() => handleSort('result')}
                      className="inline-flex items-center gap-2 hover:text-gray-900 dark:hover:text-white transition"
                    >
                      {t('patlist.col_result')}
                      {renderSortIcon('result')}
                    </button>
                  </div>
                </th>
                <th className="px-6 py-3 text-sm font-semibold text-gray-700 dark:text-gray-200 text-right"></th>
              </tr>
            </thead>
            <tbody>
              {entries.length === 0 ? (
                <tr className="border-t border-gray-200 dark:border-gray-800">
                  <td colSpan="4" className="px-6 py-8 text-sm text-gray-500 dark:text-gray-400">
                    {emptyMessage}
                  </td>
                </tr>
              ) : entries.map((assessment) => {
                const shareToken = assessmentShareTokens[assessment.id];
                const hasShare = Boolean(shareToken);
                const totalPoints = getResultValue(assessment);
                const achievement = getAchievement(assessment.patType, totalPoints);

                return (
                  <tr
                    key={assessment.id}
                    className="border-t border-gray-200 dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800/40"
                  >
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="flex items-center gap-2 text-sm">
                        <span className="font-semibold text-gray-900 dark:text-gray-100">{assessment.name}</span>
                        <span
                          className={`px-3 py-1 rounded-full text-xs font-semibold ${getPatTypeColor(
                            assessment.patType
                          )}`}
                        >
                          {assessment.patType}
                        </span>
                        {hasShare && (
                          <span className={`px-3 py-1 rounded-full text-xs font-semibold ${
                            testsVisible
                              ? 'bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-200'
                              : 'bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200'
                          }`}>
                            {testsVisible ? t('patlist.share_active') : t('patlist.share_paused')}
                          </span>
                        )}
                        {assessment.isFinalized && (
                          <span className="px-3 py-1 rounded-full text-xs font-semibold bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200">
                            {t('patlist.finalized')}
                          </span>
                        )}
                      </div>
                    </td>
                    <td className="px-6 py-4 text-sm text-gray-600 dark:text-gray-300 whitespace-nowrap">
                      <div className="inline-flex items-center gap-2">
                        <Calendar className="w-4 h-4" aria-hidden="true" />
                        {formatDateForRow(assessment.datum)}
                      </div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="flex items-center gap-3">
                        <span className="text-xl font-bold text-green-600 dark:text-green-300">
                          {totalPoints.toFixed(0)}
                        </span>
                        <span className={`inline-flex px-2 py-1 rounded text-xs font-semibold ${achievement.color} ${achievement.text}`}>
                        {achievement.name}
                        </span>
                      </div>
                    </td>
                    <td className="px-6 py-4 whitespace-nowrap">
                      <div className="flex items-center justify-end gap-2">
                        <button
                          onClick={() => onEdit(assessment)}
                          className="bg-indigo-600 text-white px-4 py-2 rounded hover:bg-indigo-700 transition text-sm"
                        >
                          {t('patlist.open')}
                        </button>
                        <button
                          onClick={(e) => {
                            e.stopPropagation();
                            onDelete(assessment.id);
                          }}
                          className="text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 p-2"
                          title={t('patlist.delete')}
                        >
                          <Trash2 className="w-5 h-5" aria-hidden="true" />
                        </button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}
      </div>
    );
  };

  return (
    <div className="min-h-screen bg-gradient-to-br from-green-50 to-blue-100 dark:from-gray-950 dark:to-gray-900 p-6 text-gray-900 dark:text-gray-100">
      <div className="max-w-7xl mx-auto">
        <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg p-6 mb-6 border border-gray-100 dark:border-gray-800">
          <div className="flex items-center justify-between">
            <h1 className="text-3xl font-bold text-gray-800 dark:text-gray-100">{t('patlist.title')}</h1>
            <div className="relative">
              <button
                onClick={() => setShowCreateMenu((current) => !current)}
                className="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition flex items-center justify-center gap-2"
              >
                <Plus className="w-4 h-4" />
                {t('patlist.new_assessment')}
              </button>

              {showCreateMenu && (
                <div className="absolute right-0 top-full mt-2 w-48 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 shadow-lg z-10 overflow-hidden">
                  {patTypeOptions.map((patType) => (
                    <button
                      key={patType}
                      type="button"
                      onClick={() => {
                        setShowCreateMenu(false);
                        onCreate(patType);
                      }}
                      className="w-full px-4 py-3 text-left text-sm font-medium text-gray-800 dark:text-gray-100 hover:bg-gray-100 dark:hover:bg-gray-800 transition"
                    >
                      {patType}
                    </button>
                  ))}
                </div>
              )}
            </div>
          </div>

        </div>

        {overview && <div className="mt-6">{overview}</div>}

        {assessments.length > 0 && (
          <div className="space-y-6">
            {renderAssessmentTable(
              'open',
              t('patlist.open_assessments'),
              sortedOpenAssessments,
              openAssessments.length,
              t('patlist.no_open')
            )}
            {renderAssessmentTable(
              'finalized',
              t('patlist.closed_assessments'),
              sortedFinalizedAssessments,
              finalizedAssessments.length,
              t('patlist.no_closed')
            )}
          </div>
        )}

        {assessments.length === 0 && (
          <div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg p-12 text-center border border-gray-100 dark:border-gray-800">
            <User className="w-16 h-16 mx-auto mb-4 text-gray-300 dark:text-gray-700" aria-hidden="true" />
            <p className="text-gray-600 dark:text-gray-300 mb-4">{t('patlist.no_assessments')}</p>
            <p className="text-sm text-gray-500 dark:text-gray-400">{t('patlist.no_assessments_hint')}</p>
          </div>
        )}
      </div>
    </div>
  );
};

export default PatList;
