/**
 * Current duty view: full-screen card when opened via Mini App deep link (startapp=duty).
 * Fetches today's duties, finds the active one, shows name, shift, auto-updating remaining time,
 * and contact links. Integrates with Telegram BackButton.
 * Ported from webapp/js/currentDuty.js.
 */

"use client";

import { useEffect, useState, useCallback } from "react";
import { Calendar } from "lucide-react";
import { useTranslation } from "@/i18n/use-translation";
import { translate } from "@/i18n/messages";
import { useAppStore } from "@/store/app-store";
import { useTelegramAuth } from "@/hooks/use-telegram-auth";
import { fetchDuties, AccessDeniedError } from "@/lib/api";
import {
  localDateString,
  dateKeyToDDMM,
  formatHHMM,
} from "@/lib/date-utils";
import { getRemainingTime, findCurrentDuty } from "@/lib/current-duty";
import { triggerHapticLight } from "@/lib/telegram-haptic";
import { ContactLinks } from "@/components/contact/ContactLinks";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { AccessDeniedScreen } from "@/components/states/AccessDeniedScreen";
import type { DutyWithUser } from "@/types";
import { useTelegramBackButton, useTelegramCloseAction } from "@/hooks/telegram";
import { useScreenReady } from "@/hooks/use-screen-ready";
import { useRequestState } from "@/hooks/use-request-state";

export interface CurrentDutyViewProps {
  /** Called when user taps Back (in-app button or Telegram BackButton). */
  onBack: () => void;
  /** True when opened via pin button (startParam=duty). Shows Close instead of Back to calendar. */
  openedFromPin?: boolean;
}

/**
 * Full-screen current duty view with Telegram BackButton and auto-updating remaining time.
 */
