"use client";

import { useMemo, useState } from "react";
import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button";
import { CheckCircle2 } from "lucide-react";
import type { TrackedDeadline } from "../types";
import { getDeadlineType } from "../services/deadline-catalog";
import { getDeadlineDisplayStatus } from "../services/deadline-service";
import { cn } from "@/shared/lib/utils";

// ── Types ──

interface TimelineMilestone {
  deadline: TrackedDeadline;
  label: string;
  description: string;
  dueDate: string;
  /** Position on the timeline (0..1) */
  position: number;
  /** Status of this milestone */
  status: "completed" | "active" | "expired" | "upcoming" | "background" | "paused";
  /** Human-readable status text */
  statusText: string;
  /** Whether this is the main (user-created) deadline or an auto-tracked milestone */
  isMain: boolean;
  /** Days remaining (negative = overdue) */
  daysRemaining: number;
}

interface DeadlineTimelineProps {
  /** All tracked deadlines on this entry */
  deadlines: TrackedDeadline[];
  /** Callback to resolve a sub-deadline inline (id, note) */
  onResolveInline?: (deadlineId: string, note: string) => void;
}

// ── Build timeline from deadlines ──

function buildTimeline(deadlines: TrackedDeadline[]): {
  mainDeadlines: TimelineMilestone[];
  groups: Map<string, TimelineMilestone[]>;
} {
  const mainDeadlines: TimelineMilestone[] = [];
  // Group auto-tracked by their chain parent (or by category proximity to a main deadline)
  const groups = new Map<string, TimelineMilestone[]>();

  const now = new Date();
  now.setHours(0, 0, 0, 0);

  // Separate main vs auto-tracked deadlines
  const mainDls: TrackedDeadline[] = [];
  const autoDls: TrackedDeadline[] = [];

  for (const dl of deadlines) {
    const def = getDeadlineType(dl.typeId);
    if (def?.backgroundOnly) continue; // Skip background-only entirely
    if (def?.autoTrack) {
      autoDls.push(dl);
    } else {
      mainDls.push(dl);
    }
  }

  // For each main deadline, find its associated milestones
  for (const main of mainDls) {
    const def = getDeadlineType(main.typeId);
    const mainStart = new Date(main.startDate);
    mainStart.setHours(0, 0, 0, 0);
    const mainDue = new Date(main.dueDate);
    mainDue.setHours(0, 0, 0, 0);
    const totalSpan = Math.max(1, mainDue.getTime() - mainStart.getTime());
    const mainDaysRemaining = Math.ceil(
      (mainDue.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),
    );

    const mainStatus = getMainStatus(main, mainDaysRemaining);

    mainDeadlines.push({
      deadline: main,
      label: def?.label ?? main.typeId,
      description: def?.description ?? "",
      dueDate: main.dueDate,
      position: 1,
      status: mainStatus,
      statusText: getStatusText(mainStatus, mainDaysRemaining),
      isMain: true,
      daysRemaining: mainDaysRemaining,
    });

    // Find auto-tracked milestones that fall within this main deadline's range
    const milestones: TimelineMilestone[] = [];
    for (const auto of autoDls) {
      const autoDef = getDeadlineType(auto.typeId);
      if (!autoDef) continue;

      // Check if this auto-tracked deadline is related (same start date or chain parent in this group)
      const autoStart = new Date(auto.startDate);
      autoStart.setHours(0, 0, 0, 0);
      const autoDue = new Date(auto.dueDate);
      autoDue.setHours(0, 0, 0, 0);

      // Only include if it starts from the same point or is within the main's time range
      const startsNearMain =
        Math.abs(autoStart.getTime() - mainStart.getTime()) <
        2 * 24 * 60 * 60 * 1000;
      const isChainRelated = auto.chainParentId
        ? deadlines.some(
            (d) =>
              d.id === auto.chainParentId &&
              (d.typeId === main.typeId ||
                d.chainParentId === main.id),
          )
        : false;

      if (!startsNearMain && !isChainRelated) continue;

      const pos = Math.min(
        0.95,
        Math.max(
          0.05,
          (autoDue.getTime() - mainStart.getTime()) / totalSpan,
        ),
      );
      const autoDaysRemaining = Math.ceil(
        (autoDue.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),
      );
      const autoStatus = getAutoStatus(auto, autoDaysRemaining, autoDef.id);

      milestones.push({
        deadline: auto,
        label: autoDef.label,
        description: getExpiredDescription(autoDef.id, autoStatus),
        dueDate: auto.dueDate,
        position: pos,
        status: autoStatus,
        statusText: getAutoStatusText(autoDef.id, autoStatus, autoDaysRemaining),
        isMain: false,
        daysRemaining: autoDaysRemaining,
      });
    }

    // Sort milestones by position
    milestones.sort((a, b) => a.position - b.position);
    if (milestones.length > 0) {
      groups.set(main.id, milestones);
    }
  }

  // Handle auto-tracked deadlines that aren't associated with any main deadline
  const associatedAutoIds = new Set<string>();
  for (const ms of groups.values()) {
    for (const m of ms) {
      associatedAutoIds.add(m.deadline.id);
    }
  }
  const orphanedAuto = autoDls.filter(
    (dl) => !associatedAutoIds.has(dl.id),
  );

  if (orphanedAuto.length > 0 && mainDls.length === 0) {
    // If there are ONLY auto-tracked deadlines (no main), show them as standalone milestones
    for (const auto of orphanedAuto) {
      const autoDef = getDeadlineType(auto.typeId);
      if (!autoDef) continue;
      const autoDue = new Date(auto.dueDate);
      autoDue.setHours(0, 0, 0, 0);
      const daysRemaining = Math.ceil(
        (autoDue.getTime() - now.getTime()) / (1000 * 60 * 60 * 24),
      );
      const status = getMainStatus(auto, daysRemaining);

      mainDeadlines.push({
        deadline: auto,
        label: autoDef.label,
        description: autoDef.description,
        dueDate: auto.dueDate,
        position: 1,
        status,
        statusText: getStatusText(status, daysRemaining),
        isMain: true,
        daysRemaining,
      });
    }
  }

  return { mainDeadlines, groups };
}

