import Link from "next/link";
import type {
  AlertSeverity,
  Completion,
  DeliveryMode,
  SmsState,
  StudentStatus,
} from "@/lib/attendance-report";

export function fa(n: number): string {
  return n.toLocaleString("fa-IR");
}

export function faPct(n: number): string {
  return `${fa(n)}٪`;
}

export const STATUS_META: Record<
  StudentStatus,
  { label: string; className: string; dot: string; color: string }
> = {
  present: {
    label: "حاضر",
    className: "bg-emerald-50 text-emerald-800 ring-emerald-200",
    dot: "bg-emerald-500",
    color: "#10b981",
  },
  late: {
    label: "تأخیر",
    className: "bg-amber-50 text-amber-800 ring-amber-200",
    dot: "bg-amber-400",
    color: "#f59e0b",
  },
  absent: {
    label: "غایب",
    className: "bg-rose-50 text-rose-800 ring-rose-200",
    dot: "bg-rose-500",
    color: "#f43f5e",
  },
  temporary_exit: {
    label: "خروج موقت",
    className: "bg-violet-50 text-violet-800 ring-violet-200",
    dot: "bg-violet-400",
    color: "#8b5cf6",
  },
  unchecked: {
    label: "ثبت‌نشده",
    className: "bg-slate-100 text-slate-700 ring-slate-200",
    dot: "bg-slate-400",
    color: "#64748b",
  },
};

export const COMPLETION_META: Record<Completion, { label: string; className: string }> = {
  complete: { label: "تکمیل", className: "bg-emerald-50 text-emerald-800 ring-emerald-200" },
  partial: { label: "ناقص", className: "bg-amber-50 text-amber-800 ring-amber-200" },
  empty: { label: "پرنشده", className: "bg-rose-50 text-rose-800 ring-rose-200" },
};

export const SMS_META: Record<SmsState, { label: string; className: string }> = {
  delivered: { label: "تحویل‌شده", className: "bg-emerald-50 text-emerald-800" },
  queued: { label: "در صف ارسال", className: "bg-amber-50 text-amber-800" },
  failed: { label: "ناموفق", className: "bg-rose-50 text-rose-800" },
  none: { label: "بدون پیامک", className: "bg-slate-100 text-slate-600" },
};

/**
 * حضوری در برابر مجازی. رنگ روی «مجازی بودن» سوار است تا در یک نگاه از
 * حضوری جدا شود و حالت‌های آفلاین و ترکیبی هم برچسب خودشان را نگه دارند.
 */
export const DELIVERY_META: Record<
  DeliveryMode,
  { label: string; short: string; className: string; color: string; icon: string }
> = {
  in_person: {
    label: "حضوری",
    short: "حضوری",
    className: "bg-teal-50 text-teal-800 ring-teal-200",
    color: "#0d9488",
    icon: "🏫",
  },
  online: {
    label: "مجازی",
    short: "مجازی",
    className: "bg-indigo-50 text-indigo-800 ring-indigo-200",
    color: "#6366f1",
    icon: "💻",
  },
  offline: {
    label: "مجازی · آفلاین",
    short: "آفلاین",
    className: "bg-sky-50 text-sky-800 ring-sky-200",
    color: "#0ea5e9",
    icon: "🎞",
  },
  hybrid: {
    label: "ترکیبی",
    short: "ترکیبی",
    className: "bg-fuchsia-50 text-fuchsia-800 ring-fuchsia-200",
    color: "#c026d3",
    icon: "🔀",
  },
};

export function deliveryMeta(mode: DeliveryMode | null | undefined) {
  return DELIVERY_META[mode ?? "in_person"] ?? DELIVERY_META.in_person;
}

export function StatusChip({ status, label }: { status: StudentStatus; label?: string }) {
  const meta = STATUS_META[status] ?? STATUS_META.unchecked;
  return (
    <span
      className={`inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[11px] font-bold ring-1 ${meta.className}`}
    >
      <span className={`h-1.5 w-1.5 rounded-full ${meta.dot}`} />
      {label ?? meta.label}
    </span>
  );
}

