"use client";

import { User, MapPin } from "lucide-react";
import { shortAddress } from "./constants";
import type { ScheduleDayMerged, ScheduleClassWithLocation } from "./constants";

interface ScheduleGroup {
  trainer: string;
  type: string;
  level?: string;
  hasSlots: boolean;
  recruiting: boolean;
  location?: string;
  locationAddress?: string;
  slots: { day: string; dayShort: string; time: string }[];
}

function buildGroups(days: ScheduleDayMerged[]): ScheduleGroup[] {
  const map = new Map<string, ScheduleGroup>();

  for (const day of days) {
    for (const cls of day.classes as ScheduleClassWithLocation[]) {
      // Use groupId if available, otherwise fall back to trainer+type+location
      const locPart = cls.locationName ?? "";
      const key = cls.groupId
        ? `${cls.groupId}||${locPart}`
        : `${cls.trainer}||${cls.type}||${locPart}`;

      const existing = map.get(key);
      if (existing) {
        existing.slots.push({ day: day.day, dayShort: day.dayShort, time: cls.time });
        if (cls.hasSlots) existing.hasSlots = true;
        if (cls.recruiting) existing.recruiting = true;
        if (cls.level && !existing.level) existing.level = cls.level;
      } else {
        map.set(key, {
          trainer: cls.trainer,
          type: cls.type,
          level: cls.level,
          hasSlots: !!cls.hasSlots,
          recruiting: !!cls.recruiting,
          location: cls.locationName,
          locationAddress: cls.locationAddress,
          slots: [{ day: day.day, dayShort: day.dayShort, time: cls.time }],
        });
      }
    }
  }

  return Array.from(map.values());
}

/** Group slots by day, then merge days that share identical time sets */
function mergeSlotsByDay(slots: { day: string; dayShort: string; time: string }[]): { days: string[]; times: string[] }[] {
  // Step 1: collect times per day
  const dayMap = new Map<string, { dayShort: string; times: string[] }>();
  const dayOrder: string[] = [];
  for (const s of slots) {
    const existing = dayMap.get(s.day);
    if (existing) {
      if (!existing.times.includes(s.time)) existing.times.push(s.time);
    } else {
      dayMap.set(s.day, { dayShort: s.dayShort, times: [s.time] });
      dayOrder.push(s.day);
    }
  }
  // Sort times within each day
  for (const entry of dayMap.values()) entry.times.sort();

  // Step 2: merge days with identical time sets
  const result: { days: string[]; times: string[] }[] = [];
  const used = new Set<string>();
  for (const day of dayOrder) {
    if (used.has(day)) continue;
    const entry = dayMap.get(day)!;
    const timeKey = entry.times.join("|");
    const days = [entry.dayShort];
    used.add(day);
    for (const other of dayOrder) {
      if (used.has(other)) continue;
      const o = dayMap.get(other)!;
      if (o.times.join("|") === timeKey) { days.push(o.dayShort); used.add(other); }
    }
    result.push({ days, times: entry.times });
  }
  return result;
}

/** Group schedule groups by trainer for compact display */
function groupByTrainer(groups: ScheduleGroup[]): Map<string, ScheduleGroup[]> {
  const map = new Map<string, ScheduleGroup[]>();
  for (const g of groups) {
    const existing = map.get(g.trainer);
    if (existing) existing.push(g);
    else map.set(g.trainer, [g]);
  }
  return map;
}

/** Within a trainer's groups, cluster by class type preserving order */
function groupByType(groups: ScheduleGroup[]): { type: string; groups: ScheduleGroup[] }[] {
  const result: { type: string; groups: ScheduleGroup[] }[] = [];
  const map = new Map<string, ScheduleGroup[]>();
  for (const g of groups) {
    const existing = map.get(g.type);
    if (existing) {
      existing.push(g);
    } else {
      const arr = [g];
      map.set(g.type, arr);
      result.push({ type: g.type, groups: arr });
    }
  }
  return result;
}

interface GroupViewProps {
  typeDots: Record<string, string>;
  filteredDays: ScheduleDayMerged[];
  filterType: string | null;
  setFilterType: (type: string | null) => void;
  filterTrainer: string | null;
  setFilterTrainer: (trainer: string | null) => void;
  showLocation?: boolean;
  onBook?: (groupInfo: string) => void;
}