function getMainStatus(
  dl: TrackedDeadline,
  daysRemaining: number,
): TimelineMilestone["status"] {
  if (dl.resolution === "completed") return "completed";
  if (dl.resolution !== "pending") return "completed";
  if (dl.pausedAt) return "paused";
  if (daysRemaining < 0) return "expired";
  if (daysRemaining <= 5) return "active";
  return "upcoming";
}

function getAutoStatus(
  dl: TrackedDeadline,
  daysRemaining: number,
  typeId: string,
): TimelineMilestone["status"] {
  if (dl.resolution !== "pending") return "completed";
  if (daysRemaining < 0) {
    // For verification-type deadlines, "expired" means the window has passed
    if (typeId.includes("verificare")) return "expired";
    return "expired";
  }
  if (daysRemaining <= 2) return "active";
  return "upcoming";
}

function getStatusText(
  status: TimelineMilestone["status"],
  daysRemaining: number,
): string {
  switch (status) {
    case "completed":
      return "Finalizat";
    case "paused":
      return "Suspendat — așteptare completări";
    case "expired":
      return daysRemaining < 0
        ? `${Math.abs(daysRemaining)}z depasit`
        : "Depasit";
    case "active":
      return daysRemaining === 0
        ? "Astazi"
        : `${daysRemaining}z ramase`;
    case "upcoming":
      return `${daysRemaining}z ramase`;
    default:
      return "";
  }
}

function getAutoStatusText(
  typeId: string,
  status: TimelineMilestone["status"],
  daysRemaining: number,
): string {
  if (status === "completed") return "Finalizat";
  if (status === "expired") {
    if (typeId.includes("verificare")) {
      return "Expirat — nu se mai pot solicita clarificari";
    }
    return `Depasit cu ${Math.abs(daysRemaining)}z`;
  }
  if (daysRemaining === 0) return "Astazi";
  return `${daysRemaining}z`;
}

