import { ReactNode, useMemo, useState } from "react";
import {
  App as AntApp,
  Avatar,
  Button,
  Form,
  Input,
  Layout,
  Menu,
  Modal,
  Space,
  Tag,
  Typography,
  theme,
} from "antd";
import {
  ApartmentOutlined,
  ApiOutlined,
  AuditOutlined,
  ArrowLeftOutlined,
  BankOutlined,
  CloudSyncOutlined,
  KeyOutlined,
  LogoutOutlined,
  MobileOutlined,
  RobotOutlined,
  AppstoreOutlined,
  TeamOutlined,
  UserAddOutlined,
  UserOutlined,
  ThunderboltOutlined,
  MenuFoldOutlined,
  MenuUnfoldOutlined,
} from "@ant-design/icons";
import { bindPhone, changePassword, exitPlatformTenant, saveSession, type Session } from "./api";
import { hasEntitlement, isCompanyAdmin, isPlatformAdmin, roleLabel } from "./agentPerms";

const { Header, Sider, Content } = Layout;

export type ConsoleTab =
  | "generate"
  | "modules"
  | "agent"
  | "roles"
  | "agents"
  | "orgs"
  | "invites"
  | "members"
  | "audit"
  | "sync"
  | "platform";

type Props = {
  session: Session;
  entitlements: string[] | null;
  tab: ConsoleTab;
  onTabChange: (tab: ConsoleTab) => void;
  onOpenApp: () => void;
  onLogout: () => void;
  onSession?: (s: Session) => void;
  busy?: boolean;
  banner?: ReactNode;
  children: ReactNode;
};

const TAB_TITLES: Record<ConsoleTab, string> = {
  platform: "平台管理",
  generate: "生成与发布",
  modules: "模块管理",
  sync: "数据同步",
  agent: "智能体胶囊",
  roles: "角色管理",
  agents: "智能体账号",
  orgs: "组织管理",
  invites: "邀请加入",
  members: "成员管理",
  audit: "审计",
};

