import { useMemo, useState } from "react";
import { Input, Picker, ScrollView, Text, View } from "@tarojs/components";
import Taro, { useDidShow } from "@tarojs/taro";
import AdminGuard from "../../components/AdminGuard";
import { useActionDrawer } from "../../components/action-drawer";
import {
  getActivityRegistrations,
  getAdminActivities,
  manualActivityCheckin,
  searchActivityParticipants,
  type ActivityParticipantCandidate,
  type AdminActivityRegistrationRow,
  type AdminActivityRow,
} from "../../api/admin";
import { useUserStore } from "../../store/user";
import { haptic } from "../../utils/haptics";
import { isLoggedInAsAdmin } from "../../utils/adminAuth";
import "./index.scss";

type CheckinMode = "checkin" | "makeup";
type PersonRow = AdminActivityRegistrationRow | ActivityParticipantCandidate;

const ACTIVE_STATUSES = new Set(["recruiting", "pending_start", "ongoing", "full", "ended"]);

function roleLabel(roleCode?: string) {
  const map: Record<string, string> = {
    CITY_ADMIN: "市管理员",
    BRANCH_ADMIN: "分会管理员",
    PLATFORM_ADMIN: "平台管理员",
  };
  return map[String(roleCode || "")] || roleCode || "管理员";
}

function statusLabel(status?: string) {
  const map: Record<string, string> = {
    recruiting: "报名中",
    pending_start: "待开始",
    ongoing: "进行中",
    full: "已满员",
    ended: "已结束",
  };
  return map[String(status || "")] || status || "-";
}

function displayName(row: PersonRow) {
  return row.realName || row.nickname || (row.userId ? `用户 ${row.userId}` : "未命名用户");
}

function rowMeta(row: PersonRow, includeVoucher = false) {
  const parts = [
    row.phone,
    row.email,
    includeVoucher ? (row as AdminActivityRegistrationRow).voucherNo || (row as AdminActivityRegistrationRow).orderNo : "",
    (row as ActivityParticipantCandidate).branchName,
  ].filter(Boolean);
  return parts.length ? parts.join(" · ") : "暂无联系方式";
}

function numberOf(value: any) {
  const num = Number(value);
  return Number.isFinite(num) ? num : 0;
}

