import XinTable from "@/components/XinTable";
import type {XinTableColumn} from "@/components/XinTable/typings.ts";
import {Button, Card, type CardProps, Col, message, Row, Switch, Table, type TableProps, Tag, Tooltip, Tree, type TreeProps, Typography} from "antd";
import {type RuleFieldsList, rulesList, setRule, statusRole, users as usersApi} from "@/api/system/sys_role";
import type {ISysRole} from "@/domain/iSysRole.ts";
import React, {useEffect, useRef, useState} from "react";
import type ISysUser from "@/domain/iSysUser.ts";
import {KeyOutlined, SaveOutlined, SmileOutlined, TeamOutlined} from "@ant-design/icons";
import { useTranslation } from "react-i18next";
import { isArray } from "lodash";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";

dayjs.extend(relativeTime);

const { Title, Text } = Typography;

const Role = () => {
  const {t} = useTranslation();
  // 状态管理
  const [selectedRoleId, setSelectedRoleId] = useState<number | undefined>();
  const [activeTab, setActiveTab] = useState('users');
  const [roleUsers, setRoleUsers] = useState<ISysUser[]>([]);
  const [roleUsersTotal, setRoleUsersTotal] = useState<number>(0);
  const [isLoadingUsers, setIsLoadingUsers] = useState<boolean>(false);
  const [ruleFields, setRuleFields] = useState<RuleFieldsList[]>([]);
  const [checkedRuleKeys, setCheckedRuleKeys] = useState<React.Key[]>([]);
  const [isSavingRules, setIsSavingRules] = useState<boolean>(false);
  // 树展开状态
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  // 树引用
  const treeRef = useRef<any>(null);
  // Tab 配置
  const tabList: CardProps['tabList'] = [
    {
      key: "users",
      icon: <TeamOutlined />,
      label: t('system.role.tab.users'),
    },
    {
      key: "rules",
      icon: <KeyOutlined />,
      label: t('system.role.tab.rules')
    }
  ];
  // 角色表格列配置
  const roleColumns: XinTableColumn<ISysRole>[] = [
    {
      title: 'id',
      dataIndex: "id",
      valueType: "text",
      align: 'center',
      width: 80,
      hideInForm: true
    },
    {
      title: t('system.role.table.roleName'),
      dataIndex: "name",
      valueType: "text",
      align: "center",
      required: true,
      colProps: {span: 8},
      rules: [{ required: true, message: t('system.role.table.roleName.required') }],
      render: (value: any, record: ISysRole) => (
        <>
          <Tooltip title={record.description}>
            <Tag variant="filled" color="blue">{value}</Tag>
          </Tooltip>
        </>
      ),
    },
    {
      title: t('system.role.table.sort'),
      dataIndex: "sort",
      valueType: "digit",
      hideInSearch: true,
      align: "center",
      required: true,
      colProps: {span: 8},
      rules: [{ required: true, message: t('system.role.table.sort.required') }],
      render: (value: number) => <Tag variant="filled" color="purple">{value}</Tag>,
    },
    {
      title: t('system.role.table.userCount'),
      dataIndex: "countUser",
      valueType: "text",
      hideInForm: true,
      align: "center",
      render: (value: number) => <a><u>{value}{t('system.role.userTable.person')}</u></a>,
    },
    {
      title: t('system.role.table.status'),
      dataIndex: "status",
      valueType: "switch",
      align: "center",
      colProps: {span: 8},
      filters: [
        { text: t('system.role.table.status.disable'), value: 0 },
        { text: t('system.role.table.status.enable'), value: 1 },
      ],
      hideInSearch: true,
      required: true,
      rules: [{ required: true, message: t('system.role.table.status.required') }],
      render: (_, record: ISysRole) => (
        <Switch
          disabled={record.id === 1}
          checked={record.status === 1}
          checkedChildren={t('system.role.table.status.enable')}
          unCheckedChildren={t('system.role.table.status.disable')}
          onChange={async (_, event) => {
            event.stopPropagation();
            try {
              await statusRole(record.id!);
              message.success(t('system.role.message.statusUpdateSuccess'));
            } catch (error) {
              message.error(t('system.role.message.statusUpdateFailed'));
              console.error('Failed to update role status:', error);
            }
          }}
        />
      ),
    },
    {
      valueType: 'textarea',
      title: t('system.role.table.description'),
      dataIndex: 'description',
      colProps: {span: 24},
      hideInTable: true,
    },
    {
      title: t('system.role.table.createdAt'),
      hideInForm: true,
      hideInSearch: true,
      dataIndex: 'created_at',
      align: 'center',
      render: (value: string) => value ? dayjs(value).fromNow() : '-',
    },
    {
      title: t('system.role.table.updatedAt'),
      hideInForm: true,
      hideInSearch: true,
      dataIndex: 'updated_at',
      align: 'center',
      render: (value: string) => value ? dayjs(value).fromNow() : '-',
    },
  ];
  // 用户列表表格列配置
  const userColumns: TableProps<ISysUser>['columns'] = [
    {
      title: t('system.role.userTable.userId'),
      dataIndex: 'id',
      key: 'id',
      align: 'center',
      width: 80,
    },
    {
      title: t('system.role.userTable.username'),
      dataIndex: 'username',
      key: 'username',
      align: 'center',
    },
    {
      title: t('system.role.userTable.nickname'),
      dataIndex: 'nickname',
      key: 'nickname',
      align: 'center',
    },
    {
      title: t('system.role.userTable.email'),
      dataIndex: 'email',
      key: 'email',
      align: 'center',
      ellipsis: true,
    },
    {
      title: t('system.role.userTable.mobile'),
      dataIndex: 'mobile',
      key: 'mobile',
      align: 'center',
    },
    {
      title: t('system.role.userTable.status'),
      dataIndex: 'status',
      key: 'status',
      align: 'center',
      render: (value: number) => {
        const status = value === 0
          ? { color: 'error', text: t('system.role.userTable.status.banned') }
          : { color: 'success', text: t('system.role.userTable.status.normal') };
        return <Tag color={status.color}>{status.text}</Tag>;
      },
      width: 80,
    },
  ];
  // 获取角色用户列表
  const fetchRoleUsers = async (page: number = 1, pageSize: number = 10) => {
    if (!selectedRoleId) return;
    setIsLoadingUsers(true);
    try {
      const response = await usersApi(selectedRoleId, { page, pageSize });
      const { data, total } = response.data.data!;
      setRoleUsers(data);
      setRoleUsersTotal(total);
    } finally {
      setIsLoadingUsers(false);
    }
  }

  useEffect(() => {
    rulesList().then(response => {
      setRuleFields(response.data.data!);
    });
   }, []);

  // 当selectedRoleId变化时，重新获取用户列表
  useEffect(() => { fetchRoleUsers(1, 10) }, [selectedRoleId]);

  // 事件处理函数
  const handleRoleSelect = (record: ISysRole) => {
    setSelectedRoleId(record.id!);
    // 回显当前角色的权限
    if (record.ruleIds && record.ruleIds.length > 0) {
      setCheckedRuleKeys(record.ruleIds);
    } else {
      setCheckedRuleKeys([]);
    }
  };

  // 渲染权限树节点
  const renderRuleTreeNode = (node: RuleFieldsList) => {
    if (node.local) {
      return (
        <>
          {t(node.local)} - <span style={{ color: '#00000040' }}>{node.title}</span>
        </>
      );
    }
    return <>{node.title}</>;
  };

  // 处理权限树勾选变化
  const handleRuleCheck: TreeProps['onCheck'] = (checkedKeys) => {
    if(isArray(checkedKeys)) {
      setCheckedRuleKeys(checkedKeys);
    }else {
      setCheckedRuleKeys(checkedKeys.checked);
    }
  };

  // 处理树展开状态变化
  const handleTreeExpand = (keys: React.Key[]) => {
    setExpandedKeys(keys);
  };

  // 获取所有节点的key
  const getAllNodeKeys = (nodes: RuleFieldsList[]): React.Key[] => {
    let keys: React.Key[] = [];
    nodes.forEach(node => {
      keys.push(node.key);
      if (node.children && node.children.length > 0) {
        keys = [...keys, ...getAllNodeKeys(node.children)];
      }
    });
    return keys;
  };

  // 展开全部节点
  const expandAll = () => {
    const allKeys = getAllNodeKeys(ruleFields);
    setExpandedKeys(allKeys);
  };

  // 折叠全部节点
  const collapseAll = () => {
    setExpandedKeys([]);
  };

  // 选择全部节点
  const selectAll = () => {
    const allKeys = getAllNodeKeys(ruleFields);
    setCheckedRuleKeys(allKeys);
  };

  // 取消选择全部节点
  const deselectAll = () => {
    setCheckedRuleKeys([]);
  };

  // 反选节点
  const invertSelection = () => {
    const allKeys = getAllNodeKeys(ruleFields);
    const currentCheckedSet = new Set(checkedRuleKeys);
    const invertedKeys = allKeys.filter(key => !currentCheckedSet.has(key));
    setCheckedRuleKeys(invertedKeys);
  };

  // 保存权限设置
  const handleSaveRules = async () => {
    if (!selectedRoleId) {
      message.warning(t('system.role.message.selectRoleFirst'));
      return;
    }
    setIsSavingRules(true);
    try {
      const ruleIds = checkedRuleKeys.map(key => Number(key));
      await setRule(selectedRoleId, ruleIds);
      message.success(t('system.role.message.rulesSaveSuccess'));
    } finally {
      setIsSavingRules(false);
    }
  }

  return (
    <>
      <div className={'mb-5'}>
        <Title level={3}>{t('system.role.page.title')}</Title>
        <Text type="secondary">{t('system.role.page.description')}</Text>
      </div>
      <Row gutter={[20, 20]}>
        {/* 角色列表 */}
        <Col xxl={14} lg={12} xs={24}>
          <XinTable<ISysRole>
            api="/system/role"
            accessName="system.role"
            columns={roleColumns}
            rowKey="id"
            searchShow={false}
            searchProps={false}
            scroll={{x: 800}}
            editShow={(row) => row.id !== 1}
            deleteShow={(row) => row.id !== 1}
            formProps={{
              grid: true,
              rowProps: { gutter: [20, 0] },
              layout: 'vertical'
            }}
            modalProps={{
              width: 800
            }}
            operateProps={{
              fixed: 'right'
            }}
            rowSelection={{
              type: 'radio',
              selectedRowKeys: selectedRoleId ? [selectedRoleId] : [],
              onChange: (_, rows) => handleRoleSelect(rows[0])
            }}
            onRow ={(record) => ({
              onClick: () => handleRoleSelect(record)
            })}
          />
        </Col>

        {/* 用户列表和权限管理 */}
        <Col xxl={10} lg={12} xs={24}>
          <Card
            tabList={tabList}
            onTabChange={setActiveTab}
            activeTabKey={activeTab}
            styles={{ body: { minHeight: '70vh' } }}
          >
            { selectedRoleId ? (
              activeTab === 'users' ? (
                <Table<ISysUser>
                  loading={isLoadingUsers}
                  dataSource={roleUsers}
                  bordered={true}
                  columns={userColumns}
                  size="small"
                  pagination={{
                    total: roleUsersTotal,
                    showSizeChanger: true,
                    onChange: fetchRoleUsers
                  }}
                  scroll={{x: 600}}
                />
              ) : (
                <>
                  <div style={{ height: '600px', overflow: 'auto', marginBottom: 12 }}>
                    <Tree
                      ref={treeRef}
                      checkable
                      treeData={ruleFields}
                      checkedKeys={checkedRuleKeys}
                      onCheck={handleRuleCheck}
                      titleRender={renderRuleTreeNode}
                      checkStrictly={true}
                      expandedKeys={expandedKeys}
                      onExpand={handleTreeExpand}
                    />
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <span style={{ color: '#666', fontSize: 12 }}>
                      {t('system.role.permission.selectedCount', { count: checkedRuleKeys.length })}
                    </span>
                    <Button size="small" onClick={expandAll}>{t('system.role.button.expandAll')}</Button>
                    <Button size="small" onClick={collapseAll}>{t('system.role.button.collapseAll')}</Button>
                    <Button size="small" onClick={selectAll}>{t('system.role.button.selectAll')}</Button>
                    <Button size="small" onClick={deselectAll}>{t('system.role.button.clearAll')}</Button>
                    <Button size="small" onClick={invertSelection}>{t('system.role.button.invertSelection')}</Button>
                    <Button
                      type="primary"
                      icon={<SaveOutlined />}
                      loading={isSavingRules}
                      onClick={handleSaveRules}
                      size="small"
                      disabled={selectedRoleId === 1}
                    >
                      {t('system.role.button.saveRules')}
                    </Button>
                  </div>
                </>
              )
            ) : (
              <div style={{ textAlign: 'center', color: '#00000040' }}>
                <SmileOutlined style={{ fontSize: 40, marginBottom: 12 }} />
                <p>{t('system.role.placeholder.selectRole')}</p>
              </div>
            )}
          </Card>
        </Col>
      </Row>
    </>
  );
}

export default Role;