export function CompletionChip({
  completion,
  label,
}: {
  completion: Completion;
  label?: string;
}) {
  const meta = COMPLETION_META[completion] ?? COMPLETION_META.empty;
  return (
    <span className={`rounded-full px-2.5 py-1 text-[11px] font-bold ring-1 ${meta.className}`}>
      {label ?? meta.label}
    </span>
  );
}

export function SmsChip({ state, label }: { state: SmsState; label?: string }) {
  const meta = SMS_META[state] ?? SMS_META.none;
  return (
    <span className={`rounded-full px-2 py-1 text-[11px] font-bold ${meta.className}`}>
      {label ?? meta.label}
    </span>
  );
}

/** برچسب حضوری/مجازی برای هر ردیف گزارش. */
export function DeliveryChip({
  mode,
  label,
  compact = false,
}: {
  mode: DeliveryMode | null | undefined;
  label?: string;
  compact?: boolean;
}) {
  const meta = deliveryMeta(mode);
  return (
    <span
      className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-bold ring-1 ${meta.className}`}
      title={label ?? meta.label}
    >
      <span aria-hidden>{meta.icon}</span>
      {compact ? meta.short : (label ?? meta.label)}
    </span>
  );
}

export function GlassCard({
  children,
  className = "",
}: {
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <section
      className={`rounded-[1.6rem] border border-white/70 bg-white/80 p-4 shadow-card backdrop-blur-md lg:p-5 ${className}`}
    >
      {children}
    </section>
  );
}

export function CardTitle({
  kicker,
  title,
  action,
}: {
  kicker?: string;
  title: string;
  action?: React.ReactNode;
}) {
  return (
    <div className="mb-4 flex items-start justify-between gap-3">
      <div>
        {kicker ? (
          <p className="text-[11px] font-bold tracking-wide text-teal-700">{kicker}</p>
        ) : null}
        <h2 className="text-sm font-bold text-slate-900 lg:text-base">{title}</h2>
      </div>
      {action}
    </div>
  );
}

export function RingGauge({
  percent,
  label,
  value,
  color,
  active,
  href,
  onClick,
}: {
  percent: number;
  label: string;
  value: string;
  color: string;
  active?: boolean;
  href?: string;
  onClick?: () => void;
}) {
  const size = 112;
  const stroke = 10;
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const clamped = Math.max(0, Math.min(100, percent));
  const dash = (clamped / 100) * c;

  const shell = `flex flex-col items-center rounded-3xl p-3 text-center transition ${
    active ? "bg-white ring-2 ring-teal-300 shadow-sm" : "hover:bg-white/70"
  }`;

  const body = (
    <>
      <div className="relative" style={{ width: size, height: size }}>
        <svg width={size} height={size} className="-rotate-90">
          <circle
            cx={size / 2}
            cy={size / 2}
            r={r}
            fill="none"
            stroke="#e2e8f0"
            strokeWidth={stroke}
          />
          <circle
            cx={size / 2}
            cy={size / 2}
            r={r}
            fill="none"
            stroke={color}
            strokeWidth={stroke}
            strokeLinecap="round"
            strokeDasharray={`${dash} ${c - dash}`}
          />
        </svg>
        <p className="absolute inset-0 flex items-center justify-center text-lg font-black tabular-nums text-slate-900">
          {faPct(clamped)}
        </p>
      </div>
      <p className="mt-1 text-xs font-bold text-slate-700">{label}</p>
      <p className="text-[11px] tabular-nums text-slate-500">{value}</p>
    </>
  );

  if (href) {
    return (
      <Link href={href} className={shell}>
        {body}
      </Link>
    );
  }

  return (
    <button type="button" onClick={onClick} className={shell}>
      {body}
    </button>
  );
}

export function severityTone(severity: AlertSeverity): string {
  if (severity === "critical") return "bg-rose-50 text-rose-800 ring-rose-200";
  if (severity === "warning") return "bg-orange-50 text-orange-800 ring-orange-200";
  return "bg-sky-50 text-sky-800 ring-sky-200";
}

export function severitySurface(severity: AlertSeverity): string {
  if (severity === "critical") return "bg-rose-50";
  if (severity === "warning") return "bg-amber-50";
  return "bg-sky-50";
}

export function LegendDot({ color, label }: { color: string; label: string }) {
  return (
    <span className="inline-flex items-center gap-1.5">
      <span className="h-2 w-2 rounded-full" style={{ background: color }} />
      {label}
    </span>
  );
}

export function MiniStat({
  label,
  value,
  hint,
  tone,
  href,
  onClick,
  active,
}: {
  label: string;
  value: string;
  hint?: string;
  tone: "emerald" | "amber" | "rose" | "slate" | "teal" | "indigo";
  href?: string;
  onClick?: () => void;
  active?: boolean;
}) {
  const map: Record<string, string> = {
    emerald: "bg-emerald-50 text-emerald-800",
    amber: "bg-amber-50 text-amber-800",
    rose: "bg-rose-50 text-rose-800",
    slate: "bg-slate-100 text-slate-700",
    teal: "bg-teal-50 text-teal-800",
    indigo: "bg-indigo-50 text-indigo-800",
  };
  const shell = `block rounded-2xl px-3 py-3 text-right transition hover:brightness-95 ${map[tone]} ${
    active ? "ring-2 ring-teal-300" : ""
  }`;
  const body = (
    <>
      <p className="text-[11px] font-bold opacity-80">{label}</p>
      <p className="text-xl font-black tabular-nums">{value}</p>
      {hint ? <p className="mt-0.5 text-[10px] opacity-70">{hint}</p> : null}
    </>
  );

  if (href) {
    return (
      <Link href={href} className={shell}>
        {body}
      </Link>
    );
  }

  return (
    <button type="button" onClick={onClick} className={shell}>
      {body}
    </button>
  );
}

/** نوار رتبه‌بندی برای فهرست‌های «بیشترین …». */
export function RankBar({
  index,
  title,
  meta,
  percent,
  barClassName,
  href,
  onClick,
}: {
  index: number;
  title: string;
  meta: string;
  percent: number;
  barClassName: string;
  href?: string;
  onClick?: () => void;
}) {
  const body = (
    <>
      <span className="w-5 text-xs font-black text-slate-400">{fa(index + 1)}</span>
      <div className="min-w-0 flex-1">
        <div className="mb-1 flex justify-between gap-2 text-xs">
          <span className="truncate font-bold text-slate-700">{title}</span>
          <span className="shrink-0 tabular-nums text-slate-500">{meta}</span>
        </div>
        <div className="h-2 overflow-hidden rounded-full bg-slate-100">
          <div
            className={`h-full rounded-full ${barClassName}`}
            style={{ width: `${Math.max(2, Math.min(100, percent))}%` }}
          />
        </div>
      </div>
    </>
  );

  if (href) {
    return (
      <Link href={href} className="flex w-full items-center gap-3 text-right">
        {body}
      </Link>
    );
  }

  return (
    <button type="button" onClick={onClick} className="flex w-full items-center gap-3 text-right">
      {body}
    </button>
  );
}

export function EmptyState({ children }: { children: React.ReactNode }) {
  return (
    <p className="rounded-2xl bg-slate-50 p-4 text-center text-sm text-slate-400">{children}</p>
  );
}

export function LoadingRows({ rows = 4 }: { rows?: number }) {
  return (
    <div className="space-y-2" aria-busy="true">
      {Array.from({ length: rows }).map((_, i) => (
        <div key={i} className="h-10 animate-pulse rounded-xl bg-slate-100" />
      ))}
    </div>
  );
}

export function GroupedBarChart({
  labels,
  series,
}: {
  labels: string[];
  series: Array<{ key: string; color: string; values: number[] }>;
}) {
  const w = 420;
  const h = 180;
  const pad = { t: 12, r: 8, b: 28, l: 28 };
  const max = Math.max(...series.flatMap((s) => s.values), 1);
  const groupW = (w - pad.l - pad.r) / Math.max(labels.length, 1);
  // با یک شعبه، گروه باید هم‌اندازه حالت چندشعبه بماند و وسط نمودار بنشیند.
  const barW = Math.min(34, Math.max(6, (groupW - 16) / Math.max(series.length, 1)));

  return (
    <svg viewBox={`0 0 ${w} ${h}`} className="h-44 w-full" style={{ direction: "ltr" }} role="img">
      {[0, 25, 50, 75, 100].map((tick) => {
        const y = pad.t + ((100 - tick) / 100) * (h - pad.t - pad.b);
        return (
          <g key={tick}>
            <line x1={pad.l} x2={w - pad.r} y1={y} y2={y} stroke="#e2e8f0" strokeWidth="1" />
            <text x={pad.l - 6} y={y + 3} textAnchor="end" fontSize="9" fill="#94a3b8">
              {tick}
            </text>
          </g>
        );
      })}
      {labels.map((label, i) => {
        const gx = pad.l + i * groupW + (groupW - series.length * barW) / 2;
        return (
          <g key={`${label}-${i}`}>
            {series.map((s, si) => {
              const val = s.values[i] ?? 0;
              const bh = (val / max) * (h - pad.t - pad.b);
              const x = gx + si * barW;
              const y = h - pad.b - bh;
              return (
                <rect key={s.key} x={x} y={y} width={barW - 2} height={bh} rx={3} fill={s.color} />
              );
            })}
            <text
              x={gx + (series.length * barW) / 2}
              y={h - 8}
              textAnchor="middle"
              fontSize="10"
              fill="#64748b"
            >
              {label}
            </text>
          </g>
        );
      })}
    </svg>
  );
}

export function MultiLineChart({
  labels,
  series,
}: {
  labels: string[];
  series: Array<{ key: string; color: string; values: Array<number | null> }>;
}) {
  const w = 420;
  const h = 180;
  const pad = { t: 16, r: 10, b: 28, l: 28 };
  const values = series.flatMap((s) => s.values.filter((v): v is number => v !== null));
  const rawMin = values.length ? Math.min(...values) : 0;
  const rawMax = values.length ? Math.max(...values) : 100;
  // دامنه پویا: با داده‌های نزدیک به هم، نمودار صاف نمی‌شود.
  const min = Math.max(0, Math.floor((rawMin - 5) / 10) * 10);
  const max = Math.min(100, Math.max(min + 10, Math.ceil((rawMax + 5) / 10) * 10));
  const innerW = w - pad.l - pad.r;
  const innerH = h - pad.t - pad.b;
  const xAt = (i: number) => pad.l + (i / Math.max(labels.length - 1, 1)) * innerW;
  const yAt = (v: number) => pad.t + ((max - v) / (max - min)) * innerH;
  const ticks = [min, Math.round((min + max) / 2), max];
  const step = Math.max(1, Math.ceil(labels.length / 8));

  return (
    <svg viewBox={`0 0 ${w} ${h}`} className="h-44 w-full" style={{ direction: "ltr" }} role="img">
      {ticks.map((tick) => {
        const y = yAt(tick);
        return (
          <g key={tick}>
            <line x1={pad.l} x2={w - pad.r} y1={y} y2={y} stroke="#e2e8f0" />
            <text x={pad.l - 6} y={y + 3} textAnchor="end" fontSize="9" fill="#94a3b8">
              {tick}
            </text>
          </g>
        );
      })}
      {series.map((s) => {
        let started = false;
        const pts = s.values
          .map((v, i) => {
            if (v === null) return "";
            const cmd = started ? "L" : "M";
            started = true;
            return `${cmd} ${xAt(i)} ${yAt(v)}`;
          })
          .filter(Boolean)
          .join(" ");
        return (
          <g key={s.key}>
            <path d={pts} fill="none" stroke={s.color} strokeWidth="2.4" strokeLinejoin="round" />
            {s.values.map((v, i) =>
              v === null ? null : <circle key={i} cx={xAt(i)} cy={yAt(v)} r="3" fill={s.color} />,
            )}
          </g>
        );
      })}
      {labels.map((label, i) =>
        i % step === 0 ? (
          <text
            key={`${label}-${i}`}
            x={xAt(i)}
            y={h - 8}
            textAnchor="middle"
            fontSize="10"
            fill="#64748b"
          >
            {label}
          </text>
        ) : null,
      )}
    </svg>
  );
}
