"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useConvex, useMutation } from "convex/react";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { api } from "@/lib/convex/api";

type SharePermission = "read" | "edit";

export interface DocumentShareDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  documentId: string;
  documentTitle?: string | null;
  workspaceId: string;
  allowIncludeDescendants?: boolean;
  onChanged?: () => void | Promise<void>;
}

export function DocumentShareDialog({
  open,
  onOpenChange,
  documentId,
  documentTitle,
  workspaceId,
  allowIncludeDescendants = false,
  onChanged,
}: DocumentShareDialogProps) {
  const convex = useConvex();
  const [username, setUsername] = useState("");
  const [permission, setPermission] = useState<SharePermission>("read");
  const [includeDescendants, setIncludeDescendants] = useState(false);
  const [disableDownload, setDisableDownload] = useState(false);
  const [disableCopy, setDisableCopy] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [shares, setShares] = useState<any[] | null>(null);
  const [sharesLoading, setSharesLoading] = useState(false);
  const [groups, setGroups] = useState<Array<{ id: string; name: string }>>([]);
  const [groupShares, setGroupShares] = useState<any[] | null>(null);
  const [selectedGroupId, setSelectedGroupId] = useState("");
  const [groupIncludeDescendants, setGroupIncludeDescendants] = useState(false);
  const [groupDisableDownload, setGroupDisableDownload] = useState(false);
  const [groupDisableCopy, setGroupDisableCopy] = useState(false);
  const [groupMembers, setGroupMembers] = useState<Array<{ userId: string; username: string | null; role: string }>>(
    [],
  );
  const [groupEditableUserIds, setGroupEditableUserIds] = useState<Set<string>>(() => new Set());

  const upsertShare = useMutation(api.documentShares.upsert);
  const removeShare = useMutation(api.documentShares.remove);
  const upsertGroupShare = useMutation(api.documentGroupShares.upsert);
  const removeGroupShare = useMutation(api.documentGroupShares.remove);

  const loadShares = useCallback(async () => {
    if (!open) return;
    if (!documentId) {
      setShares([]);
      return;
    }

    setSharesLoading(true);
    try {
      const resp = await convex.query(api.documentShares.listByDocument, { documentId });
      setShares(Array.isArray(resp) ? resp : []);
    } catch (e: any) {
      const msg = e?.message ?? "加载共享者失败，请重试";
      // 说明：这类报错通常是 Convex functions 没有部署到当前 backend（尤其是自托管场景）。
      if (String(msg).includes("Could not find public function for 'documentShares:listByDocument'")) {
        setError("共享功能后端未部署/未更新：请在 `wolai-frontend` 目录执行 `npx convex dev --env-file ../.env.all` 或 `npx convex deploy --env-file ../.env.all` 后重试。");
      } else {
        setError(msg);
      }
      setShares([]);
    } finally {
      setSharesLoading(false);
    }
  }, [convex, documentId, open]);

  const loadGroups = useCallback(async () => {
    if (!open) return;
    if (!workspaceId) {
      setGroups([]);
      return;
    }
    const resp = await convex.query(api.groups.listByWorkspace, { workspaceId });
    const rows = Array.isArray(resp) ? (resp as any[]) : [];
    setGroups(rows.map((g) => ({ id: String(g.id), name: String(g.name ?? "") })));
  }, [convex, open, workspaceId]);

  const loadGroupShares = useCallback(async () => {
    if (!open) return;
    if (!documentId) {
      setGroupShares([]);
      return;
    }
    const resp = await convex.query(api.documentGroupShares.listByDocument, { documentId });
    setGroupShares(Array.isArray(resp) ? resp : []);
  }, [convex, documentId, open]);

  const loadGroupMembers = useCallback(
    async (groupId: string) => {
      if (!open) return;
      if (!groupId) {
        setGroupMembers([]);
        return;
      }
      const resp = await convex.query(api.groupMembers.listByGroup, { groupId });
      const rows = Array.isArray(resp) ? (resp as any[]) : [];
      setGroupMembers(
        rows.map((m) => ({
          userId: String(m.userId),
          username: m.username ? String(m.username) : null,
          role: String(m.role ?? ""),
        })),
      );
    },
    [convex, open],
  );

  useEffect(() => {
    if (!open) {
      setUsername("");
      setPermission("read");
      setIncludeDescendants(false);
      setDisableDownload(false);
      setDisableCopy(false);
      setSubmitting(false);
      setError(null);
      setShares(null);
      setSharesLoading(false);
      setGroups([]);
      setGroupShares(null);
      setSelectedGroupId("");
      setGroupIncludeDescendants(false);
      setGroupDisableDownload(false);
      setGroupDisableCopy(false);
      setGroupMembers([]);
      setGroupEditableUserIds(new Set());
      return;
    }
    void loadShares();
    void loadGroups();
    void loadGroupShares();
  }, [loadGroups, loadGroupShares, loadShares, open]);

  useEffect(() => {
    if (!open) return;
    void loadGroupMembers(selectedGroupId);
  }, [loadGroupMembers, open, selectedGroupId]);

  useEffect(() => {
    if (!open) return;
    if (!selectedGroupId) return;
    const rows = Array.isArray(groupShares) ? groupShares : [];
    const existing = rows.find((r: any) => String(r.groupId) === String(selectedGroupId));
    if (existing) {
      setGroupIncludeDescendants(Boolean(existing.includeDescendants));
      setGroupDisableDownload(Boolean(existing.disableDownload));
      setGroupDisableCopy(Boolean(existing.disableCopy));
      const editable = new Set<string>(Array.isArray(existing.editableUserIds) ? existing.editableUserIds.map(String) : []);
      setGroupEditableUserIds(editable);
    } else {
      setGroupIncludeDescendants(false);
      setGroupDisableDownload(false);
      setGroupDisableCopy(false);
      setGroupEditableUserIds(new Set());
    }
  }, [groupShares, open, selectedGroupId]);

  const shareRows = useMemo(() => {
    if (!Array.isArray(shares)) return [];
    return shares;
  }, [shares]);

  const handleSubmit = async () => {
    setError(null);
    const u = username.trim();
    if (!u) {
      setError("请输入对方用户名");
      return;
    }
    setSubmitting(true);
    try {
      await upsertShare({
        documentId,
        username: u,
        permission,
        includeDescendants: allowIncludeDescendants ? includeDescendants : false,
        disableDownload,
        disableCopy,
      });
      setUsername("");
      await loadShares();
      await onChanged?.();
    } catch (e: any) {
      const msg = e?.message ?? "共享失败，请重试";
      if (
        String(msg).includes("ArgumentValidationError") &&
        (String(msg).includes("disableCopy") || String(msg).includes("disableDownload"))
      ) {
        // 兼容旧后端：先用旧参数重试，避免用户完全无法共享。
        try {
          await upsertShare({
            documentId,
            username: u,
            permission,
            includeDescendants: allowIncludeDescendants ? includeDescendants : false,
          } as any);
          setUsername("");
          await loadShares();
          await onChanged?.();
          setError(
            "已共享，但“禁止下载/禁止复制”未生效（当前 Convex 后端未更新）。请在 `wolai-frontend` 目录执行 `npx convex dev --env-file ../.env.all` 或 `npx convex deploy --env-file ../.env.all` 后再设置限制。",
          );
        } catch {
          setError(
            "共享功能已升级（新增“禁止下载/禁止复制”），但当前 Convex 后端未更新。请在 `wolai-frontend` 目录执行 `npx convex dev --env-file ../.env.all` 或 `npx convex deploy --env-file ../.env.all` 后刷新页面再试。",
          );
        }
      } else {
        setError(msg);
      }
    } finally {
      setSubmitting(false);
    }
  };

  const handleRemove = async (sharedWithUserId: string) => {
    setError(null);
    setSubmitting(true);
    try {
      await removeShare({ documentId, sharedWithUserId });
      await loadShares();
      await onChanged?.();
    } catch (e: any) {
      setError(e?.message ?? "移除失败，请重试");
    } finally {
      setSubmitting(false);
    }
  };

  const handleUpsertGroupShare = async () => {
    setError(null);
    const groupId = selectedGroupId;
    if (!groupId) {
      setError("请选择群组");
      return;
    }
    setSubmitting(true);
    try {
      await upsertGroupShare({
        documentId,
        groupId,
        includeDescendants: allowIncludeDescendants ? groupIncludeDescendants : false,
        editableUserIds: Array.from(groupEditableUserIds),
        disableDownload: groupDisableDownload,
        disableCopy: groupDisableCopy,
      });
      await loadGroupShares();
      await onChanged?.();
    } catch (e: any) {
      const msg = e?.message ?? "公开失败，请重试";
      if (
        String(msg).includes("ArgumentValidationError") &&
        (String(msg).includes("disableCopy") || String(msg).includes("disableDownload"))
      ) {
        try {
          await upsertGroupShare({
            documentId,
            groupId,
            includeDescendants: allowIncludeDescendants ? groupIncludeDescendants : false,
            editableUserIds: Array.from(groupEditableUserIds),
          } as any);
          await loadGroupShares();
          await onChanged?.();
          setError(
            "已公开，但“禁止下载/禁止复制”未生效（当前 Convex 后端未更新）。请在 `wolai-frontend` 目录执行 `npx convex dev --env-file ../.env.all` 或 `npx convex deploy --env-file ../.env.all` 后再设置限制。",
          );
        } catch {
          setError(
            "共享功能已升级（新增“禁止下载/禁止复制”），但当前 Convex 后端未更新。请在 `wolai-frontend` 目录执行 `npx convex dev --env-file ../.env.all` 或 `npx convex deploy --env-file ../.env.all` 后刷新页面再试。",
          );
        }
      } else {
        setError(msg);
      }
    } finally {
      setSubmitting(false);
    }
  };

  const handleRemoveGroupShare = async (groupId: string) => {
    setError(null);
    setSubmitting(true);
    try {
      await removeGroupShare({ documentId, groupId });
      await loadGroupShares();
      await onChanged?.();
    } catch (e: any) {
      setError(e?.message ?? "取消公开失败，请重试");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>共享：{documentTitle ?? "无标题"}</DialogTitle>
        </DialogHeader>

        <div className="space-y-3">
          <div className="space-y-2">
            <div className="text-sm text-gray-600">输入用户名进行共享</div>
            <div className="flex gap-2">
              <Input
                value={username}
                onChange={(e) => setUsername(e.target.value)}
                placeholder="对方用户名"
                disabled={submitting}
              />
              <Button onClick={() => void handleSubmit()} disabled={submitting}>
                {submitting ? "处理中..." : "共享/更新"}
              </Button>
            </div>

            <div className="flex flex-wrap items-center gap-4 text-sm text-gray-700">
              <label className="flex items-center gap-2">
                <input
                  type="radio"
                  name="permission"
                  checked={permission === "read"}
                  onChange={() => setPermission("read")}
                  disabled={submitting}
                />
                只读
              </label>
              <label className="flex items-center gap-2">
                <input
                  type="radio"
                  name="permission"
                  checked={permission === "edit"}
                  onChange={() => setPermission("edit")}
                  disabled={submitting}
                />
                可编辑
              </label>
              {allowIncludeDescendants && (
                <label className="flex items-center gap-2">
                  <input
                    type="checkbox"
                    checked={includeDescendants}
                    onChange={(e) => setIncludeDescendants(e.target.checked)}
                    disabled={submitting}
                  />
                  包含子页面（共享文件夹）
                </label>
              )}
              <label className="flex items-center gap-2">
                <input
                  type="checkbox"
                  checked={disableDownload}
                  onChange={(e) => setDisableDownload(e.target.checked)}
                  disabled={submitting}
                />
                禁止下载
              </label>
              <label className="flex items-center gap-2">
                <input
                  type="checkbox"
                  checked={disableCopy}
                  onChange={(e) => setDisableCopy(e.target.checked)}
                  disabled={submitting}
                />
                禁止复制
              </label>
            </div>
          </div>

          <div className="rounded-md border border-gray-200 p-3">
            <div className="text-sm font-medium text-gray-700">公开到群组（群组内所有人可见）</div>
            <div className="mt-2 space-y-2">
              <div className="flex flex-wrap items-center gap-2">
                <select
                  className="h-9 rounded-md border border-gray-200 bg-white px-2 text-sm"
                  value={selectedGroupId}
                  onChange={(e) => setSelectedGroupId(e.target.value)}
                  disabled={submitting}
                >
                  <option value="">请选择群组</option>
                  {groups.map((g) => (
                    <option key={g.id} value={g.id}>
                      {g.name}
                    </option>
                  ))}
                </select>
                {allowIncludeDescendants && (
                  <label className="flex items-center gap-2 text-sm text-gray-700">
                    <input
                      type="checkbox"
                      checked={groupIncludeDescendants}
                      onChange={(e) => setGroupIncludeDescendants(e.target.checked)}
                      disabled={submitting}
                    />
                    包含子页面（公开文件夹）
                  </label>
                )}
                <label className="flex items-center gap-2 text-sm text-gray-700">
                  <input
                    type="checkbox"
                    checked={groupDisableDownload}
                    onChange={(e) => setGroupDisableDownload(e.target.checked)}
                    disabled={submitting}
                  />
                  禁止下载
                </label>
                <label className="flex items-center gap-2 text-sm text-gray-700">
                  <input
                    type="checkbox"
                    checked={groupDisableCopy}
                    onChange={(e) => setGroupDisableCopy(e.target.checked)}
                    disabled={submitting}
                  />
                  禁止复制
                </label>
                <Button onClick={() => void handleUpsertGroupShare()} disabled={submitting || !selectedGroupId}>
                  {submitting ? "处理中..." : "公开/更新"}
                </Button>
              </div>

              <div className="rounded-md border border-gray-200">
                <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">
                  群组成员权限（默认只读，可单独设为可编辑）
                </div>
                <div className="max-h-44 overflow-auto p-2">
                  {!selectedGroupId ? (
                    <div className="px-2 py-2 text-sm text-gray-400">请选择群组</div>
                  ) : groupMembers.length === 0 ? (
                    <div className="px-2 py-2 text-sm text-gray-400">暂无成员</div>
                  ) : (
                    <div className="space-y-1">
                      {groupMembers.map((m) => {
                        const checked = groupEditableUserIds.has(m.userId);
                        return (
                          <label
                            key={m.userId}
                            className="flex items-center justify-between gap-2 rounded-md px-2 py-2 text-sm hover:bg-gray-50"
                          >
                            <span className="min-w-0 flex-1 truncate text-gray-900">
                              {m.username ?? m.userId}
                              <span className="ml-2 text-xs text-gray-400">{m.role === "owner" ? "群主" : "成员"}</span>
                            </span>
                            <span className="flex items-center gap-2 text-xs text-gray-600">
                              <span>{checked ? "可编辑" : "只读"}</span>
                              <input
                                type="checkbox"
                                checked={checked}
                                onChange={(e) => {
                                  const next = new Set(groupEditableUserIds);
                                  if (e.target.checked) next.add(m.userId);
                                  else next.delete(m.userId);
                                  setGroupEditableUserIds(next);
                                }}
                                disabled={submitting}
                              />
                            </span>
                          </label>
                        );
                      })}
                    </div>
                  )}
                </div>
              </div>

              <div className="rounded-md border border-gray-200">
                <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">
                  已公开到群组
                </div>
                <div className="max-h-44 overflow-auto p-2">
                  {groupShares === null ? (
                    <div className="px-2 py-2 text-sm text-gray-400">加载中...</div>
                  ) : (groupShares ?? []).length === 0 ? (
                    <div className="px-2 py-2 text-sm text-gray-400">暂无公开群组</div>
                  ) : (
                    <div className="space-y-1">
                      {(groupShares ?? []).map((r: any) => (
                        <div
                          key={String(r.groupId)}
                          className="flex items-center justify-between gap-2 rounded-md px-2 py-2 text-sm hover:bg-gray-50"
                        >
                          <div className="min-w-0 flex-1">
                            <div className="truncate text-gray-900">{r.groupName ?? r.groupId}</div>
                            <div className="text-xs text-gray-500">
                              {r.includeDescendants ? "包含子页面" : "仅当前页面"}
                              {" · "}
                              可编辑：{Array.isArray(r.editableUserIds) ? r.editableUserIds.length : 0} 人
                              {(r.disableDownload || r.disableCopy) ? (
                                <>
                                  {" · "}
                                  {r.disableDownload ? "禁止下载" : ""}
                                  {r.disableDownload && r.disableCopy ? " / " : ""}
                                  {r.disableCopy ? "禁止复制" : ""}
                                </>
                              ) : null}
                            </div>
                          </div>
                          <Button
                            variant="outline"
                            className="h-8"
                            disabled={submitting}
                            onClick={() => void handleRemoveGroupShare(String(r.groupId))}
                          >
                            取消公开
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>

          {error && <div className="rounded-md bg-red-50 px-3 py-2 text-sm text-red-700">{error}</div>}

          <div className="rounded-md border border-gray-200">
            <div className="border-b border-gray-200 px-3 py-2 text-sm font-medium text-gray-700">
              已共享给
            </div>
            <div className="max-h-60 overflow-auto p-2">
              {sharesLoading && shares === null ? (
                <div className="px-2 py-2 text-sm text-gray-400">加载中...</div>
              ) : shareRows.length === 0 ? (
                <div className="px-2 py-2 text-sm text-gray-400">暂无共享者</div>
              ) : (
                <div className="space-y-1">
                  {shareRows.map((row: any) => (
                    <div
                      key={row.userId}
                      className="flex items-center justify-between gap-2 rounded-md px-2 py-2 text-sm hover:bg-gray-50"
                    >
                      <div className="min-w-0 flex-1">
                        <div className="truncate text-gray-900">
                          {row.username ?? row.userId}
                        </div>
                        <div className="text-xs text-gray-500">
                          权限：{row.permission === "edit" ? "可编辑" : "只读"}
                          {row.includeDescendants ? " · 包含子页面" : ""}
                          {(row.disableDownload || row.disableCopy) ? (
                            <>
                              {" · "}
                              {row.disableDownload ? "禁止下载" : ""}
                              {row.disableDownload && row.disableCopy ? " / " : ""}
                              {row.disableCopy ? "禁止复制" : ""}
                            </>
                          ) : null}
                        </div>
                      </div>
                      <Button
                        variant="outline"
                        className="h-8"
                        disabled={submitting}
                        onClick={() => void handleRemove(String(row.userId))}
                      >
                        移除
                      </Button>
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={submitting}>
            关闭
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