export function ConsoleLayout({
  session,
  entitlements,
  tab,
  onTabChange,
  onOpenApp,
  onLogout,
  onSession,
  busy,
  banner,
  children,
}: Props) {
  const [collapsed, setCollapsed] = useState(false);
  const [pwdOpen, setPwdOpen] = useState(false);
  const [pwdBusy, setPwdBusy] = useState(false);
  const [phoneOpen, setPhoneOpen] = useState(false);
  const [phoneBusy, setPhoneBusy] = useState(false);
  const [exitTenantBusy, setExitTenantBusy] = useState(false);
  const [pwdForm] = Form.useForm<{ old_password: string; new_password: string; confirm: string }>();
  const [phoneForm] = Form.useForm<{ phone: string }>();
  const { token } = theme.useToken();
  const { message } = AntApp.useApp();

  const items = useMemo(() => {
    const out: { key: ConsoleTab; icon: ReactNode; label: string }[] = [];
    const platform = isPlatformAdmin(session.role);
    const inTenant = (session.tenantId || 0) > 0;

    if (platform && !inTenant) {
      out.push({ key: "platform", icon: <BankOutlined />, label: "平台管理" });
      return out;
    }

    if (!inTenant) return out;

    if (platform) {
      out.push({ key: "platform", icon: <BankOutlined />, label: "平台管理" });
    }

    const ent = (p: string) => hasEntitlement(entitlements, p);
    const companyAdmin = isCompanyAdmin(session.role) || platform;

    if (ent("发布模块") || ent("写入模块") || ent("读取模块")) {
      out.push({ key: "generate", icon: <ThunderboltOutlined />, label: "生成与发布" });
    }
    if (ent("读取模块")) {
      out.push({ key: "modules", icon: <AppstoreOutlined />, label: "模块管理" });
    }
    if (companyAdmin && ent("数据同步")) {
      out.push({ key: "sync", icon: <CloudSyncOutlined />, label: "数据同步" });
    }
    if (ent("读取模块")) {
      out.push({ key: "agent", icon: <ApiOutlined />, label: "智能体胶囊" });
    }
    if (ent("管理智能体")) {
      out.push({ key: "roles", icon: <KeyOutlined />, label: "角色管理" });
      out.push({ key: "agents", icon: <RobotOutlined />, label: "智能体账号" });
    }
    if (companyAdmin && ent("管理组织")) {
      out.push({ key: "orgs", icon: <ApartmentOutlined />, label: "组织管理" });
    }
    if (companyAdmin && ent("邀请成员")) {
      out.push({ key: "invites", icon: <UserAddOutlined />, label: "邀请加入" });
      out.push({ key: "members", icon: <TeamOutlined />, label: "成员管理" });
    }
    if (ent("查看审计")) {
      out.push({ key: "audit", icon: <AuditOutlined />, label: "审计" });
    }
    return out;
  }, [session, entitlements]);

  return (
    <Layout className="console-root" style={{ minHeight: "100vh" }}>
      <Sider
        collapsible
        collapsed={collapsed}
        trigger={null}
        width={232}
        className="console-sider"
        theme="light"
      >
        <div className={`console-brand ${collapsed ? "is-collapsed" : ""}`}>
          <span className="console-brand-mark">宇</span>
          {!collapsed && (
            <div className="console-brand-text">
              <strong>宇信达智建</strong>
              <span>{isPlatformAdmin(session.role) ? "平台超管工作台" : "AI 建站控制台"}</span>
            </div>
          )}
        </div>
        <Menu
          mode="inline"
          selectedKeys={[tab]}
          items={items}
          onClick={({ key }) => onTabChange(key as ConsoleTab)}
          style={{ borderInlineEnd: 0, padding: "8px 8px 24px" }}
        />
      </Sider>
      <Layout>
        <Header className="console-header" style={{ background: token.colorBgContainer }}>
          <Space size="middle">
            <Button
              type="text"
              icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
              onClick={() => setCollapsed((v) => !v)}
            />
            <Typography.Title level={4} style={{ margin: 0 }}>
              {TAB_TITLES[tab] || "控制台"}
            </Typography.Title>
          </Space>
          <Space size="middle" wrap>
            <Space size={8}>
              <Avatar size="small" icon={<UserOutlined />} style={{ background: token.colorPrimary }} />
              <span className="console-user">{session.displayName || session.username}</span>
              {session.username ? (
                <Typography.Text type="secondary" code style={{ fontSize: 12 }}>
                  {session.username}
                </Typography.Text>
              ) : null}
              {session.phone ? (
                <Tag icon={<MobileOutlined />}>{session.phone}</Tag>
              ) : (
                <Tag>未绑手机</Tag>
              )}
              <Tag color="green">{roleLabel(session.role || "管理员")}</Tag>
              {isPlatformAdmin(session.role) && session.tenantId > 0 ? (
                <>
                  <Tag color="orange">管理：{session.tenantName || `公司 #${session.tenantId}`}</Tag>
                  <Button
                    size="small"
                    icon={<ArrowLeftOutlined />}
                    loading={exitTenantBusy}
                    onClick={async () => {
                      setExitTenantBusy(true);
                      try {
                        const next = await exitPlatformTenant(session);
                        saveSession(next);
                        onSession?.(next);
                        onTabChange("platform");
                        message.success("已回到平台工作台");
                      } catch (e: any) {
                        message.error(e.message || String(e));
                      } finally {
                        setExitTenantBusy(false);
                      }
                    }}
                  >
                    返回平台工作台
                  </Button>
                </>
              ) : session.tenantId > 0 ? (
                <Tag>公司 #{session.tenantId}</Tag>
              ) : null}
            </Space>
            <Button
              icon={<MobileOutlined />}
              onClick={() => {
                phoneForm.setFieldsValue({
                  phone: session.phone || "",
                });
                setPhoneOpen(true);
              }}
            >
              {session.phone ? "更换手机" : "绑定手机"}
            </Button>
            <Button
              icon={<KeyOutlined />}
              onClick={() => {
                pwdForm.resetFields();
                setPwdOpen(true);
              }}
            >
              修改密码
            </Button>
            <Button onClick={onOpenApp} disabled={busy}>
              打开模块
            </Button>
            <Button icon={<LogoutOutlined />} onClick={onLogout}>
              退出
            </Button>
          </Space>
        </Header>
        <Content className="console-content">
          {banner}
          <div className="console-panel">{children}</div>
        </Content>
      </Layout>

      <Modal
        title="修改密码"
        open={pwdOpen}
        onCancel={() => setPwdOpen(false)}
        confirmLoading={pwdBusy}
        onOk={async () => {
          const v = await pwdForm.validateFields();
          setPwdBusy(true);
          try {
            await changePassword(session, v.old_password, v.new_password);
            message.success("密码已更新");
            setPwdOpen(false);
            pwdForm.resetFields();
          } catch (e: any) {
            message.error(e.message || String(e));
          } finally {
            setPwdBusy(false);
          }
        }}
        destroyOnHidden
      >
        <Form form={pwdForm} layout="vertical">
          <Typography.Paragraph type="secondary">
            账号 <Typography.Text code>{session.username}</Typography.Text> 为系统分配、不可更改；仅可修改密码。
            绑定手机后也可用手机号 + 密码登录。
          </Typography.Paragraph>
          <Form.Item
            name="old_password"
            label="当前密码"
            rules={[{ required: true, message: "请输入当前密码" }]}
          >
            <Input.Password autoComplete="current-password" />
          </Form.Item>
          <Form.Item
            name="new_password"
            label="新密码"
            rules={[
              { required: true, message: "请输入新密码" },
              { min: 6, message: "至少 6 位" },
            ]}
          >
            <Input.Password autoComplete="new-password" />
          </Form.Item>
          <Form.Item
            name="confirm"
            label="确认新密码"
            dependencies={["new_password"]}
            rules={[
              { required: true, message: "请再次输入" },
              ({ getFieldValue }) => ({
                validator(_, value) {
                  if (!value || getFieldValue("new_password") === value) return Promise.resolve();
                  return Promise.reject(new Error("两次输入不一致"));
                },
              }),
            ]}
          >
            <Input.Password autoComplete="new-password" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={session.phone ? "更换手机号" : "绑定手机号"}
        open={phoneOpen}
        onCancel={() => setPhoneOpen(false)}
        confirmLoading={phoneBusy}
        onOk={async () => {
          const v = await phoneForm.validateFields();
          setPhoneBusy(true);
          try {
            const phone = (v.phone || "").trim();
            const res = await bindPhone(session, phone);
            const next = {
              ...session,
              phone: res.phone || undefined,
              usernameLoginDisabled: !!res.username_login_disabled,
            };
            saveSession(next);
            onSession?.(next);
            message.success(res.phone ? `已绑定 ${res.phone}` : "已更新");
            setPhoneOpen(false);
          } catch (e: any) {
            message.error(e.message || String(e));
          } finally {
            setPhoneBusy(false);
          }
        }}
        destroyOnHidden
      >
        <Form form={phoneForm} layout="vertical">
          <Typography.Paragraph type="secondary">
            绑定后可用手机号+密码或短信登录。有 License 期限控制时也可用用户名登录。
          </Typography.Paragraph>
          <Form.Item
            name="phone"
            label="手机号"
            rules={[
              {
                validator: async (_, value) => {
                  const s = String(value || "").trim();
                  if (!s) return;
                  if (!/^1[3-9]\d{9}$/.test(s) && !/^\+?86\s*1[3-9]\d{9}$/.test(s.replace(/\s/g, ""))) {
                    throw new Error("请输入 11 位大陆手机号");
                  }
                },
              },
            ]}
          >
            <Input placeholder="例如 13800138000" maxLength={20} allowClear />
          </Form.Item>
        </Form>
      </Modal>
    </Layout>
  );
}
