"use client";

import { FormEvent, useEffect, useMemo, useRef, useState } from "react";
import { CirclePause, KeyRound, Loader2, Pencil, Plus, RefreshCw, Save, Search, Trash2, UserCheck, UserPlus, UserX } from "lucide-react";
import { crossfadeIn, pulseFeedback, revealChildren, runScopedMotion } from "@/lib/ui/motion";

type OrganizationInfo = {
  organizationId: string;
  organizationName: string;
};

type OrganizationGroupInfo = {
  groupId: string;
  groupName: string;
};

type OrganizationRoleInfo = {
  roleId: string;
  roleName: string;
};

type OrganizationMemberInfo = {
  memberId: string;
  memberName: string;
  memberStatus: string;
  memberPhone: string;
  organizationId: string;
  memberRoleId?: string;
  memberRoleName?: string;
  memberGroupId?: string;
  memberGroupName?: string;
  memberUserId?: string;
};

type PageResult<T> = {
  records: T[];
  total: number;
  size: number;
  current: number;
  pages: number;
};

type AccountPayload = {
  configured: boolean;
  missing: string[];
  staffConfigured: boolean;
  staffMissing: string[];
  selectedOrganizationId: string;
  organizations: OrganizationInfo[];
  groups: OrganizationGroupInfo[];
  roles: OrganizationRoleInfo[];
  members: PageResult<OrganizationMemberInfo>;
  warnings?: string[];
  memberListAvailable?: boolean;
  passwordManagementAvailable: boolean;
};

type MemberForm = {
  organizationId: string;
  username: string;
  memberName: string;
  memberPhone: string;
  initialPassword: string;
  mustChangePassword: boolean;
  roleId: string;
  groupId: string;
};

type DepartmentForm = {
  groupName: string;
  groupDesc: string;
};

const blankForm: MemberForm = {
  organizationId: "",
  username: "",
  memberName: "",
  memberPhone: "",
  initialPassword: "",
  mustChangePassword: true,
  roleId: "",
  groupId: ""
};

const blankDepartmentForm: DepartmentForm = {
  groupName: "",
  groupDesc: ""
};

const STATUS_OPTIONS = [
  { value: "", label: "全部状态" },
  { value: "0", label: "在岗" },
  { value: "1", label: "休假" },
  { value: "2", label: "停用" }
];

