import { useEffect, useMemo, useState } from 'react';
import {
  Alert,
  Button,
  Card,
  Checkbox,
  Col,
  Form,
  Row,
  Select,
  Space,
  Tabs,
  Tag,
  Typography,
  message,
} from 'antd';
import {
  HQ_ADMIN_ROLES,
  HQ_PERMISSION_CATALOG,
  computeHqEffectivePermissionKeys,
  type HqPermissionKey,
} from '@dukang/shared-types';
import { request, type HqProfile } from '../lib/api';

type RolePermRes = { role: string; permissionKeys: string[] };
type AccountOption = { id: string; name: string; phone: string; loginName: string | null; adminRole: string };
type AccountPermRes = {
  account: AccountOption;
  permissionKeys: string[];
  rolePermissionKeys: string[];
  grantKeys?: string[];
  denyKeys?: string[];
  userPermissionKeys: string[];
  effectivePermissionKeys: string[];
};

const ROLE_LABELS = Object.fromEntries(HQ_ADMIN_ROLES.map((r) => [r.value, r.label]));

const CATALOG_GROUPS = [...new Set(HQ_PERMISSION_CATALOG.map((p) => p.group ?? '其他'))];

function groupColSpan(itemCount: number): number {
  if (itemCount <= 2) return 12;
  if (itemCount === 3) return 8;
  if (itemCount === 4) return 6;
  return 8;
}

function PermissionChecklist({
  value,
  onChange,
  disabled,
  roleKeys,
  grantKeys,
}: {
  value: string[];
  onChange: (keys: string[]) => void;
  disabled?: boolean;
  roleKeys?: string[];
  grantKeys?: string[];
}) {
  const roleSet = new Set(roleKeys ?? []);
  const grantSet = new Set(grantKeys ?? []);
  return (
    <Checkbox.Group
      style={{ width: '100%' }}
      value={value}
      disabled={disabled}
      onChange={(checked) => onChange(checked as string[])}
    >
      {CATALOG_GROUPS.map((group) => {
        const items = HQ_PERMISSION_CATALOG.filter((p) => (p.group ?? '其他') === group);
        const span = groupColSpan(items.length);
        const compact = items.length <= 3;
        return (
          <div
            key={group}
            style={{
              marginBottom: 16,
              padding: '12px 16px',
              background: '#fafafa',
              borderRadius: 8,
              border: '1px solid #f0f0f0',
            }}
          >
            <Typography.Text strong style={{ display: 'block', marginBottom: 10 }}>
              {group}
            </Typography.Text>
            {compact ? (
              <Space size={[24, 8]} wrap>
                {items.map((item) => (
                  <Checkbox key={item.key} value={item.key}>
                    {item.label}
                    {roleSet.has(item.key) && !value.includes(item.key) ? (
                      <Tag style={{ marginLeft: 6 }} color="red">已撤销</Tag>
                    ) : grantSet.has(item.key) ? (
                      <Tag style={{ marginLeft: 6 }} color="orange">追加</Tag>
                    ) : roleSet.has(item.key) ? (
                      <Tag style={{ marginLeft: 6 }} color="blue">角色</Tag>
                    ) : null}
                  </Checkbox>
                ))}
              </Space>
            ) : (
              <Row gutter={[12, 10]}>
                {items.map((item) => (
                  <Col key={item.key} xs={24} sm={12} md={span}>
                    <Checkbox value={item.key}>
                      {item.label}
                      {roleSet.has(item.key) && !value.includes(item.key) ? (
                        <Tag style={{ marginLeft: 6 }} color="red">已撤销</Tag>
                      ) : grantSet.has(item.key) ? (
                        <Tag style={{ marginLeft: 6 }} color="orange">追加</Tag>
                      ) : roleSet.has(item.key) ? (
                        <Tag style={{ marginLeft: 6 }} color="blue">角色</Tag>
                      ) : null}
                    </Checkbox>
                  </Col>
                ))}
              </Row>
            )}
          </div>
        );
      })}
    </Checkbox.Group>
  );
}

function splitAccountOverrides(roleKeys: string[], effectiveKeys: string[]) {
  const roleSet = new Set(roleKeys);
  const effectiveSet = new Set(effectiveKeys);
  const grantKeys = effectiveKeys.filter((k) => !roleSet.has(k));
  const denyKeys = roleKeys.filter((k) => !effectiveSet.has(k));
  return { grantKeys, denyKeys };
}