function getExpiredDescription(
  typeId: string,
  status: TimelineMilestone["status"],
): string {
  if (status === "expired" && typeId.includes("verificare")) {
    return "Termenul de verificare a expirat — nu se mai pot solicita clarificari si nu se mai poate restitui dosarul.";
  }
  if (status === "expired" && (typeId.includes("emitere") || typeId.includes("ac-emitere"))) {
    return "Termenul legal de emitere a fost depasit — poate fi sesizat ISC (sanctiuni).";
  }
  return "";
}

function formatShortDate(iso: string): string {
  try {
    const d = new Date(iso);
    return `${String(d.getDate()).padStart(2, "0")}.${String(d.getMonth() + 1).padStart(2, "0")}`;
  } catch {
    return iso;
  }
}

function formatFullDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString("ro-RO", {
      day: "2-digit",
      month: "long",
      year: "numeric",
    });
  } catch {
    return iso;
  }
}

// ── Component ──

export function DeadlineTimeline({ deadlines, onResolveInline }: DeadlineTimelineProps) {
  const { mainDeadlines, groups } = useMemo(
    () => buildTimeline(deadlines),
    [deadlines],
  );

  if (mainDeadlines.length === 0) return null;

  return (
    <div className="space-y-4">
      {mainDeadlines.map((main) => {
        const milestones = groups.get(main.deadline.id) ?? [];
        const displayStatus = getDeadlineDisplayStatus(main.deadline);

        return (
          <div key={main.deadline.id} className="space-y-2">
            {/* Main deadline header */}
            <div
              className={cn(
                "rounded-lg border px-3 py-2",
                main.status === "expired"
                  ? "border-destructive/40 bg-destructive/5"
                  : main.status === "paused"
                    ? "border-blue-400/40 bg-blue-50/30 dark:border-blue-800 dark:bg-blue-950/20"
                    : main.status === "active"
                      ? "border-amber-300 bg-amber-50/30 dark:border-amber-800 dark:bg-amber-950/20"
                      : main.status === "completed"
                        ? "border-muted bg-muted/20"
                        : "border-border",
              )}
            >
              <div className="flex items-center justify-between">
                <span className="text-xs font-medium">{main.label}</span>
                <Badge
                  variant="outline"
                  className={cn(
                    "text-[10px]",
                    displayStatus.variant === "red" &&
                      "border-red-400 text-red-700 dark:text-red-400",
                    displayStatus.variant === "yellow" &&
                      "border-amber-400 text-amber-700 dark:text-amber-400",
                    displayStatus.variant === "green" &&
                      "border-green-400 text-green-700 dark:text-green-400",
                    displayStatus.variant === "blue" &&
                      "border-blue-400 text-blue-700 dark:text-blue-400",
                    displayStatus.variant === "gray" &&
                      "border-muted text-muted-foreground",
                  )}
                >
                  {displayStatus.label}
                </Badge>
              </div>

              <div className="mt-1 flex flex-wrap items-center gap-3 text-[10px] text-muted-foreground">
                <span>Start: {formatShortDate(main.deadline.startDate)}</span>
                <span title={`Data maximă: ${formatFullDate(main.dueDate)}`}>
                  Scadent: {formatShortDate(main.dueDate)}
                </span>
                {main.status === "paused" && (
                  <span className="font-medium text-blue-600 dark:text-blue-400">
                    ⏸ Suspendat — așteptare completări
                  </span>
                )}
                {(main.deadline.totalPausedDays ?? 0) > 0 && (
                  <span className="text-blue-500/70" title="Total zile in care termenul a fost suspendat">
                    ({main.deadline.totalPausedDays}z suspendate)
                  </span>
                )}
                {main.daysRemaining > 0 && main.status !== "completed" && main.status !== "paused" && (
                  <span
                    className={cn(
                      "font-medium",
                      main.daysRemaining <= 5
                        ? "text-amber-600 dark:text-amber-400"
                        : "text-foreground",
                    )}
                  >
                    {main.daysRemaining}z ramase
                  </span>
                )}
                {main.daysRemaining < 0 && main.status === "expired" && (
                  <span className="font-medium text-destructive">
                    {Math.abs(main.daysRemaining)}z depasit
                  </span>
                )}
              </div>

              {main.status === "expired" && main.deadline.typeId.includes("emitere") && (
                <p className="mt-1 text-[10px] font-medium text-destructive">
                  Termenul legal de emitere a fost depasit — poate fi sesizat ISC (sanctiuni)
                </p>
              )}

              {main.deadline.resolutionNote && (
                <p className="mt-1 text-[10px] text-muted-foreground italic">
                  {main.deadline.resolutionNote}
                </p>
              )}

              {/* Progress bar */}
              {main.status !== "completed" && (
                <ProgressBar deadline={main.deadline} status={main.status} />
              )}

              {/* Milestones timeline */}
              {milestones.length > 0 && (
                <MilestoneTimeline
                  milestones={milestones}
                  mainDeadline={main.deadline}
                  onResolveInline={onResolveInline}
                />
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ── Progress bar ──

function ProgressBar({
  deadline,
  status,
}: {
  deadline: TrackedDeadline;
  status: TimelineMilestone["status"];
}) {
  const now = new Date();
  now.setHours(0, 0, 0, 0);
  const start = new Date(deadline.startDate);
  start.setHours(0, 0, 0, 0);
  const due = new Date(deadline.dueDate);
  due.setHours(0, 0, 0, 0);

  const total = Math.max(1, due.getTime() - start.getTime());
  const elapsed = now.getTime() - start.getTime();
  const pct = Math.min(100, Math.max(0, (elapsed / total) * 100));

  return (
    <div className="mt-2 h-1.5 rounded-full bg-muted">
      <div
        className={cn(
          "h-1.5 rounded-full transition-all",
          status === "expired"
            ? "bg-red-500"
            : status === "paused"
              ? "bg-blue-400 animate-pulse"
              : status === "active"
                ? "bg-amber-500"
                : "bg-green-500",
        )}
        style={{ width: `${pct}%` }}
      />
    </div>
  );
}

// ── Milestone timeline (horizontal dots along the progress bar) ──

function MilestoneTimeline({
  milestones,
  mainDeadline,
  onResolveInline,
}: {
  milestones: TimelineMilestone[];
  mainDeadline: TrackedDeadline;
  onResolveInline?: (deadlineId: string, note: string) => void;
}) {
  const [resolvingId, setResolvingId] = useState<string | null>(null);
  const [resolveNote, setResolveNote] = useState("");
  return (
    <div className="mt-3 space-y-0">
      {/* Timeline track */}
      <div className="relative h-6">
        {/* Base line */}
        <div className="absolute top-[10px] left-0 right-0 h-px bg-border" />

        {/* Start marker */}
        <div className="absolute top-[7px] left-0 h-1.5 w-1.5 rounded-full bg-muted-foreground" />

        {/* End marker (main deadline) */}
        <div className="absolute top-[7px] right-0 h-1.5 w-1.5 rounded-full bg-muted-foreground" />

        {/* Milestone dots */}
        {milestones.map((ms) => (
          <div
            key={ms.deadline.id}
            className="absolute top-0"
            style={{ left: `${ms.position * 100}%` }}
            title={`${ms.label}\nData maximă: ${formatFullDate(ms.dueDate)}\n${ms.statusText}${ms.description ? `\n${ms.description}` : ""}`}
          >
            <div
              className={cn(
                "h-5 w-5 -ml-2.5 rounded-full border-2 flex items-center justify-center",
                ms.status === "completed"
                  ? "border-green-500 bg-green-100 dark:bg-green-900/40"
                  : ms.status === "expired"
                    ? "border-muted-foreground/40 bg-muted"
                    : ms.status === "active"
                      ? "border-amber-500 bg-amber-100 dark:bg-amber-900/40"
                      : "border-border bg-background",
              )}
            >
              {ms.status === "completed" && (
                <span className="text-[8px] text-green-700 dark:text-green-300">
                  ✓
                </span>
              )}
              {ms.status === "expired" && (
                <span className="text-[8px] text-muted-foreground">—</span>
              )}
            </div>
          </div>
        ))}
      </div>

      {/* Milestone labels below */}
      <div className="space-y-1.5 pt-1">
        {milestones.map((ms) => {
          const canResolve =
            onResolveInline &&
            ms.deadline.resolution === "pending" &&
            ms.status !== "expired";
          const isResolving = resolvingId === ms.deadline.id;

          return (
            <div key={ms.deadline.id} className="text-[10px]">
              <div className="flex items-start gap-2">
                <span
                  className={cn(
                    "mt-0.5 h-1.5 w-1.5 shrink-0 rounded-full",
                    ms.status === "completed"
                      ? "bg-green-500"
                      : ms.status === "expired"
                        ? "bg-muted-foreground/40"
                        : ms.status === "active"
                          ? "bg-amber-500"
                          : "bg-border",
                  )}
                />
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2">
                    <span
                      className={cn(
                        "font-medium",
                        ms.status === "expired" && "text-muted-foreground line-through",
                        ms.status === "completed" && "text-muted-foreground",
                      )}
                    >
                      {ms.label}
                    </span>
                    <span className="text-muted-foreground" title={`Data maximă: ${formatFullDate(ms.dueDate)}`}>
                      {formatShortDate(ms.dueDate)}
                    </span>
                    <span
                      className={cn(
                        ms.status === "expired"
                          ? "text-muted-foreground italic"
                          : ms.status === "active"
                            ? "text-amber-600 dark:text-amber-400 font-medium"
                            : ms.status === "completed"
                              ? "text-green-600 dark:text-green-400"
                              : "text-muted-foreground",
                      )}
                    >
                      {ms.statusText}
                    </span>
                    {canResolve && !isResolving && (
                      <button
                        onClick={() => {
                          setResolvingId(ms.deadline.id);
                          setResolveNote("");
                        }}
                        className="ml-1 flex items-center gap-0.5 text-green-600 hover:text-green-500 dark:text-green-400"
                        title="Rezolva rapid"
                      >
                        <CheckCircle2 className="h-3 w-3" />
                      </button>
                    )}
                  </div>
                  {ms.description && (
                    <p className="text-muted-foreground italic">{ms.description}</p>
                  )}
                </div>
              </div>

              {/* Inline resolve form */}
              {isResolving && (
                <div className="ml-3.5 mt-1 flex items-center gap-1.5 rounded border bg-muted/50 px-2 py-1">
                  <input
                    type="text"
                    placeholder="Motiv (ex: transmis pe email)"
                    value={resolveNote}
                    onChange={(e) => setResolveNote(e.target.value)}
                    className="flex-1 bg-transparent text-[10px] outline-none placeholder:text-muted-foreground/60"
                    autoFocus
                    onKeyDown={(e) => {
                      if (e.key === "Enter" && resolveNote.trim()) {
                        onResolveInline?.(ms.deadline.id, resolveNote.trim());
                        setResolvingId(null);
                        setResolveNote("");
                      }
                      if (e.key === "Escape") {
                        setResolvingId(null);
                        setResolveNote("");
                      }
                    }}
                  />
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-5 px-1.5 text-[9px] text-green-600"
                    disabled={!resolveNote.trim()}
                    onClick={() => {
                      onResolveInline?.(ms.deadline.id, resolveNote.trim());
                      setResolvingId(null);
                      setResolveNote("");
                    }}
                  >
                    OK
                  </Button>
                  <Button
                    size="sm"
                    variant="ghost"
                    className="h-5 px-1 text-[9px] text-muted-foreground"
                    onClick={() => {
                      setResolvingId(null);
                      setResolveNote("");
                    }}
                  >
                    ✕
                  </Button>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