export function GroupView({
  typeDots,
  filteredDays,
  filterType,
  setFilterType,
  filterTrainer,
  setFilterTrainer,
  showLocation,
  onBook,
}: GroupViewProps) {
  const groups = buildGroups(filteredDays);
  const byTrainer = groupByTrainer(groups);

  if (groups.length === 0) {
    return (
      <div className="py-12 text-center text-sm text-neutral-400 dark:text-white/30">
        Нет занятий по выбранным фильтрам
      </div>
    );
  }

  return (
    <div className="mt-8 space-y-3 px-4 sm:px-6 lg:px-8 xl:px-6 max-w-4xl mx-auto">
      {Array.from(byTrainer.entries()).map(([trainer, trainerGroups]) => {
        const byType = groupByType(trainerGroups);
        const totalGroups = trainerGroups.length;

        return (
          <div
            key={trainer}
            className="rounded-xl border border-neutral-200 bg-white overflow-hidden dark:border-white/[0.06] dark:bg-[#0a0a0a]"
          >
            {/* Trainer header */}
            <button
              onClick={() => setFilterTrainer(filterTrainer === trainer ? null : trainer)}
              className={`flex items-center gap-2 w-full px-4 py-2.5 text-left transition-colors cursor-pointer ${
                filterTrainer === trainer
                  ? "bg-gold/10 dark:bg-gold/5"
                  : "bg-neutral-50 dark:bg-white/[0.02]"
              }`}
            >
              <User size={14} className={filterTrainer === trainer ? "text-gold" : "text-neutral-400 dark:text-white/40"} />
              <span className={`text-sm font-semibold ${
                filterTrainer === trainer ? "text-gold" : "text-neutral-800 dark:text-white/80"
              }`}>
                {trainer}
              </span>
              <span className="ml-auto text-[10px] text-neutral-400 dark:text-white/25">
                {totalGroups === 1 ? "1 группа" : `${totalGroups} групп${totalGroups < 5 ? "ы" : ""}`}
              </span>
            </button>

            {/* Type → Groups */}
            <div className="divide-y divide-neutral-100 dark:divide-white/[0.04]">
              {byType.map(({ type, groups: typeGroups }) => {
                const dotColor = typeDots[type] ?? "bg-white/30";

                return (
                  <div key={type} className="px-4 py-2.5">
                    {/* Class type row */}
                    <button
                      onClick={() => setFilterType(filterType === type ? null : type)}
                      className="flex items-center gap-1.5 cursor-pointer"
                    >
                      <span className={`h-2 w-2 shrink-0 rounded-full ${dotColor}`} />
                      <span className="text-sm font-medium text-neutral-800 dark:text-white/80">
                        {type}
                      </span>
                    </button>

                    {/* Group rows under this type */}
                    <div className="mt-1.5 space-y-1 pl-3.5">
                      {typeGroups.map((group, gi) => {
                        const merged = mergeSlotsByDay(group.slots);

                        return (
                          <div
                            key={gi}
                            className="flex items-center gap-2 flex-wrap"
                          >
                            {/* Datetimes */}
                            <div className="flex items-center gap-0.5 flex-wrap">
                              {merged.map((m, i) => (
                                <span key={i} className="inline-flex items-center gap-1 text-xs">
                                  {i > 0 && <span className="text-neutral-300 dark:text-white/15 mx-0.5">·</span>}
                                  <span className="rounded bg-gold/10 px-1.5 py-0.5 text-[10px] font-bold text-gold-dark dark:text-gold">
                                    {m.days.join(", ")}
                                  </span>
                                  <span className="font-medium tabular-nums text-neutral-500 dark:text-white/45">
                                    {m.times.join(", ")}
                                  </span>
                                </span>
                              ))}
                            </div>

                            {/* Badges */}
                            {group.level && (
                              <span className="rounded-full bg-rose-500/15 border border-rose-500/25 px-2 py-px text-[10px] font-semibold text-rose-600 dark:text-rose-400">
                                {group.level}
                              </span>
                            )}
                            {group.hasSlots && (
                              <span className="rounded-full bg-emerald-500/15 border border-emerald-500/25 px-2 py-px text-[10px] font-semibold text-emerald-600 dark:text-emerald-400">
                                есть места
                              </span>
                            )}
                            {group.recruiting && (
                              <span className="rounded-full bg-sky-500/15 border border-sky-500/25 px-2 py-px text-[10px] font-semibold text-sky-600 dark:text-sky-400">
                                набор
                              </span>
                            )}

                            {/* Location */}
                            {showLocation && group.location && (
                              <span className="flex items-center gap-1 text-[10px] text-neutral-400 dark:text-white/25">
                                <MapPin size={9} />
                                {group.location}
                              </span>
                            )}

                            {/* Book button */}
                            {onBook && (
                              <button
                                onClick={() => onBook(`${group.type}, ${group.trainer}, ${group.slots.map(s => s.dayShort).join("/")} ${group.slots[0]?.time ?? ""}`)}
                                className="ml-auto rounded-lg bg-gold/10 border border-gold/20 px-3 py-1 text-[11px] font-semibold text-gold hover:bg-gold/20 transition-colors cursor-pointer shrink-0"
                              >
                                Записаться
                              </button>
                            )}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        );
      })}
    </div>
  );
}