export default function HqPermissionsPage() {
  const [profile, setProfile] = useState<HqProfile | null>(null);
  const [role, setRole] = useState<string>('OPS');
  const [roleKeys, setRoleKeys] = useState<string[]>([]);
  const [roleLoading, setRoleLoading] = useState(false);
  const [roleSaving, setRoleSaving] = useState(false);

  const [accounts, setAccounts] = useState<AccountOption[]>([]);
  const [accountId, setAccountId] = useState<string>();
  const [accountKeys, setAccountKeys] = useState<string[]>([]);
  const [roleInheritedKeys, setRoleInheritedKeys] = useState<string[]>([]);
  const [grantKeys, setGrantKeys] = useState<string[]>([]);
  const [denyKeys, setDenyKeys] = useState<string[]>([]);
  const [accountLoading, setAccountLoading] = useState(false);
  const [accountSaving, setAccountSaving] = useState(false);

  const selectedAccount = useMemo(
    () => accounts.find((a) => a.id === accountId),
    [accounts, accountId],
  );
  const selectedIsSuperAdmin = selectedAccount?.adminRole === 'SUPER_ADMIN';

  const previewEffectiveKeys = useMemo(
    () => computeHqEffectivePermissionKeys(roleInheritedKeys, grantKeys, denyKeys),
    [roleInheritedKeys, grantKeys, denyKeys],
  );

  const isSuperAdmin = profile?.adminRole === 'SUPER_ADMIN';

  useEffect(() => {
    request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
  }, []);

  useEffect(() => {
    if (!isSuperAdmin) return;
    request<{ items: AccountOption[] }>('/admin/hq-accounts?page=1&pageSize=100')
      .then((res) => setAccounts(res.items))
      .catch(() => {});
  }, [isSuperAdmin]);

  useEffect(() => {
    if (!isSuperAdmin || !role) return;
    setRoleLoading(true);
    request<RolePermRes>(`/admin/hq-permissions/roles/${role}`)
      .then((res) => setRoleKeys(res.permissionKeys))
      .finally(() => setRoleLoading(false));
  }, [isSuperAdmin, role]);

  useEffect(() => {
    if (!isSuperAdmin || !accountId) return;
    setAccountLoading(true);
    request<AccountPermRes>(`/admin/hq-permissions/accounts/${accountId}`)
      .then((res) => {
        setGrantKeys(res.grantKeys ?? res.userPermissionKeys ?? []);
        setDenyKeys(res.denyKeys ?? []);
        setRoleInheritedKeys(res.rolePermissionKeys);
        setAccountKeys(res.effectivePermissionKeys);
      })
      .finally(() => setAccountLoading(false));
  }, [isSuperAdmin, accountId]);

  async function saveRolePermissions() {
    setRoleSaving(true);
    try {
      const res = await request<RolePermRes>(`/admin/hq-permissions/roles/${role}`, {
        method: 'PUT',
        body: JSON.stringify({ permissionKeys: roleKeys }),
      });
      setRoleKeys(res.permissionKeys);
      message.success('角色权限已保存');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败');
    } finally {
      setRoleSaving(false);
    }
  }

  async function saveAccountPermissions() {
    if (!accountId) return;
    setAccountSaving(true);
    try {
      const res = await request<AccountPermRes>(`/admin/hq-permissions/accounts/${accountId}`, {
        method: 'PUT',
        body: JSON.stringify({ grantKeys, denyKeys }),
      });
      setGrantKeys(res.grantKeys ?? res.userPermissionKeys ?? []);
      setDenyKeys(res.denyKeys ?? []);
      setRoleInheritedKeys(res.rolePermissionKeys);
      setAccountKeys(res.effectivePermissionKeys);
      message.success('用户权限已保存');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败');
    } finally {
      setAccountSaving(false);
    }
  }

  if (!isSuperAdmin) {
    return (
      <div>
        <Typography.Title level={4}>权限分配</Typography.Title>
        <Alert type="warning" showIcon message="仅超级管理员可配置权限" />
      </div>
    );
  }

  return (
    <div>
      <Typography.Title level={4}>权限分配</Typography.Title>
      <Typography.Paragraph type="secondary">
        按角色配置基础权限；按用户可追加或撤销。最终生效权限 =（角色权限 ∪ 追加）− 撤销。
        超级管理员默认拥有除「危险操作」外的全部权限；删除用户/订单/城市需在「按用户分配」中单独勾选（默认均无）。
        运营/财务默认可删除门店分类；城市门店服务可新增分类，不可删除。
        「系统设置」已拆分为各配置分组；「财务」对应门店/合伙人/酒厂账单。
      </Typography.Paragraph>

      <Tabs
        items={[
          {
            key: 'role',
            label: '按角色分配',
            children: (
              <Card loading={roleLoading}>
                <Form layout="inline" style={{ marginBottom: 16 }}>
                  <Form.Item label="角色">
                    <Select
                      style={{ width: 180 }}
                      value={role}
                      onChange={setRole}
                      options={HQ_ADMIN_ROLES.map((r) => ({
                        value: r.value,
                        label: r.label,
                        disabled: r.value === 'SUPER_ADMIN',
                      }))}
                    />
                  </Form.Item>
                </Form>
                {role === 'SUPER_ADMIN' ? (
                  <Alert
                    type="info"
                    showIcon
                    message="超级管理员基础权限固定（不含危险操作）。删除用户/订单/城市请到「按用户分配」为具体账号勾选。"
                  />
                ) : (
                  <>
                    <PermissionChecklist value={roleKeys} onChange={setRoleKeys} />
                    <div style={{ marginTop: 16 }}>
                      <Button type="primary" loading={roleSaving} onClick={() => void saveRolePermissions()}>
                        保存角色权限
                      </Button>
                    </div>
                  </>
                )}
              </Card>
            ),
          },
          {
            key: 'user',
            label: '按用户分配',
            children: (
              <Card loading={accountLoading}>
                <Form layout="inline" style={{ marginBottom: 16 }}>
                  <Form.Item label="HQ 账户">
                    <Select
                      showSearch
                      allowClear
                      placeholder="选择账户"
                      style={{ width: 320 }}
                      value={accountId}
                      onChange={setAccountId}
                      optionFilterProp="label"
                      options={accounts.map((a) => ({
                        value: a.id,
                        label: `${a.name} · ${a.loginName || a.phone} · ${ROLE_LABELS[a.adminRole] || a.adminRole}`,
                      }))}
                    />
                  </Form.Item>
                </Form>
                {!accountId ? (
                  <Alert type="info" showIcon message="请先选择要配置的 HQ 账户" />
                ) : (
                  <>
                    <Typography.Paragraph type="secondary">
                      勾选表示该账号最终拥有该权限。取消角色已有项即为撤销；勾选角色没有的项即为追加。
                      切换角色会清空账号级追加/撤销。
                    </Typography.Paragraph>
                    <PermissionChecklist
                      value={accountKeys}
                      roleKeys={roleInheritedKeys}
                      grantKeys={grantKeys}
                      disabled={selectedIsSuperAdmin}
                      onChange={(nextEffective) => {
                        if (selectedIsSuperAdmin) return;
                        const next = splitAccountOverrides(roleInheritedKeys, nextEffective);
                        setGrantKeys(next.grantKeys);
                        setDenyKeys(next.denyKeys);
                        setAccountKeys(nextEffective);
                      }}
                    />
                    {selectedIsSuperAdmin ? (
                      <Alert
                        type="info"
                        showIcon
                        style={{ marginTop: 12 }}
                        message="超级管理员基础权限不可撤销。危险操作请到下方以外的方式：当前勾选仅展示生效权限。"
                      />
                    ) : null}
                    <div style={{ marginTop: 12 }}>
                      <span style={{ marginRight: 8 }}>合并生效：</span>
                      <Space wrap size={[4, 4]}>
                        {previewEffectiveKeys.map((key) => {
                          const item = HQ_PERMISSION_CATALOG.find((p) => p.key === (key as HqPermissionKey));
                          return (
                            <Tag key={key}>
                              {item?.label || key}
                            </Tag>
                          );
                        })}
                      </Space>
                    </div>
                    <div style={{ marginTop: 16 }}>
                      <Button
                        type="primary"
                        loading={accountSaving}
                        disabled={selectedIsSuperAdmin}
                        onClick={() => void saveAccountPermissions()}
                      >
                        保存用户权限
                      </Button>
                    </div>
                  </>
                )}
              </Card>
            ),
          },
        ]}
      />
    </div>
  );
}
