"use client";

import * as React from "react";
import { Button } from "./button.tsx";
import { Popover, PopoverContent, PopoverTrigger } from "./popover.tsx";
import { ScrollArea } from "./scroll-area.tsx";
import { cn } from "../lib/utils.ts";
import { Clock, ChevronDown } from "@untitledui/icons";
import { DateTimeInput } from "./datetime-input.tsx";
import {
  QUICK_RANGES,
  expressionToDate,
  getTimeRangeDisplayText,
  type QuickRange,
} from "../lib/time-expressions.ts";

export interface TimeRange {
  from: string;
  to: string;
}

export interface TimeRangePickerProps {
  value: TimeRange;
  onChange: (value: TimeRange) => void;
  className?: string;
  disabled?: boolean;
  /** Quick ranges to display. Defaults to QUICK_RANGES */
  quickRanges?: QuickRange[];
  /** Optional translations for the UI labels */
  labels?: {
    absoluteTimeRange?: string;
    from?: string;
    to?: string;
    applyTimeRange?: string;
  };
}

export function TimeRangePicker({
  value,
  onChange,
  className,
  disabled,
  quickRanges = QUICK_RANGES,
  labels,
}: TimeRangePickerProps) {
  const absoluteTimeRangeLabel =
    labels?.absoluteTimeRange ?? "Absolute time range";
  const fromLabel = labels?.from ?? "From";
  const toLabel = labels?.to ?? "To";
  const applyTimeRangeLabel = labels?.applyTimeRange ?? "Apply time range";
  const [open, setOpen] = React.useState(false);
  const [localFrom, setLocalFrom] = React.useState(value.from);
  const [localTo, setLocalTo] = React.useState(value.to);
  const [validationError, setValidationError] = React.useState<string | null>(
    null,
  );
  // Sync local state when prop changes (action during render)
  const prevValueRef = React.useRef({ from: value.from, to: value.to });
  if (
    // oxlint-disable-next-line ban-ref-current-assignment/ban-ref-current-assignment -- TODO: refactor render-time .current access
    prevValueRef.current.from !== value.from ||
    // oxlint-disable-next-line ban-ref-current-assignment/ban-ref-current-assignment -- TODO: refactor render-time .current access
    prevValueRef.current.to !== value.to
  ) {
    // oxlint-disable-next-line ban-ref-current-assignment/ban-ref-current-assignment -- TODO: refactor render-time .current access
    prevValueRef.current = { from: value.from, to: value.to };
    setLocalFrom(value.from);
    setLocalTo(value.to);
  }

  const handleQuickRangeSelect = (range: QuickRange) => {
    prevValueRef.current = { from: range.from, to: range.to };
    setLocalFrom(range.from);
    setLocalTo(range.to);
    setOpen(false);
    onChange({ from: range.from, to: range.to });
  };

  const handleApply = () => {
    // Validate that from is before to
    const fromResult = expressionToDate(localFrom);
    const toResult = expressionToDate(localTo);

    if (!fromResult.valid || !fromResult.date) {
      setValidationError("Invalid 'From' date");
      return;
    }

    if (!toResult.valid || !toResult.date) {
      setValidationError("Invalid 'To' date");
      return;
    }

    if (fromResult.date >= toResult.date) {
      setValidationError("'From' must be before 'To'");
      return;
    }

    setValidationError(null);
    onChange({ from: localFrom, to: localTo });
    setOpen(false);
  };

  // Check if current value matches a quick range
  const isQuickRangeSelected = (range: QuickRange) => {
    return value.from === range.from && value.to === range.to;
  };

  const displayText = getTimeRangeDisplayText(value.from, value.to);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          className={cn("gap-1.5 min-w-[160px] justify-between", className)}
          disabled={disabled}
        >
          <div className="flex items-center gap-1.5">
            <Clock className="size-4 text-muted-foreground" />
            <span className="text-sm">{displayText}</span>
          </div>
          <ChevronDown className="size-4 text-muted-foreground" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="w-[540px] p-0"
        align="end"
        sideOffset={4}
        onCloseAutoFocus={(e) => e.preventDefault()}
        // Instant exit animation prevents the popover from "blinking" when a
        // re-render (triggered by route navigation) restarts the CSS exit
        // animation while the portal is still in the DOM.
        style={!open ? { animationDuration: "0s" } : undefined}
      >
        <div className="flex">
          {/* Left: Absolute time range */}
          <div className="flex-1 p-4 border-r">
            <h4 className="text-sm font-medium mb-4">
              {absoluteTimeRangeLabel}
            </h4>

            <div className="space-y-4">
              <div>
                <label className="text-xs text-muted-foreground mb-1.5 block">
                  {fromLabel}
                </label>
                <DateTimeInput
                  value={localFrom}
                  onChange={setLocalFrom}
                  placeholder="now-24h"
                />
              </div>

              <div>
                <label className="text-xs text-muted-foreground mb-1.5 block">
                  {toLabel}
                </label>
                <DateTimeInput
                  value={localTo}
                  onChange={setLocalTo}
                  placeholder="now"
                />
              </div>

              {validationError && (
                <p className="text-xs text-destructive">{validationError}</p>
              )}

              <Button onClick={handleApply} className="w-full" size="sm">
                {applyTimeRangeLabel}
              </Button>
            </div>
          </div>

          {/* Right: Quick ranges */}
          <div className="w-[200px]">
            <ScrollArea className="h-[280px]">
              <div className="p-2">
                {quickRanges.map((range) => {
                  const isSelected = isQuickRangeSelected(range);
                  return (
                    <button
                      key={range.value}
                      type="button"
                      onClick={() => handleQuickRangeSelect(range)}
                      className={cn(
                        "w-full text-left px-3 py-2 text-sm rounded-md transition-colors",
                        "hover:bg-accent hover:text-accent-foreground",
                        isSelected &&
                          "bg-accent text-accent-foreground font-medium",
                      )}
                    >
                      {range.label}
                    </button>
                  );
                })}
              </div>
            </ScrollArea>
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}
