import { useEffect, useState } from "react";
import {
  App as AntApp,
  Button,
  Checkbox,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Table,
  Tag,
  Typography,
} from "antd";
import {
  EditOutlined,
  PlusOutlined,
  ReloadOutlined,
  SafetyCertificateOutlined,
  KeyOutlined,
  LoginOutlined,
  LogoutOutlined,
} from "@ant-design/icons";
import {
  Session,
  PlatformAdminInfo,
  createPlatformTenant,
  enterPlatformTenant,
  exitPlatformTenant,
  getPlatformTenantPerms,
  issuePlatformAdminAccount,
  issuePlatformAdminInvite,
  listPlatformPermModules,
  listPlatformTenantAdmins,
  listPlatformTenants,
  listPlatformLwwOverrides,
  rollbackPlatformLwwOverride,
  setPlatformTenantPerms,
  updatePlatformTenant,
  updatePlatformTenantAdmin,
} from "./api";
import { confirmEnterCompany } from "./platformGuard";

type TenantRow = {
  tenant_id: number;
  name: string;
  slug: string;
  created_at: string;
  user_count: number;
  app_count: number;
};

type PermModule = { title: string; items: { perm: string; desc: string }[] };

export function PlatformTenantsPage(props: {
  session: Session;
  busy: boolean;
  setBusy: (v: boolean) => void;
  setError: (v: string) => void;
  setInfo: (v: string) => void;
  onSession?: (s: Session) => void;
  onEnteredCompany?: () => void;
}) {
  const { session, busy, setBusy, setError, setInfo, onSession, onEnteredCompany } = props;
  const { message, modal } = AntApp.useApp();
  const acting = (session.tenantId || 0) > 0;
  const [items, setItems] = useState<TenantRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const [renameOpen, setRenameOpen] = useState(false);
  const [permOpen, setPermOpen] = useState(false);
  const [adminOpen, setAdminOpen] = useState(false);
  const [editing, setEditing] = useState<TenantRow | null>(null);
  const [admins, setAdmins] = useState<PlatformAdminInfo[]>([]);
  const [adminUserId, setAdminUserId] = useState<number | null>(null);
  const [modules, setModules] = useState<PermModule[]>([]);
  const [catalogTotal, setCatalogTotal] = useState(0);
  const [selected, setSelected] = useState<string[]>([]);
  const [lastInvite, setLastInvite] = useState<string>("");
  const [lastAccount, setLastAccount] = useState<{
    username: string;
    password?: string;
    phone?: string;
    company: string;
  } | null>(null);
  const [lwwItems, setLwwItems] = useState<
    Awaited<ReturnType<typeof listPlatformLwwOverrides>>["items"]
  >([]);
  const [lwwLoading, setLwwLoading] = useState(false);
  const [form] = Form.useForm<{ name: string; slug: string; admin_phone?: string; with_invite?: boolean }>();
  const [renameForm] = Form.useForm<{ name: string; slug: string }>();
  const [adminForm] = Form.useForm<{
    user_id: number;
    phone: string;
    reset_password: boolean;
    password: string;
  }>();

  async function refresh() {
    setLoading(true);
    try {
      const res = await listPlatformTenants(session);
      setItems(res.items || []);
    } catch (e: any) {
      const msg = e.message || String(e);
      setError(msg);
      message.error(msg);
    } finally {
      setLoading(false);
    }
  }

  async function refreshLww() {
    setLwwLoading(true);
    try {
      const res = await listPlatformLwwOverrides(session, { limit: 100 });
      setLwwItems(res.items || []);
    } catch (e: any) {
      message.error(e.message || String(e));
    } finally {
      setLwwLoading(false);
    }
  }

  async function openAdminCreds(row: TenantRow) {
    setEditing(row);
    setBusy(true);
    try {
      const res = await listPlatformTenantAdmins(session, row.tenant_id);
      const list = res.items || [];
      setAdmins(list);
      if (list.length === 0) {
        // 无管理员：直接生成（手机号可选）
        const created = await issuePlatformAdminAccount(session, row.tenant_id, "");
        const acc = created.admin_account;
        setLastAccount({
          username: acc.username,
          password: acc.password,
          phone: acc.phone,
          company: row.name,
        });
        modal.info({
          title: `「${row.name}」管理员账号已生成`,
          content: (
            <div>
              <p>
                用户名：<Typography.Text copyable code>{acc.username}</Typography.Text>
              </p>
              <p>
                密码：<Typography.Text copyable code>{acc.password}</Typography.Text>
              </p>
              <Typography.Text type="danger">密码仅此一次展示；之后可在此改密码/绑手机。</Typography.Text>
            </div>
          ),
          okText: "已保存",
        });
        await refresh();
        return;
      }
      const first = list[0];
      setAdminUserId(first.user_id);
      adminForm.setFieldsValue({
        user_id: first.user_id,
        phone: first.phone || "",
        reset_password: false,
        password: "",
      });
      setAdminOpen(true);
    } catch (e: any) {
      message.error(e.message || String(e));
    } finally {
      setBusy(false);
    }
  }

  useEffect(() => {
    void refresh();
    void refreshLww();
    listPlatformPermModules(session)
      .then((r) => {
        setModules(r.modules || []);
        setCatalogTotal((r.catalog || []).length);
      })
      .catch(() => undefined);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [session.accessToken]);

  async function openPerms(row: TenantRow) {
    setEditing(row);
    setBusy(true);
    try {
      const cur = await getPlatformTenantPerms(session, row.tenant_id);
      setSelected(cur.permissions || []);
      if (cur.total) setCatalogTotal(cur.total);
      setPermOpen(true);
    } catch (e: any) {
      message.error(e.message || String(e));
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="panel">
      <Typography.Title level={4} style={{ marginTop: 0 }}>
        平台工作台 · 公司总览
      </Typography.Title>
      <Typography.Paragraph type="secondary">
        这是<strong>平台超级管理员自己的功能</strong>：新建/改名公司、路径 slug、权限额度；新建时同步生成该公司管理员账号（随机唯一）。
        路径约定：基础域名下 <Typography.Text code>/{`{slug}`}/...</Typography.Text>
        （例如 www.yuxinda.com/aaa/）。点「管理该公司」打开内部视图；身份始终是超管。
      </Typography.Paragraph>

      {acting && (
        <Typography.Paragraph>
          <Tag color="orange">
            正在管理：{session.tenantName || `公司 #${session.tenantId}`}
          </Tag>
          <Button
            size="small"
            icon={<LogoutOutlined />}
            style={{ marginLeft: 8 }}
            loading={busy}
            onClick={async () => {
              setBusy(true);
              try {
                const next = await exitPlatformTenant(session);
                onSession?.(next);
                setInfo("已回到平台工作台");
                message.success("已回到平台工作台");
              } catch (e: any) {
                message.error(e.message || String(e));
              } finally {
                setBusy(false);
              }
            }}
          >
            返回平台工作台
          </Button>
        </Typography.Paragraph>
      )}

      {lastAccount && (
        <Typography.Paragraph className="flash ok">
          「{lastAccount.company}」管理员（用户名唯一不可改）：
          用户名 <Typography.Text copyable code>{lastAccount.username}</Typography.Text>
          {lastAccount.password ? (
            <>
              {" · "}
              密码 <Typography.Text copyable code>{lastAccount.password}</Typography.Text>
            </>
          ) : null}
          {lastAccount.phone ? (
            <>
              {" · "}
              手机 <Typography.Text copyable code>{lastAccount.phone}</Typography.Text>
            </>
          ) : null}
        </Typography.Paragraph>
      )}
      {lastInvite && (
        <Typography.Paragraph className="flash ok">
          管理员邀请码：<Typography.Text copyable code>{lastInvite}</Typography.Text>（可选，发给客户自行注册）
        </Typography.Paragraph>
      )}

      <Space style={{ marginBottom: 12 }}>
        <Button type="primary" icon={<PlusOutlined />} onClick={() => setOpen(true)}>
          新建公司
        </Button>
        <Button icon={<ReloadOutlined />} loading={loading} onClick={() => void refresh()}>
          刷新
        </Button>
      </Space>

      <Table
        rowKey="tenant_id"
        loading={loading}
        dataSource={items}
        pagination={false}
        columns={[
          { title: "ID", dataIndex: "tenant_id", width: 70 },
          { title: "公司名称", dataIndex: "name" },
          {
            title: "路径 slug",
            dataIndex: "slug",
            width: 140,
            render: (s: string) => (s ? <Typography.Text code>/{s}/</Typography.Text> : <Tag>未设置</Tag>),
          },
          { title: "成员", dataIndex: "user_count", width: 70 },
          { title: "模块", dataIndex: "app_count", width: 70 },
          {
            title: "创建时间",
            dataIndex: "created_at",
            render: (v: string) => (v ? new Date(v).toLocaleString() : "—"),
          },
          {
            title: "操作",
            width: 420,
            render: (_: unknown, r: TenantRow) => (
              <Space wrap size={4}>
                <Button
                  type="primary"
                  size="small"
                  icon={<LoginOutlined />}
                  loading={busy}
                  onClick={async () => {
                    const ok = await confirmEnterCompany(modal, r.name, r.tenant_id);
                    if (!ok) return;
                    setBusy(true);
                    try {
                      const next = await enterPlatformTenant(session, r.tenant_id);
                      next.tenantName = r.name;
                      onSession?.(next);
                      setInfo(`已打开「${r.name}」管理视图（身份仍是平台超管）`);
                      message.success(`已打开「${r.name}」管理视图（身份仍是平台超管）`);
                      onEnteredCompany?.();
                    } catch (e: any) {
                      message.error(e.message || String(e));
                    } finally {
                      setBusy(false);
                    }
                  }}
                >
                  管理该公司
                </Button>
                <Button
                  size="small"
                  icon={<KeyOutlined />}
                  loading={busy}
                  onClick={() => void openAdminCreds(r)}
                >
                  管理员凭据
                </Button>
                <Button
                  size="small"
                  icon={<SafetyCertificateOutlined />}
                  onClick={() => void openPerms(r)}
                >
                  权限额度
                </Button>
                <Button
                  size="small"
                  icon={<EditOutlined />}
                  onClick={() => {
                    setEditing(r);
                    renameForm.setFieldsValue({ name: r.name, slug: r.slug || "" });
                    setRenameOpen(true);
                  }}
                >
                  改名/slug
                </Button>
                <Button
                  size="small"
                  type="link"
                  loading={busy}
                  onClick={async () => {
                    setBusy(true);
                    try {
                      const inv = await issuePlatformAdminInvite(session, r.tenant_id);
                      setLastInvite(inv.code);
                      setInfo(`已为「${r.name}」生成管理员邀请码`);
                      message.success("邀请码已生成");
                    } catch (e: any) {
                      message.error(e.message || String(e));
                    } finally {
                      setBusy(false);
                    }
                  }}
                >
                  邀请码
                </Button>
              </Space>
            ),
          },
        ]}
      />

      <Modal
        title="新建公司"
        open={open}
        onCancel={() => setOpen(false)}
        onOk={async () => {
          const v = await form.validateFields();
          setBusy(true);
          try {
            const res = await createPlatformTenant(
              session,
              v.name.trim(),
              !!v.with_invite,
              (v.slug || "").trim(),
              (v.admin_phone || "").trim()
            );
            const acc = res.admin_account;
            if (!acc?.username || !acc?.password) {
              message.error("公司已创建，但未返回管理员账号，请点「管理员凭据」补发");
              setOpen(false);
              form.resetFields();
              await refresh();
              return;
            }
            setLastAccount({
              username: acc.username,
              password: acc.password,
              phone: acc.phone,
              company: res.tenant.name,
            });
            modal.info({
              title: "公司与管理员账号已就绪",
              content: (
                <div>
                  <p>
                    公司 <Typography.Text strong>{res.tenant.name}</Typography.Text>
                    （路径 <Typography.Text code>/{res.tenant.slug}/</Typography.Text>）
                  </p>
                  <p>
                    管理员用户名：<Typography.Text copyable code>{acc.username}</Typography.Text>
                  </p>
                  <p>
                    管理员密码：<Typography.Text copyable code>{acc.password}</Typography.Text>
                  </p>
                  {acc.phone || v.admin_phone ? (
                    <p>
                      手机：<Typography.Text copyable code>{acc.phone || v.admin_phone}</Typography.Text>
                    </p>
                  ) : null}
                  <Typography.Text type="danger">
                    创建公司即附带此账号；密码仅展示一次，请立即保存。
                  </Typography.Text>
                </div>
              ),
              okText: "已保存",
            });
            const code = res.admin_invite?.code;
            if (code) setLastInvite(code);
            message.success(`已创建「${res.tenant.name}」并生成管理员账号`);
            setInfo(`已创建「${res.tenant.name}」管理员 ${acc.username}`);
            setOpen(false);
            form.resetFields();
            await refresh();
          } catch (e: any) {
            message.error(e.message || String(e));
          } finally {
            setBusy(false);
          }
        }}
        confirmLoading={busy}
      >
        <Form form={form} layout="vertical" initialValues={{ with_invite: false }}>
          <Form.Item name="name" label="公司名称" rules={[{ required: true, message: "请填写名称" }]}>
            <Input placeholder="例如：某某科技" />
          </Form.Item>
          <Form.Item
            name="slug"
            label="路径 slug"
            extra="访问前缀，如 aaa → www.yuxinda.com/aaa/。小写字母开头，仅 a-z/0-9/-"
            rules={[
              { required: true, message: "请填写 slug" },
              { pattern: /^[a-z][a-z0-9-]{1,31}$/, message: "格式：2–32 位，小写字母开头" },
            ]}
          >
            <Input placeholder="例如：aaa" />
          </Form.Item>
          <Form.Item
            name="admin_phone"
            label="管理员手机号（可选）"
            extra="填写则绑定，可用手机登录；有 License 期限控制时不必强制"
            rules={[
              {
                validator: async (_, value) => {
                  const s = String(value || "").trim();
                  if (!s) return;
                  if (!/^1[3-9]\d{9}$/.test(s)) throw new Error("请输入 11 位大陆手机号");
                },
              },
            ]}
          >
            <Input placeholder="例如 13800138000" maxLength={20} allowClear />
          </Form.Item>
          <Typography.Paragraph type="secondary" style={{ marginBottom: 8 }}>
            <strong>创建后立即生成</strong>管理员账号（随机用户名 + 初始密码）；密码弹窗展示一次。
          </Typography.Paragraph>
          <Form.Item name="with_invite" valuePropName="checked">
            <Checkbox>额外生成邀请码（可选，一般不需要）</Checkbox>
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="修改公司名称 / 路径"
        open={renameOpen}
        onCancel={() => setRenameOpen(false)}
        onOk={async () => {
          if (!editing) return;
          const v = await renameForm.validateFields();
          setBusy(true);
          try {
            await updatePlatformTenant(session, editing.tenant_id, v.name.trim(), (v.slug || "").trim());
            message.success("已保存");
            setRenameOpen(false);
            await refresh();
          } catch (e: any) {
            message.error(e.message || String(e));
          } finally {
            setBusy(false);
          }
        }}
        confirmLoading={busy}
      >
        <Form form={renameForm} layout="vertical">
          <Form.Item name="name" label="公司名称" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item
            name="slug"
            label="路径 slug"
            extra="修改后，对外路径变为 /{slug}/（路由层后续阶段启用）"
            rules={[
              { required: true, message: "请填写 slug" },
              { pattern: /^[a-z][a-z0-9-]{1,31}$/, message: "格式：2–32 位，小写字母开头" },
            ]}
          >
            <Input />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={editing ? `管理员凭据 · ${editing.name}` : "管理员凭据"}
        open={adminOpen}
        onCancel={() => setAdminOpen(false)}
        confirmLoading={busy}
        okText="保存"
        onOk={async () => {
          if (!editing || !adminUserId) return;
          const v = await adminForm.validateFields();
          const phoneChanged =
            (v.phone || "").trim() !== (admins.find((a) => a.user_id === adminUserId)?.phone || "");
          if (!v.reset_password && !phoneChanged) {
            message.info("未修改密码或手机号");
            return;
          }
          setBusy(true);
          try {
            const body: {
              reset_password?: boolean;
              password?: string;
              phone?: string;
            } = {};
            if (v.reset_password) {
              body.reset_password = true;
              body.password = (v.password || "").trim();
            }
            if (phoneChanged) {
              body.phone = (v.phone || "").trim();
            }
            const res = await updatePlatformTenantAdmin(session, editing.tenant_id, adminUserId, body);
            const acc = res.admin_account;
            setLastAccount({
              username: acc.username,
              password: acc.password,
              phone: acc.phone,
              company: editing.name,
            });
            if (acc.password) {
              modal.info({
                title: "密码已重置 — 请保存",
                content: (
                  <div>
                    <p>
                      用户名：<Typography.Text copyable code>{acc.username}</Typography.Text>
                    </p>
                    <p>
                      新密码：<Typography.Text copyable code>{acc.password}</Typography.Text>
                    </p>
                    {acc.phone ? (
                      <p>
                        手机：<Typography.Text copyable code>{acc.phone}</Typography.Text>
                      </p>
                    ) : null}
                    <Typography.Text type="danger">新密码仅此一次展示。</Typography.Text>
                  </div>
                ),
                okText: "已保存",
              });
            } else {
              message.success(acc.phone ? `已绑定手机 ${acc.phone}` : "已更新");
            }
            setInfo(`已更新「${editing.name}」管理员 ${acc.username}`);
            setAdminOpen(false);
            await refresh();
          } catch (e: any) {
            message.error(e.message || String(e));
          } finally {
            setBusy(false);
          }
        }}
        destroyOnHidden
      >
        <Form form={adminForm} layout="vertical">
          <Typography.Paragraph type="secondary">
            用户名不可改。可重置密码、绑定/更换手机号（手机登录可选）。
          </Typography.Paragraph>
          {admins.length > 1 ? (
            <Form.Item name="user_id" label="选择管理员" rules={[{ required: true }]}>
              <Select
                options={admins.map((a) => ({
                  value: a.user_id,
                  label: `${a.username}${a.phone ? ` · ${a.phone}` : ""}`,
                }))}
                onChange={(id) => {
                  setAdminUserId(id);
                  const hit = admins.find((a) => a.user_id === id);
                  adminForm.setFieldsValue({
                    phone: hit?.phone || "",
                    reset_password: false,
                    password: "",
                  });
                }}
              />
            </Form.Item>
          ) : (
            <Form.Item label="内部用户名">
              <Typography.Text code copyable>
                {admins[0]?.username || "—"}
              </Typography.Text>
            </Form.Item>
          )}
          <Form.Item
            name="phone"
            label="绑定手机号"
            extra="可选；留空保存即解除绑定。有期限控制时可用用户名登录"
            rules={[
              {
                validator: async (_, value) => {
                  const s = String(value || "").trim();
                  if (!s) return;
                  if (!/^1[3-9]\d{9}$/.test(s)) throw new Error("请输入 11 位大陆手机号");
                },
              },
            ]}
          >
            <Input placeholder="例如 13800138000" allowClear maxLength={20} />
          </Form.Item>
          <Form.Item name="reset_password" valuePropName="checked">
            <Checkbox>重置密码</Checkbox>
          </Form.Item>
          <Form.Item noStyle shouldUpdate={(p, c) => p.reset_password !== c.reset_password}>
            {() =>
              adminForm.getFieldValue("reset_password") ? (
                <Form.Item
                  name="password"
                  label="新密码"
                  extra="留空则随机生成，保存后仅展示一次"
                >
                  <Input.Password placeholder="至少 6 位，可留空自动生成" />
                </Form.Item>
              ) : null
            }
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={editing ? `公司权限额度 · ${editing.name}` : "公司权限额度"}
        open={permOpen}
        width={720}
        onCancel={() => setPermOpen(false)}
        onOk={() => {
          if (!editing) return;
          const doSave = async () => {
            setBusy(true);
            try {
              const res = await setPlatformTenantPerms(session, editing.tenant_id, selected);
              setSelected(res.permissions || []);
              message.success(`已保存（${(res.permissions || []).length}/${res.total || catalogTotal}）`);
              setPermOpen(false);
            } catch (e: any) {
              message.error(e.message || String(e));
            } finally {
              setBusy(false);
            }
          };
          if (selected.length === 0) {
            modal.confirm({
              title: "确认清空该公司全部权限？",
              content: "保存后该公司将无法使用任何业务接口，直到重新授予。",
              onOk: () => void doSave(),
            });
            return;
          }
          void doSave();
        }}
        confirmLoading={busy}
        okText="保存额度"
      >
        <Space style={{ marginBottom: 12 }}>
          <Tag>
            已选 {selected.length}/{catalogTotal || "?"}
          </Tag>
          <Button
            size="small"
            onClick={() =>
              setSelected(modules.flatMap((m) => (m.items || []).map((i) => i.perm)))
            }
          >
            全选
          </Button>
          <Button size="small" onClick={() => setSelected([])}>
            全不选
          </Button>
        </Space>
        <Space direction="vertical" size="middle" style={{ width: "100%" }}>
          {modules.map((g) => {
            const groupPerms = (g.items || []).map((i) => i.perm);
            return (
              <div key={g.title}>
                <Typography.Text strong>{g.title}</Typography.Text>
                <div style={{ marginTop: 8 }}>
                  <Checkbox.Group
                    style={{
                      width: "100%",
                      display: "grid",
                      gridTemplateColumns: "repeat(auto-fill, minmax(220px, 1fr))",
                      gap: 8,
                    }}
                    options={(g.items || []).map((i) => ({
                      label: (
                        <span>
                          {i.perm}
                          <br />
                          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                            {i.desc}
                          </Typography.Text>
                        </span>
                      ),
                      value: i.perm,
                    }))}
                    value={selected.filter((p) => groupPerms.includes(p))}
                    onChange={(checked) => {
                      const group = new Set(groupPerms);
                      const kept = selected.filter((p) => !group.has(p));
                      setSelected([...kept, ...(checked as string[])]);
                    }}
                  />
                </div>
              </div>
            );
          })}
        </Space>
      </Modal>

      <Typography.Title level={5} style={{ marginTop: 32 }}>
        LWW 覆盖日志（仅超管）
      </Typography.Title>
      <Typography.Paragraph type="secondary">
        同步自动覆盖时的落败/胜出记录；公司管理员不可见。默认保留 90 天。
        对「源端覆盖」记录可按落败快照回滚线上单行（需通道 remote 仍可达）。
      </Typography.Paragraph>
      <Space style={{ marginBottom: 8 }}>
        <Button icon={<ReloadOutlined />} loading={lwwLoading} onClick={() => void refreshLww()}>
          刷新日志
        </Button>
      </Space>
      <Table
        rowKey="id"
        size="small"
        loading={lwwLoading}
        dataSource={lwwItems}
        pagination={{ pageSize: 10 }}
        columns={[
          { title: "公司", dataIndex: "tenant_id", width: 80 },
          { title: "入口", dataIndex: "entry", width: 100 },
          { title: "表", dataIndex: "table", width: 120 },
          { title: "主键", dataIndex: "row_pk", ellipsis: true },
          { title: "策略", dataIndex: "policy", width: 110 },
          { title: "结果", dataIndex: "outcome", width: 120 },
          {
            title: "时间",
            dataIndex: "created_at",
            width: 180,
            render: (v: string) => (v ? new Date(v).toLocaleString() : ""),
          },
          {
            title: "操作",
            width: 100,
            render: (_: unknown, r: (typeof lwwItems)[number]) =>
              r.outcome === "applied_source" ? (
                <Button
                  size="small"
                  danger
                  loading={busy}
                  onClick={() => {
                    modal.confirm({
                      title: "按落败快照回滚线上单行？",
                      content: `${r.table} / ${r.row_pk}`,
                      onOk: async () => {
                        setBusy(true);
                        try {
                          await rollbackPlatformLwwOverride(session, r.id);
                          message.success("已回滚并记入审计");
                          await refreshLww();
                        } catch (e: any) {
                          message.error(e.message || String(e));
                        } finally {
                          setBusy(false);
                        }
                      },
                    });
                  }}
                >
                  回滚
                </Button>
              ) : null,
          },
        ]}
      />
    </div>
  );
}