export function AccountManager() {
  const [payload, setPayload] = useState<AccountPayload | null>(null);
  const [organizationId, setOrganizationId] = useState("");
  const [status, setStatus] = useState("");
  const [query, setQuery] = useState("");
  const [draftQuery, setDraftQuery] = useState("");
  const [pageNum, setPageNum] = useState(1);
  const [form, setForm] = useState<MemberForm>(blankForm);
  const [departmentForm, setDepartmentForm] = useState<DepartmentForm>(blankDepartmentForm);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [creatingGroup, setCreatingGroup] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const managerRef = useRef<HTMLDivElement | null>(null);
  const listRef = useRef<HTMLElement | null>(null);
  const feedbackRef = useRef<HTMLDivElement | null>(null);

  const selectedOrganizationId = organizationId || payload?.selectedOrganizationId || "";
  const members = payload?.members.records || [];
  const total = payload?.members.total || 0;
  const pages = payload?.members.pages || 0;
  const memberListAvailable = payload?.memberListAvailable !== false;
  const warnings = payload?.warnings || [];
  const canSubmit = Boolean(payload?.configured && selectedOrganizationId && form.memberName.trim() &&
    (editingId || (payload.staffConfigured && form.memberPhone.trim())) &&
    selectedRoleId(payload, form) && selectedGroupId(payload, form));

  const currentOrganization = useMemo(() => {
    return payload?.organizations.find((item) => item.organizationId === selectedOrganizationId);
  }, [payload?.organizations, selectedOrganizationId]);

  useEffect(() => {
    void loadAccounts();
  }, [organizationId, pageNum, query, status]);

  useEffect(() => {
    return runScopedMotion(managerRef, (scope) => revealChildren(scope));
  }, []);

  useEffect(() => {
    crossfadeIn(listRef.current);
  }, [members.length, pageNum, query, status, selectedOrganizationId]);

  useEffect(() => {
    pulseFeedback(feedbackRef.current);
  }, [error, message]);

  async function loadAccounts() {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams({
        pageNum: String(pageNum),
        pageSize: "10"
      });
      if (organizationId) params.set("organizationId", organizationId);
      if (query) params.set("memberName", query);
      if (status) params.set("memberStatus", status);
      const response = await fetch(`/api/admin/accounts?${params.toString()}`, { cache: "no-store" });
      const nextPayload = await response.json() as AccountPayload & { error?: string };
      if (!response.ok) throw new Error(nextPayload.error || "读取账号数据失败");
      setPayload(nextPayload);
      syncSelectedOrganization(nextPayload);
      syncFormDefaults(nextPayload);
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }

  function syncSelectedOrganization(nextPayload: AccountPayload) {
    if (!organizationId && nextPayload.selectedOrganizationId) {
      setOrganizationId(nextPayload.selectedOrganizationId);
    }
  }

  function syncFormDefaults(nextPayload: AccountPayload) {
    setForm((current) => {
      const nextOrganizationId = nextPayload.selectedOrganizationId || current.organizationId;
      return {
        ...current,
        organizationId: nextOrganizationId,
        roleId: nextPayload.roles.some((role) => role.roleId === current.roleId)
          ? current.roleId
          : nextPayload.roles[0]?.roleId || "",
        groupId: nextPayload.groups.some((group) => group.groupId === current.groupId)
          ? current.groupId
          : nextPayload.groups[0]?.groupId || ""
      };
    });
  }

  function submitSearch(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setPageNum(1);
    setQuery(draftQuery.trim());
  }

  async function submitMember(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    setError(null);
    setMessage(null);
    try {
      const roleId = selectedRoleId(payload, form);
      const groupId = selectedGroupId(payload, form);
      const body = editingId ? {
        memberId: editingId,
        memberName: form.memberName.trim(),
        roleId,
        groupId
      } : {
        organizationId: selectedOrganizationId,
        username: form.username.trim(),
        phone: form.memberPhone.trim(),
        name: form.memberName.trim(),
        initialPassword: form.initialPassword.trim(),
        mustChangePassword: form.mustChangePassword,
        memberName: form.memberName.trim(),
        memberPhone: form.memberPhone.trim(),
        roleId,
        groupId
      };
      const response = await fetch("/api/admin/accounts", {
        method: editingId ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body)
      });
      const result = await response.json();
      if (!response.ok) throw new Error(result.error || "保存成员失败");
      const initialPassword = result.user?.initialPassword;
      const successMessage = editingId
        ? "成员信息已更新。"
        : initialPassword
          ? `成员已创建，初始密码：${initialPassword}`
          : "成员已创建。";
      setMessage(!editingId && !memberListAvailable
        ? `${successMessage} 成员列表暂不可用，上游授权后可在列表看到。`
        : successMessage);
      resetForm();
      await loadAccounts();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  }

  async function changeStatus(memberId: string, memberStatus: "0" | "1" | "2") {
    await mutateMember("PUT", { memberId, memberStatus }, "成员状态已更新。");
  }

  async function removeMember(memberId: string) {
    if (!window.confirm("确定删除这个成员？")) return;
    await mutateMember("DELETE", { memberId }, "成员已删除。");
  }

  async function resetPassword(member: OrganizationMemberInfo) {
    if (!member.memberUserId) {
      setError("该成员还没有绑定企业端用户，不能重置密码。");
      return;
    }
    const newPassword = window.prompt(`请输入 ${member.memberName} 的新密码`);
    if (!newPassword) return;
    setSaving(true);
    setError(null);
    setMessage(null);
    try {
      const response = await fetch("/api/admin/accounts/password", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          userId: member.memberUserId,
          newPassword,
          mustChangePassword: true
        })
      });
      const result = await response.json();
      if (!response.ok) throw new Error(result.error || "重置密码失败");
      setMessage("密码已重置，用户下次登录需要修改密码。");
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  }

  async function mutateMember(method: "PUT" | "DELETE", body: Record<string, string>, successMessage: string) {
    setSaving(true);
    setError(null);
    setMessage(null);
    try {
      const response = await fetch("/api/admin/accounts", {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body)
      });
      const result = await response.json();
      if (!response.ok) throw new Error(result.error || "成员操作失败");
      setMessage(successMessage);
      await loadAccounts();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  }

  async function submitGroup(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!selectedOrganizationId) {
      setError("请先选择组织。");
      return;
    }
    const groupName = departmentForm.groupName.trim();
    if (!groupName) {
      setError("部门名称不能为空。");
      return;
    }
    setCreatingGroup(true);
    setError(null);
    setMessage(null);
    try {
      const response = await fetch("/api/admin/accounts/groups", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          organizationId: selectedOrganizationId,
          groupName,
          groupDesc: departmentForm.groupDesc.trim()
        })
      });
      const result = await response.json() as { error?: string; group?: OrganizationGroupInfo | null };
      if (!response.ok) throw new Error(result.error || "创建部门失败");
      setDepartmentForm(blankDepartmentForm);
      await loadAccounts();
      if (result.group?.groupId) {
        setForm((current) => ({ ...current, groupId: result.group?.groupId || current.groupId }));
      }
      setMessage("部门已创建。");
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setCreatingGroup(false);
    }
  }

  function editMember(member: OrganizationMemberInfo) {
    setEditingId(member.memberId);
    setForm({
      organizationId: member.organizationId || selectedOrganizationId,
      username: "",
      memberName: member.memberName || "",
      memberPhone: member.memberPhone || "",
      initialPassword: "",
      mustChangePassword: true,
      roleId: member.memberRoleId || payload?.roles[0]?.roleId || "",
      groupId: member.memberGroupId || payload?.groups[0]?.groupId || ""
    });
  }

  function resetForm() {
    setEditingId(null);
    setForm({
      organizationId: selectedOrganizationId,
      username: "",
      memberName: "",
      memberPhone: "",
      initialPassword: "",
      mustChangePassword: true,
      roleId: payload?.roles[0]?.roleId || "",
      groupId: payload?.groups[0]?.groupId || ""
    });
  }

  return (
    <div className="account-manager" ref={managerRef}>
      <div className="workspace-head" data-animate>
        <div>
          <h1 className="workspace-title">账号管理</h1>
        </div>
        <div className="workspace-meta">
          <span className="status">{payload?.organizations.length || 0} 组织</span>
          <span className="status running">{total} 成员</span>
          <span className={`status ${payload?.configured ? "" : "failed"}`}>{payload?.configured ? "已接入" : "待配置"}</span>
        </div>
      </div>

      <section className="panel account-actions" data-animate>
        <label className="field account-org-field">
          <span>组织</span>
          <select
            value={selectedOrganizationId}
            onChange={(event) => {
              setOrganizationId(event.target.value);
              setPageNum(1);
              setEditingId(null);
              setForm({ ...blankForm, organizationId: event.target.value });
            }}
            disabled={!payload?.configured || loading}
          >
            {payload?.organizations.length ? payload.organizations.map((item) => (
              <option value={item.organizationId} key={item.organizationId}>{item.organizationName || item.organizationId}</option>
            )) : (
              <option value="">{payload?.configured ? "暂无组织" : "组织接口未配置"}</option>
            )}
          </select>
        </label>
        <form className="log-search account-search" onSubmit={submitSearch}>
          <Search aria-hidden="true" />
          <input
            value={draftQuery}
            placeholder="搜索成员姓名"
            onChange={(event) => setDraftQuery(event.target.value)}
            disabled={!memberListAvailable || loading}
          />
        </form>
        <select className="account-status-select" value={status} onChange={(event) => {
          setStatus(event.target.value);
          setPageNum(1);
        }} disabled={!memberListAvailable || loading}>
          {STATUS_OPTIONS.map((item) => <option value={item.value} key={item.value}>{item.label}</option>)}
        </select>
        <div className="toolbar">
          <button className="button" type="button" onClick={loadAccounts} disabled={loading || saving}>
            {loading ? <Loader2 className="spin" size={18} /> : <RefreshCw size={18} />}
            刷新
          </button>
        </div>
      </section>

      {error || message ? (
        <div ref={feedbackRef}>
          {error ? <div className="callout" role="alert">{error}</div> : null}
          {message ? <div className="callout success-callout" role="status" aria-live="polite">{message}</div> : null}
        </div>
      ) : null}

      {warnings.length ? (
        <div className="callout" role="status" data-animate>
          {accountWarningText(warnings[0])}
        </div>
      ) : null}

      {!payload?.configured ? (
        <div className="callout" role="status" data-animate>
          组织接口未配置：需要组织能力网关地址，用于读取组织、部门、角色和成员列表。
        </div>
      ) : !payload.passwordManagementAvailable ? (
        <div className="callout" role="status" data-animate>
          企业端用户接口未配置：{payload?.staffMissing.join("、") || "ZHINIAN_STAFF_API_BASE_URL、ZHINIAN_ORG_TENANT_ID"}。配置后可创建企业用户并重置密码。
        </div>
      ) : null}

      <section className="panel account-department-panel" data-animate>
        <div className="settings-group-head">
          <div>
            <h2>部门管理</h2>
            <p className="muted">{currentOrganization?.organizationName || selectedOrganizationId || "请选择组织"}</p>
          </div>
        </div>
        <form className="account-department-form" onSubmit={submitGroup}>
          <label className="field">
            <span>部门名称</span>
            <input
              value={departmentForm.groupName}
              onChange={(event) => setDepartmentForm((item) => ({ ...item, groupName: event.target.value }))}
              disabled={!payload?.configured || !selectedOrganizationId || creatingGroup}
            />
          </label>
          <label className="field">
            <span>部门描述</span>
            <input
              value={departmentForm.groupDesc}
              placeholder="可留空"
              onChange={(event) => setDepartmentForm((item) => ({ ...item, groupDesc: event.target.value }))}
              disabled={!payload?.configured || !selectedOrganizationId || creatingGroup}
            />
          </label>
          <button className="button" type="submit" disabled={!payload?.configured || !selectedOrganizationId || creatingGroup || !departmentForm.groupName.trim()}>
            {creatingGroup ? <Loader2 className="spin" size={18} /> : <Plus size={18} />}
            创建部门
          </button>
        </form>
      </section>

      <section className="panel account-form-panel" data-animate>
        <div className="settings-group-head">
          <div>
            <h2>{editingId ? "编辑成员" : "新建用户"}</h2>
            <p className="muted">{currentOrganization?.organizationName || selectedOrganizationId || "请选择组织"}</p>
          </div>
          {editingId ? (
            <button className="button" type="button" onClick={resetForm} disabled={saving}>
              取消编辑
            </button>
          ) : null}
        </div>
        <form className="account-form-grid" onSubmit={submitMember}>
          <label className="field">
            <span>成员名称</span>
            <input value={form.memberName} onChange={(event) => setForm((item) => ({ ...item, memberName: event.target.value }))} disabled={!payload?.configured || saving} />
          </label>
          <label className="field">
            <span>手机号</span>
            <input value={form.memberPhone} onChange={(event) => setForm((item) => ({ ...item, memberPhone: event.target.value }))} disabled={!payload?.configured || saving || Boolean(editingId)} />
          </label>
          <label className="field">
            <span>用户名</span>
            <input value={form.username} placeholder="默认使用手机号" onChange={(event) => setForm((item) => ({ ...item, username: event.target.value }))} disabled={!payload?.staffConfigured || saving || Boolean(editingId)} />
          </label>
          <label className="field">
            <span>初始密码</span>
            <input type="password" value={form.initialPassword} placeholder="留空由服务端生成" onChange={(event) => setForm((item) => ({ ...item, initialPassword: event.target.value }))} disabled={!payload?.staffConfigured || saving || Boolean(editingId)} />
          </label>
          <label className="field">
            <span>角色</span>
            <select value={selectedRoleId(payload, form)} onChange={(event) => setForm((item) => ({ ...item, roleId: event.target.value }))} disabled={!payload?.roles.length || saving}>
              {payload?.roles.length ? payload.roles.map((role) => (
                <option value={role.roleId} key={role.roleId}>{role.roleName}</option>
              )) : <option value="">暂无角色</option>}
            </select>
          </label>
          <label className="field">
            <span>部门</span>
            <select value={selectedGroupId(payload, form)} onChange={(event) => setForm((item) => ({ ...item, groupId: event.target.value }))} disabled={!payload?.groups.length || saving}>
              {payload?.groups.length ? payload.groups.map((group) => (
                <option value={group.groupId} key={group.groupId}>{group.groupName}</option>
              )) : <option value="">暂无部门</option>}
            </select>
          </label>
          <label className="toggle-line account-password-toggle">
            <input
              type="checkbox"
              checked={form.mustChangePassword}
              onChange={(event) => setForm((item) => ({ ...item, mustChangePassword: event.target.checked }))}
              disabled={!payload?.staffConfigured || saving || Boolean(editingId)}
            />
            首次登录改密
          </label>
          <div className="toolbar account-form-submit">
            <button className="button primary account-create-submit" type="submit" disabled={!canSubmit || saving || creatingGroup}>
              {saving ? <Loader2 className="spin" size={18} /> : editingId ? <Save size={18} /> : <UserPlus size={18} />}
              {editingId ? "保存成员" : "新建用户"}
            </button>
          </div>
        </form>
      </section>

      <section className="panel account-list" data-animate ref={listRef}>
        {loading && !payload ? (
          <div className="settings-loading">
            <Loader2 className="spin" size={18} />
            正在读取账号
          </div>
        ) : members.length ? (
          <div className="account-table" role="table" aria-label="账号成员">
            <div className="account-row account-head" role="row">
              <span>成员</span>
              <span>角色 / 部门</span>
              <span>状态</span>
              <span>操作</span>
            </div>
            {members.map((member) => (
              <div className="account-row" role="row" key={member.memberId}>
                <div className="account-member-main">
                  <strong>{member.memberName}</strong>
                  <small>{member.memberPhone || member.memberId}</small>
                </div>
                <div className="account-member-main">
                  <strong>{member.memberRoleName || "-"}</strong>
                  <small>{member.memberGroupName || "-"}</small>
                </div>
                <span className={`status ${member.memberStatus === "2" ? "failed" : member.memberStatus === "1" ? "running" : ""}`}>{memberStatusLabel(member.memberStatus)}</span>
                <div className="toolbar account-row-actions">
                  <button className="icon-button" type="button" title="编辑成员" aria-label="编辑成员" onClick={() => editMember(member)} disabled={saving}>
                    <Pencil aria-hidden="true" />
                  </button>
                  <button className="icon-button" type="button" title="重置密码" aria-label="重置密码" onClick={() => resetPassword(member)} disabled={saving || !payload?.staffConfigured || !member.memberUserId}>
                    <KeyRound aria-hidden="true" />
                  </button>
                  <button className="icon-button" type="button" title={member.memberStatus === "0" ? "设为休假" : "设为在岗"} aria-label={member.memberStatus === "0" ? "设为休假" : "设为在岗"} onClick={() => changeStatus(member.memberId, member.memberStatus === "0" ? "1" : "0")} disabled={saving}>
                    {member.memberStatus === "0" ? <CirclePause aria-hidden="true" /> : <UserCheck aria-hidden="true" />}
                  </button>
                  <button className="icon-button danger-icon" type="button" title="停用成员" aria-label="停用成员" onClick={() => changeStatus(member.memberId, "2")} disabled={saving || member.memberStatus === "2"}>
                    <UserX aria-hidden="true" />
                  </button>
                  <button className="icon-button danger-icon" type="button" title="删除成员" aria-label="删除成员" onClick={() => removeMember(member.memberId)} disabled={saving}>
                    <Trash2 aria-hidden="true" />
                  </button>
                </div>
              </div>
            ))}
          </div>
        ) : (
          <div className="log-empty">{accountEmptyText(payload)}</div>
        )}
        {pages > 1 ? (
          <div className="pagination">
            <button className="icon-button" type="button" onClick={() => setPageNum((item) => Math.max(1, item - 1))} disabled={pageNum <= 1 || loading}>‹</button>
            <span className="pager-meta">{pageNum} / {pages}</span>
            <button className="icon-button" type="button" onClick={() => setPageNum((item) => Math.min(pages, item + 1))} disabled={pageNum >= pages || loading}>›</button>
          </div>
        ) : null}
      </section>
    </div>
  );
}

