import Link from "next/link";
import { redirect } from "next/navigation";
import {
  ArrowLeftIcon,
  PencilIcon,
  CalendarIcon,
  UsersIcon,
  FileTextIcon,
  SmartphoneIcon,
  RepeatIcon,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { getSeededOperator } from "@/lib/operator";
import { getAccount, listGroupsForAccount } from "@/lib/queries";
import { ReviewSubmitClient } from "./review-submit-client";
import { DateTime } from "luxon";
import { describeRecurrence, kindFromRrule } from "@/lib/recurrence";

interface StepReviewParams {
  step?: string;
  accountId?: string;
  groupIds?: string;
  text?: string;
  mediaId?: string;
  caption?: string;
  scheduledAt?: string;
  rrule?: string;
}

interface StepReviewProps {
  params: StepReviewParams;
}

const WEEKDAY_TO_ISO: Record<string, number> = {
  MO: 1, TU: 2, WE: 3, TH: 4, FR: 5, SA: 6, SU: 7,
};
function parseWeeklyDaysFromRrule(rrule: string | undefined): number[] {
  if (!rrule) return [];
  const m = rrule.match(/BYDAY=([A-Z,]+)/i);
  if (!m) return [];
  return m[1]!
    .split(",")
    .map((d) => WEEKDAY_TO_ISO[d.toUpperCase()])
    .filter((d): d is number => d !== undefined);
}

function formatScheduledAt(iso: string, timezone: string): string {
  try {
    const dt = DateTime.fromISO(iso, { zone: timezone });
    if (!dt.isValid) return iso;
    return dt.toLocaleString(DateTime.DATETIME_FULL);
  } catch {
    return iso;
  }
}

function editLink(
  step: number,
  accountId: string,
  groupIds?: string,
  text?: string,
  mediaId?: string,
  caption?: string,
  scheduledAt?: string,
  rrule?: string,
): string {
  const sp = new URLSearchParams({ step: String(step), accountId });
  if (groupIds) sp.set("groupIds", groupIds);
  if (text) sp.set("text", text);
  if (mediaId) sp.set("mediaId", mediaId);
  if (caption) sp.set("caption", caption);
  if (scheduledAt) sp.set("scheduledAt", scheduledAt);
  if (rrule) sp.set("rrule", rrule);
  return `/reminders/new?${sp.toString()}`;
}

export async function StepReview({ params }: StepReviewProps) {
  const { accountId, groupIds, text, mediaId, caption, scheduledAt, rrule } = params;

  if (!accountId || !scheduledAt || (!text && !mediaId)) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    redirect("/reminders/new" as any);
  }

  const op = await getSeededOperator();
  const timezone = op.defaultTimezone ?? "UTC";

  // Fetch account details
  const account = await getAccount(op.id, accountId);
  if (!account) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    redirect("/reminders/new" as any);
  }

  // Fetch group names
  const groupIdsArray = groupIds ? groupIds.split(",").filter(Boolean) : [];
  const groupsResult =
    groupIdsArray.length > 0 ? await listGroupsForAccount(op.id, accountId) : null;
  const selectedGroups = groupsResult
    ? groupsResult.groups.filter((g) => groupIdsArray.includes(g.id))
    : [];

  const formattedDate = formatScheduledAt(scheduledAt, timezone);

  // Back goes to step 4 (Groups, the previous step in the new order)
  const backHref = editLink(4, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule);

  return (
    <div className="space-y-5">
      <div>
        <Button asChild variant="ghost" size="sm" className="-ml-2">
          {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
          <Link href={backHref as any}>
            <ArrowLeftIcon />
            Back
          </Link>
        </Button>
      </div>

      <p className="text-sm text-muted-foreground">
        Review your reminder before scheduling.
      </p>

      <div className="space-y-3">
        {/* Account */}
        <ReviewRow
          icon={<SmartphoneIcon className="size-4" />}
          label="Account"
          editHref={editLink(1, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule)}
        >
          <span className="text-sm font-medium">{account.label}</span>
          {account.phoneNumber && (
            <span className="text-xs text-muted-foreground ml-1.5">{account.phoneNumber}</span>
          )}
        </ReviewRow>

        {/* Message */}
        <ReviewRow
          icon={<FileTextIcon className="size-4" />}
          label="Message"
          editHref={editLink(2, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule)}
        >
          {mediaId ? (
            <span className="text-sm text-muted-foreground">
              Media file
              {caption && (
                <> with caption: <span className="text-foreground">{caption}</span></>
              )}
              {text && (
                <> · <span className="text-foreground">{text}</span></>
              )}
            </span>
          ) : text ? (
            <p className="text-sm whitespace-pre-wrap break-words">{text}</p>
          ) : (
            <span className="text-sm text-muted-foreground italic">No message</span>
          )}
        </ReviewRow>

        {/* When */}
        <ReviewRow
          icon={<CalendarIcon className="size-4" />}
          label={rrule ? "First fire" : "When"}
          editHref={editLink(3, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule)}
        >
          <span className="text-sm font-medium">{formattedDate}</span>
        </ReviewRow>

        {/* Recurrence (only if set) */}
        {rrule && (
          <ReviewRow
            icon={<RepeatIcon className="size-4" />}
            label="Repeats"
            editHref={editLink(3, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule)}
          >
            <span className="text-sm font-medium">
              {describeRecurrence(
                kindFromRrule(rrule),
                DateTime.fromISO(scheduledAt!, { zone: timezone }),
                parseWeeklyDaysFromRrule(rrule),
              )}
            </span>
          </ReviewRow>
        )}

        {/* Groups */}
        <ReviewRow
          icon={<UsersIcon className="size-4" />}
          label="Groups"
          editHref={editLink(4, accountId, groupIds, text, mediaId, caption, scheduledAt, rrule)}
        >
          {selectedGroups.length > 0 ? (
            <div className="flex flex-wrap gap-1.5">
              {selectedGroups.map((g) => (
                <span
                  key={g.id}
                  className="inline-flex items-center rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground"
                >
                  {g.name}
                </span>
              ))}
            </div>
          ) : (
            <span className="text-sm text-muted-foreground italic">
              No groups — reminder will be saved without targets
            </span>
          )}
        </ReviewRow>
      </div>

      <ReviewSubmitClient
        accountId={accountId}
        groupIds={groupIds}
        text={text}
        mediaId={mediaId}
        caption={caption}
        scheduledAt={scheduledAt}
        rrule={rrule}
        timezone={timezone}
      />
    </div>
  );
}

function ReviewRow({
  icon,
  label,
  editHref,
  children,
}: {
  icon: React.ReactNode;
  label: string;
  editHref: string;
  children: React.ReactNode;
}) {
  return (
    <Card>
      <CardContent className="py-3 px-4">
        <div className="flex items-start gap-3">
          <div className="flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground mt-0.5">
            {icon}
          </div>
          <div className="flex-1 min-w-0">
            <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-1">
              {label}
            </p>
            <div>{children}</div>
          </div>
          <Link
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            href={editHref as any}
            className="shrink-0 flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors rounded px-1.5 py-1 hover:bg-muted"
            aria-label={`Edit ${label}`}
          >
            <PencilIcon className="size-3" />
            Edit
          </Link>
        </div>
      </CardContent>
    </Card>
  );
}