export function CurrentDutyView({ onBack, openedFromPin = false }: CurrentDutyViewProps) {
  const { t } = useTranslation();
  const lang = useAppStore((s) => s.lang);
  const { initDataRaw } = useTelegramAuth();

  const [duty, setDuty] = useState<DutyWithUser | null>(null);
  const [remaining, setRemaining] = useState<{ hours: number; minutes: number } | null>(null);
  const {
    state: requestState,
    setLoading,
    setSuccess,
    setError,
    setAccessDenied,
    isLoading,
    isError,
    isAccessDenied,
  } = useRequestState("loading");

  const loadTodayDuties = useCallback(
    async (signal?: AbortSignal | null) => {
      const today = new Date();
      const from = localDateString(today);
      const to = from;
      const initData = initDataRaw ?? "";
      try {
        const duties = await fetchDuties(from, to, initData, lang, signal);
        if (signal?.aborted) return;
        const active = findCurrentDuty(duties);
        setDuty(active);
        setSuccess();
        if (active) {
          setRemaining(getRemainingTime(active.end_at));
        } else {
          setRemaining(null);
        }
      } catch (e) {
        if (signal?.aborted) return;
        if (e instanceof AccessDeniedError) {
          setAccessDenied(e.serverDetail ?? null);
          setDuty(null);
          setRemaining(null);
        } else {
          setError(translate(lang, "error_generic"));
          setDuty(null);
          setRemaining(null);
        }
      }
    },
    [initDataRaw, lang, setSuccess, setAccessDenied, setError]
  );

  // Fetch today's duties on mount; abort on unmount to avoid setState after unmount.
  useEffect(() => {
    const controller = new AbortController();
    loadTodayDuties(controller.signal);
    return () => controller.abort();
  }, [loadTodayDuties]);

  useScreenReady(!isLoading);

  // Auto-update remaining time every second when there is an active duty.
  useEffect(() => {
    if (!duty) return;
    const interval = setInterval(() => {
      setRemaining(getRemainingTime(duty.end_at));
    }, 1000);
    return () => clearInterval(interval);
  }, [duty]);

  useTelegramBackButton({
    enabled: true,
    onClick: onBack,
  });

  const handleBack = () => {
    triggerHapticLight();
    onBack();
  };

  const closeMiniAppOrFallback = useTelegramCloseAction(onBack);

  const handleClose = () => {
    triggerHapticLight();
    closeMiniAppOrFallback();
  };

  const primaryButtonLabel = openedFromPin ? t("current_duty.close") : t("current_duty.back");
  const primaryButtonAriaLabel = openedFromPin
    ? t("current_duty.close")
    : t("current_duty.back");
  const handlePrimaryAction = openedFromPin ? handleClose : handleBack;

  if (isLoading) {
    return (
      <div
        className="flex min-h-[50vh] flex-col items-center justify-center gap-4"
        role="status"
        aria-live="polite"
        aria-label={t("loading")}
      >
        <Card className="current-duty-card w-full max-w-[var(--max-width-app)] border-t-4 border-t-duty">
          <CardContent className="flex flex-col gap-4 pt-6">
            <div className="flex items-center gap-2">
              <Skeleton className="size-2 shrink-0 rounded-full" />
              <Skeleton className="h-5 w-24 rounded-full" />
            </div>
            <div className="flex flex-col gap-2">
              <Skeleton className="h-7 w-48" />
              <Skeleton className="h-4 w-full max-w-[200px]" />
              <Skeleton className="h-4 w-full max-w-[280px]" />
            </div>
            <Skeleton className="h-14 w-full rounded-lg" />
            <div className="flex flex-col gap-2 border-t border-border/50 pt-4">
              <Skeleton className="h-12 w-full rounded-md" />
              <Skeleton className="h-12 w-full rounded-md" />
            </div>
          </CardContent>
          <CardFooter>
            <Button
              onClick={handlePrimaryAction}
              aria-label={primaryButtonAriaLabel}
            >
              {primaryButtonLabel}
            </Button>
          </CardFooter>
        </Card>
      </div>
    );
  }

  if (isAccessDenied) {
    return (
      <AccessDeniedScreen
        serverDetail={requestState.accessDeniedDetail}
        primaryAction="back"
        onBack={handlePrimaryAction}
        openedFromPin={openedFromPin}
      />
    );
  }

  if (isError) {
    const handleRetry = () => {
      triggerHapticLight();
      setLoading();
      loadTodayDuties();
    };
    return (
      <div className="flex min-h-[50vh] flex-col items-center justify-center gap-4">
        <Card className="w-full max-w-[var(--max-width-app)]">
          <CardContent className="pt-6">
            <p className="text-error">{requestState.error}</p>
          </CardContent>
          <CardFooter className="flex flex-col gap-2 sm:flex-row sm:justify-end">
            <Button
              variant="default"
              onClick={handleRetry}
              aria-label={t("error.retry")}
            >
              {t("error.retry")}
            </Button>
            <Button
              variant="outline"
              onClick={handlePrimaryAction}
              aria-label={primaryButtonAriaLabel}
            >
              {primaryButtonLabel}
            </Button>
          </CardFooter>
        </Card>
      </div>
    );
  }

  if (!duty) {
    return (
      <div className="flex min-h-[50vh] flex-col items-center justify-center gap-4">
        <Card className="current-duty-card--no-duty w-full max-w-[var(--max-width-app)] border-t-4 border-t-muted">
          <CardHeader>
            <CardTitle>{t("current_duty.title")}</CardTitle>
          </CardHeader>
          <CardContent className="flex flex-col items-center gap-4">
            <span
              className="flex items-center justify-center text-muted-foreground"
              aria-hidden
            >
              <Calendar className="size-12" strokeWidth={1.5} />
            </span>
            <p className="text-center text-muted-foreground">
              {t("current_duty.no_duty")}
            </p>
          </CardContent>
          <CardFooter className="flex flex-col gap-2 sm:flex-row sm:justify-end">
            <Button onClick={handlePrimaryAction} aria-label={primaryButtonAriaLabel}>
              {primaryButtonLabel}
            </Button>
            <Button
              variant="outline"
              onClick={onBack}
              aria-label={t("current_duty.open_calendar")}
            >
              {t("current_duty.open_calendar")}
            </Button>
          </CardFooter>
        </Card>
      </div>
    );
  }

  const startLocal = localDateString(new Date(duty.start_at));
  const endLocal = localDateString(new Date(duty.end_at));
  const startDDMM = dateKeyToDDMM(startLocal);
  const endDDMM = dateKeyToDDMM(endLocal);
  const startTime = formatHHMM(duty.start_at);
  const endTime = formatHHMM(duty.end_at);
  const shiftStr = `${startDDMM} ${startTime} — ${endDDMM} ${endTime}`;
  const rem = remaining ?? getRemainingTime(duty.end_at);
  const remainingValueStr = t("current_duty.remaining_value", {
    hours: String(rem.hours),
    minutes: String(rem.minutes),
  });

  const displayTz =
    typeof window !== "undefined" &&
    (window as unknown as { __DT_TZ?: string }).__DT_TZ;
  const shiftLabel = displayTz
    ? t("current_duty.shift_tz", { tz: displayTz })
    : t("current_duty.shift_local");

  const hasContacts =
    Boolean(duty.phone && String(duty.phone).trim()) ||
    Boolean(duty.username && String(duty.username).trim());

  return (
    <div className="flex min-h-[50vh] flex-col items-center justify-center gap-4">
      <Card
        className="current-duty-card w-full max-w-[var(--max-width-app)] border-t-4 border-t-duty animate-in fade-in-0 slide-in-from-bottom-4 duration-300 motion-reduce:animate-none motion-reduce:duration-0"
        role="article"
        aria-labelledby="current-duty-title"
      >
        <CardHeader className="sr-only">
          <CardTitle id="current-duty-title">{t("current_duty.title")}</CardTitle>
        </CardHeader>
        <CardContent className="flex flex-col gap-4 pt-6">
          <span
            className="inline-flex w-fit items-center gap-2 rounded-full bg-duty/15 px-2.5 py-1 text-xs font-medium text-foreground"
            aria-hidden
          >
            <span className="size-2 shrink-0 rounded-full bg-duty animate-pulse motion-reduce:animate-none" />
            {t("duty.now_on_duty")}
          </span>
          <section className="flex flex-col gap-2" aria-label={t("current_duty.shift")}>
            <p
              className="text-xl font-bold text-foreground leading-tight"
              id="current-duty-name"
            >
              {duty.full_name}
            </p>
            <p className="text-sm text-muted-foreground break-words">
              {shiftLabel}
            </p>
            <p className="text-sm text-muted-foreground break-words">
              {shiftStr}
            </p>
          </section>
          <div
            className="rounded-lg bg-duty/10 px-3 py-2.5 flex flex-col gap-1"
            aria-label={t("current_duty.remaining_label")}
          >
            <span className="text-xs text-muted-foreground">
              {t("current_duty.remaining_label")}
            </span>
            <span className="text-xl font-semibold text-foreground tabular-nums" aria-hidden>
              {remainingValueStr}
            </span>
            <span className="text-xs text-muted-foreground">
              {t("current_duty.ends_at", { time: formatHHMM(duty.end_at) })}
            </span>
          </div>
          <section className="flex flex-col gap-2 border-t border-border/50 pt-4" aria-label={t("contact.label")}>
          {hasContacts ? (
            <ContactLinks
              phone={duty.phone}
              username={duty.username}
              layout="block"
              showLabels={true}
              contextLabel={duty.full_name ?? undefined}
              showCopyButtons={true}
            />
          ) : (
            <p className="text-sm text-muted-foreground">
              {t("current_duty.contact_info_not_set")}
            </p>
          )}
          </section>
        </CardContent>
        <CardFooter>
          <Button
            onClick={handlePrimaryAction}
            aria-label={primaryButtonAriaLabel}
          >
            {primaryButtonLabel}
          </Button>
        </CardFooter>
      </Card>
    </div>
  );
}