export default function AdminActivityCheckinPage() {
  const adminUser = useUserStore((s) => s.adminUser);
  const [activities, setActivities] = useState<AdminActivityRow[]>([]);
  const [selectedActivityId, setSelectedActivityId] = useState(0);
  const [mode, setMode] = useState<CheckinMode>("checkin");
  const [keyword, setKeyword] = useState("");
  const [registrations, setRegistrations] = useState<AdminActivityRegistrationRow[]>([]);
  const [candidates, setCandidates] = useState<ActivityParticipantCandidate[]>([]);
  const [loadingActivities, setLoadingActivities] = useState(false);
  const [searching, setSearching] = useState(false);
  const [savingId, setSavingId] = useState<number | null>(null);
  const [searched, setSearched] = useState(false);
  const [notice, setNotice] = useState("");
  const { showActionDrawer, actionDrawer } = useActionDrawer();

  const selectedActivity = useMemo(
    () => activities.find((activity) => numberOf(activity.id) === selectedActivityId),
    [activities, selectedActivityId]
  );

  const activityOptions = useMemo(
    () => activities.map((activity) => `${activity.title} · ${statusLabel(activity.status)}`),
    [activities]
  );

  const activityIndex = useMemo(
    () => Math.max(0, activities.findIndex((activity) => numberOf(activity.id) === selectedActivityId)),
    [activities, selectedActivityId]
  );

  const selectedActivityStats = useMemo(() => {
    if (!selectedActivity) return "";
    const registered = numberOf(selectedActivity.registeredCount || selectedActivity.displayRegistrationCount);
    const checkin = numberOf(selectedActivity.checkinCount);
    return `${checkin}/${registered} 已签到`;
  }, [selectedActivity]);

  async function loadActivities() {
    setLoadingActivities(true);
    try {
      const page = await getAdminActivities({ page: 1, pageSize: 200 });
      const rows = page.items.filter((activity) => ACTIVE_STATUSES.has(String(activity.status || "")));
      setActivities(rows);
      const currentStillExists = rows.some((activity) => numberOf(activity.id) === selectedActivityId);
      const nextId = currentStillExists ? selectedActivityId : numberOf(rows[0]?.id);
      setSelectedActivityId(nextId);
      if (!rows.length) {
        setRegistrations([]);
        setCandidates([]);
      }
    } finally {
      setLoadingActivities(false);
    }
  }

  useDidShow(() => {
    if (isLoggedInAsAdmin()) {
      void loadActivities();
    }
  });

  function clearResults() {
    setRegistrations([]);
    setCandidates([]);
    setSearched(false);
    setNotice("");
  }

  async function runSearch(nextMode = mode) {
    haptic("light");
    if (!selectedActivityId) {
      Taro.showToast({ title: "请先选择活动", icon: "none" });
      return;
    }
    const trimmed = keyword.trim();
    if (!trimmed) {
      Taro.showToast({ title: "请输入姓名、手机号、邮箱或报名码", icon: "none" });
      return;
    }
    setSearching(true);
    setNotice("");
    try {
      const registrationPage = await getActivityRegistrations({
        activityId: selectedActivityId,
        status: "registered",
        keyword: trimmed,
        page: 1,
        pageSize: 40,
      });
      const registrationRows = registrationPage.items;
      setRegistrations(registrationRows);
      if (nextMode === "makeup") {
        const candidateRows = await searchActivityParticipants(selectedActivityId, trimmed, 30);
        const registeredUserIds = new Set(registrationRows.map((row) => numberOf(row.userId)));
        setCandidates(
          candidateRows.filter((row) => !registeredUserIds.has(numberOf(row.userId)) && !row.registered)
        );
      } else {
        setCandidates([]);
      }
      setSearched(true);
    } finally {
      setSearching(false);
    }
  }

  async function confirmAndCheckin(row: PersonRow, kind: "checkin" | "makeup") {
    const userId = numberOf(row.userId);
    if (!selectedActivity || !userId || savingId) return;
    const name = displayName(row);
    const result = await showActionDrawer({
      type: "confirm",
      title: kind === "makeup" ? "确认补录签到" : "确认现场签到",
      content: `${name}\n${selectedActivity.title}`,
      confirmText: kind === "makeup" ? "补录并签到" : "确认签到",
      cancelText: "取消",
    });
    if (!result.confirm) return;
    setSavingId(userId);
    try {
      await manualActivityCheckin(
        numberOf(selectedActivity.id),
        userId,
        kind === "makeup" ? "小程序补录报名并签到" : "小程序现场签到"
      );
      setNotice(`${name} 已完成签到`);
      Taro.showToast({ title: "签到成功", icon: "none" });
      await runSearch(kind === "makeup" ? "makeup" : "checkin");
    } finally {
      setSavingId(null);
    }
  }

  function switchMode(nextMode: CheckinMode) {
    if (nextMode === mode) return;
    haptic("light");
    setMode(nextMode);
    clearResults();
  }

  function onActivityChange(index: number) {
    const next = activities[index];
    setSelectedActivityId(numberOf(next?.id));
    clearResults();
  }

  function renderRegistrationRow(row: AdminActivityRegistrationRow) {
    const userId = numberOf(row.userId);
    const checked = Boolean(row.checkedIn);
    return (
      <View key={`registration-${row.id || userId}`} className="admin-checkin-result">
        <View className="admin-checkin-result__main">
          <View className="admin-checkin-result__title-row">
            <Text className="admin-checkin-result__name">{displayName(row)}</Text>
            <Text className={checked ? "admin-checkin-result__state is-done" : "admin-checkin-result__state"}>
              {checked ? "已签到" : "待签到"}
            </Text>
          </View>
          <Text className="admin-checkin-result__meta">{rowMeta(row, true)}</Text>
        </View>
        <View
          className={checked || savingId === userId ? "admin-checkin-result__action disabled" : "admin-checkin-result__action"}
          onClick={() => {
            if (!checked && savingId !== userId) void confirmAndCheckin(row, "checkin");
          }}
        >
          <Text>{savingId === userId ? "处理中" : checked ? "已完成" : "签到"}</Text>
        </View>
      </View>
    );
  }

  function renderCandidateRow(row: ActivityParticipantCandidate) {
    const userId = numberOf(row.userId);
    const checked = Boolean(row.checkedIn);
    return (
      <View key={`candidate-${userId}`} className="admin-checkin-result">
        <View className="admin-checkin-result__main">
          <View className="admin-checkin-result__title-row">
            <Text className="admin-checkin-result__name">{displayName(row)}</Text>
            <Text className={checked ? "admin-checkin-result__state is-done" : "admin-checkin-result__state is-new"}>
              {checked ? "已签到" : "未报名"}
            </Text>
          </View>
          <Text className="admin-checkin-result__meta">{rowMeta(row)}</Text>
        </View>
        <View
          className={checked || savingId === userId ? "admin-checkin-result__action disabled" : "admin-checkin-result__action is-secondary"}
          onClick={() => {
            if (!checked && savingId !== userId) void confirmAndCheckin(row, "makeup");
          }}
        >
          <Text>{savingId === userId ? "处理中" : checked ? "已完成" : "补录签到"}</Text>
        </View>
      </View>
    );
  }

  return (
    <AdminGuard>
      <View className="admin-checkin-page">
        <ScrollView scrollY className="admin-checkin-scroll">
          <View className="admin-checkin-header">
            <Text className="admin-checkin-header__title">活动签到</Text>
            <Text className="admin-checkin-header__meta">
              {adminUser?.name || "管理员"} · {roleLabel(adminUser?.roleCode)}
              {adminUser?.branchNames?.length ? ` · ${adminUser.branchNames.join("、")}` : ""}
            </Text>
          </View>

          <View className="admin-checkin-section">
            <Text className="admin-checkin-section__label">1 选择活动</Text>
            <Picker
              mode="selector"
              range={activityOptions}
              value={activityIndex}
              onChange={(event) => onActivityChange(Number(event.detail.value))}
            >
              <View className="admin-checkin-picker">
                <View className="admin-checkin-picker__main">
                  <Text className={selectedActivity ? "admin-checkin-picker__title" : "admin-checkin-picker__title muted"}>
                    {loadingActivities ? "活动加载中..." : selectedActivity?.title || "暂无可签到活动"}
                  </Text>
                  {selectedActivity ? (
                    <Text className="admin-checkin-picker__meta">
                      {statusLabel(selectedActivity.status)} · {selectedActivity.startsAt || "时间待定"} · {selectedActivityStats}
                    </Text>
                  ) : null}
                </View>
                <Text className="admin-checkin-picker__arrow">选择</Text>
              </View>
            </Picker>
          </View>

          <View className="admin-checkin-section">
            <Text className="admin-checkin-section__label">2 选择操作</Text>
            <View className="admin-checkin-tabs">
              <View
                className={mode === "checkin" ? "admin-checkin-tab active" : "admin-checkin-tab"}
                onClick={() => switchMode("checkin")}
              >
                <Text>现场签到</Text>
              </View>
              <View
                className={mode === "makeup" ? "admin-checkin-tab active" : "admin-checkin-tab"}
                onClick={() => switchMode("makeup")}
              >
                <Text>补录签到</Text>
              </View>
            </View>
          </View>

          <View className="admin-checkin-section">
            <Text className="admin-checkin-section__label">3 搜索人员</Text>
            <View className="admin-checkin-search">
              <Input
                className="admin-checkin-search__input"
                value={keyword}
                type="text"
                confirmType="search"
                maxlength={60}
                placeholder="姓名 / 手机号 / 邮箱 / 活动报名码"
                onInput={(event) => setKeyword(event.detail.value)}
                onConfirm={() => void runSearch()}
              />
              <View
                className={searching ? "admin-checkin-search__button disabled" : "admin-checkin-search__button"}
                onClick={() => {
                  if (!searching) void runSearch();
                }}
              >
                <Text>{searching ? "搜索中" : "搜索"}</Text>
              </View>
            </View>
            <Text className="admin-checkin-section__hint">
              {mode === "makeup" ? "补录会自动创建报名记录并完成签到。" : "搜索报名人员后点击签到。"}
            </Text>
          </View>

          <View className="admin-checkin-section admin-checkin-section--results">
            <View className="admin-checkin-result-head">
              <Text className="admin-checkin-section__label">4 处理结果</Text>
              {notice ? <Text className="admin-checkin-notice">{notice}</Text> : null}
            </View>

            {!searched && !searching ? (
              <View className="admin-checkin-empty">
                <Text>先选择活动，再输入关键词搜索。</Text>
              </View>
            ) : null}

            {searching ? (
              <View className="admin-checkin-empty">
                <Text>正在搜索...</Text>
              </View>
            ) : null}

            {!searching && registrations.length ? (
              <View className="admin-checkin-group">
                <Text className="admin-checkin-group__title">
                  {mode === "makeup" ? "已报名人员" : "报名人员"}
                </Text>
                {registrations.map(renderRegistrationRow)}
              </View>
            ) : null}

            {!searching && mode === "makeup" && candidates.length ? (
              <View className="admin-checkin-group">
                <Text className="admin-checkin-group__title">可补录人员</Text>
                {candidates.map(renderCandidateRow)}
              </View>
            ) : null}

            {!searching && searched && registrations.length === 0 && (mode === "checkin" || candidates.length === 0) ? (
              <View className="admin-checkin-empty">
                <Text>{mode === "makeup" ? "没有找到可补录人员。" : "没有找到报名记录，可切换到补录签到。"}</Text>
              </View>
            ) : null}
          </View>
        </ScrollView>
        {actionDrawer}
      </View>
    </AdminGuard>
  );
}
