"use client";

import { useId, useMemo, useState } from "react";
import type { StageSectionConfig, SelectOption } from "@/types/form";
import type { UseFormRegister, FieldValues, FieldErrors } from "react-hook-form";
import { FieldRenderer } from "./fields/FieldRenderer";
import { MatrixGroup } from "./MatrixGroup";
import { StageIcon } from "./StageIcon";
import { evaluate } from "@/lib/conditional";

interface StageSectionProps {
  section: StageSectionConfig;
  register: UseFormRegister<FieldValues>;
  errors: FieldErrors;
  /** Live form values, used to evaluate per-field visibility rules. */
  formValues: Record<string, unknown>;
  /** Whether this is the section that matches the current org stage. */
  isCurrent: boolean;
  /** Whether the section starts open. */
  defaultOpen: boolean;
  /** Option groups fetched from CiviCRM, keyed by option_group_id. */
  options: Record<number, SelectOption[]>;
  /** Optional last-checked-in timestamp for this stage (ISO date). */
  lastTouched?: string;
}

/**
 * One accordion card per stage section. Header carries:
 *   - A hand-drawn stage icon (left)
 *   - The stage label (display serif)
 *   - A "Current stage" pill in terracotta if applicable
 *   - A field-count summary on the right
 *   - A chevron that rotates on open
 *
 * The card border thickens and tints leaf-green when current; otherwise it
 * sits quietly on the cream paper.
 */
export function StageSection({
  section,
  register,
  errors,
  formValues,
  isCurrent,
  defaultOpen,
  options,
  lastTouched,
}: StageSectionProps) {
  const [open, setOpen] = useState(defaultOpen);
  const headingId = useId();
  const panelId = useId();

  const matrixFieldNames = useMemo(() => {
    const names = new Set<string>();
    for (const m of section.matrixGroups ?? []) {
      for (const row of m.rows) for (const f of row.fields) names.add(f);
    }
    return names;
  }, [section.matrixGroups]);

  const visibleFields = section.fields.filter(
    (f) => evaluate(f.visibleWhen, formValues) && !matrixFieldNames.has(f.name),
  );

  const fieldCount =
    visibleFields.length +
    (section.matrixGroups ?? []).reduce(
      (n, g) => n + g.rows.reduce((m, r) => m + r.fields.length, 0),
      0,
    );

  return (
    <section
      aria-labelledby={headingId}
      className={
        "overflow-hidden rounded-lg bg-white/95 transition " +
        (isCurrent
          ? "border-2 border-leaf-600 shadow-[0_1px_0_0_rgba(0,0,0,0.04),0_8px_24px_-12px_rgba(60,80,40,0.18)]"
          : "border border-rule shadow-sm")
      }
    >
      <h2 id={headingId} className="m-0">
        <button
          type="button"
          onClick={() => setOpen((v) => !v)}
          aria-expanded={open}
          aria-controls={panelId}
          className={
            "group relative flex w-full items-center gap-4 px-5 py-4 text-left transition-colors sm:px-6 " +
            (isCurrent ? "bg-leaf-50/60" : "hover:bg-paper-2/60")
          }
        >
          <StageRankMark rank={section.rank} isCurrent={isCurrent} />
          <span className="flex-1 min-w-0">
            <span className="block font-display text-lg font-medium text-ink leading-tight tracking-tight sm:text-xl">
              {section.label}
            </span>
            <span className="mt-1 flex items-center gap-3 text-xs text-ink-mute">
              {isCurrent && (
                <span className="inline-flex items-center gap-1.5 rounded-full border border-clay-200 bg-clay-100/70 px-2 py-0.5 font-medium text-clay-700 uppercase tracking-[0.08em]">
                  <span className="h-1.5 w-1.5 rounded-full bg-clay-600" aria-hidden />
                  Current stage
                </span>
              )}
              <span className="tabular-nums">
                {fieldCount} {fieldCount === 1 ? "field" : "fields"}
              </span>
              {lastTouched && (
                <>
                  <span aria-hidden>·</span>
                  <span>Last touched {formatRelative(lastTouched)}</span>
                </>
              )}
            </span>
          </span>
          <Chevron open={open} />
        </button>
      </h2>

      <div
        id={panelId}
        role="region"
        aria-labelledby={headingId}
        hidden={!open}
        className="border-t border-rule-soft"
      >
        <div className="px-5 py-6 sm:px-7 sm:py-7">
          {section.intro && (
            <p className="mb-6 max-w-prose text-[15px] leading-relaxed text-ink-soft">
              {section.intro}
            </p>
          )}
          {(section.matrixGroups ?? []).length > 0 && (
            <div className="mb-7 space-y-5">
              {section.matrixGroups!.map((g) => (
                <MatrixGroup key={g.id} group={g} register={register} />
              ))}
            </div>
          )}
          {visibleFields.length === 0 && (section.matrixGroups ?? []).length === 0 ? (
            <p className="text-sm italic text-ink-mute">No fields are visible at this stage.</p>
          ) : visibleFields.length === 0 ? null : (
            <div className="grid grid-cols-1 gap-x-7 gap-y-5 md:grid-cols-2">
              {visibleFields.map((f) => {
                const resolvedOptions = f.optionGroupId ? options[f.optionGroupId] : undefined;
                const wide =
                  f.type === "textarea" ||
                  f.type === "boolean" ||
                  f.type === "multiselect";
                return (
                  <div key={f.name} className={wide ? "md:col-span-2" : ""}>
                    <FieldRenderer
                      field={f}
                      register={register}
                      errors={errors}
                      readonlyValue={formValues[f.name]}
                      resolvedOptions={resolvedOptions}
                    />
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

/**
 * Stage rank mark: the number sits in a small circle, with the hand-drawn
 * icon offset behind it. When current, the ring is leaf-green and the
 * number is white-on-green; otherwise it's quiet.
 */
function StageRankMark({ rank, isCurrent }: { rank: number; isCurrent: boolean }) {
  return (
    <span aria-hidden className="relative inline-flex h-12 w-12 flex-shrink-0 items-center justify-center">
      <StageIcon
        rank={rank}
        className={
          "absolute inset-0 h-12 w-12 transition-opacity " +
          (isCurrent ? "text-leaf-700 opacity-100" : "text-leaf-600 opacity-50")
        }
      />
      <span
        className={
          "relative z-10 inline-flex h-5 w-5 items-center justify-center rounded-full text-[10px] font-semibold tabular-nums shadow-sm " +
          (isCurrent ? "bg-leaf-700 text-paper" : "bg-paper text-ink-soft border border-rule")
        }
        style={{ marginLeft: 28, marginTop: 28 }}
      >
        {rank}
      </span>
    </span>
  );
}

function Chevron({ open }: { open: boolean }) {
  return (
    <svg
      aria-hidden
      viewBox="0 0 20 20"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      strokeLinecap="round"
      className={"h-5 w-5 flex-shrink-0 text-ink-mute transition-transform duration-300 " + (open ? "rotate-180" : "")}
    >
      <path d="M5 8 L10 13 L15 8" />
    </svg>
  );
}

function formatRelative(iso: string): string {
  const then = new Date(iso).getTime();
  if (Number.isNaN(then)) return iso;
  const days = Math.round((Date.now() - then) / (1000 * 60 * 60 * 24));
  if (days <= 0) return "today";
  if (days === 1) return "yesterday";
  if (days < 30) return `${days} days ago`;
  if (days < 365) return `${Math.round(days / 30)} months ago`;
  return `${Math.round(days / 365)} years ago`;
}