function selectedRoleId(payload: AccountPayload | null, form: MemberForm): string {
  if (payload?.roles.some((role) => role.roleId === form.roleId)) return form.roleId;
  return payload?.roles[0]?.roleId || "";
}

function selectedGroupId(payload: AccountPayload | null, form: MemberForm): string {
  if (payload?.groups.some((group) => group.groupId === form.groupId)) return form.groupId;
  return payload?.groups[0]?.groupId || "";
}

function memberStatusLabel(status: string): string {
  if (status === "0") return "在岗";
  if (status === "1") return "休假";
  if (status === "2") return "停用";
  return status || "未知";
}

function accountEmptyText(payload: AccountPayload | null): string {
  if (!payload?.configured) return "组织接口配置后显示成员";
  if (payload.memberListAvailable === false) return "成员列表暂不可用，新增账号仍可使用";
  return "暂无成员";
}

function accountWarningText(message: string): string {
  if (/仅管理员角色|上游.*管理员|hotelStaff 管理员|管理员角色/i.test(message)) {
    return "成员列表需要认证中心管理员角色 1。当前账号已允许进入本平台后台，但上游 hotelStaff 暂未授权成员列表查询。";
  }
  if (/成员列表|organizationMemberList|ZHINIAN_ORG_MEMBER_LIST_PATH/i.test(message)) {
    return "成员列表待接入：当前组织服务还没有开放成员查询，新增账号仍可使用。";
  }
  return message;
}
