import { Button, Card, Checkbox, Col, Empty, Input, Row, Space, Table, Tag, Typography, App } from 'antd';
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { listRoles, listUserRoles, listUsers, saveUserRoles } from "@/api";
import { SaveOutlined, SearchOutlined, TeamOutlined, UserOutlined } from "@ant-design/icons";
import type { SysRole, SysUser } from "@/types";
import PageHeader from "@/components/shared/PageHeader";

const { Text } = Typography;

export default function UserRoleBinding() {
  const { message } = App.useApp();
  const { t } = useTranslation();
  const [users, setUsers] = useState<SysUser[]>([]);
  const [roles, setRoles] = useState<SysRole[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [loadingRoles, setLoadingRoles] = useState(false);
  const [saving, setSaving] = useState(false);
  const [selectedUserId, setSelectedUserId] = useState<number | null>(null);
  const [checkedRoleIds, setCheckedRoleIds] = useState<number[]>([]);
  const [searchText, setSearchText] = useState("");

  const selectedUser = useMemo(() => users.find((user) => user.userId === selectedUserId) || null, [users, selectedUserId]);

  const loadUsers = async () => {
    setLoadingUsers(true);
    try {
      const list = await listUsers();
      setUsers(list || []);
    } finally {
      setLoadingUsers(false);
    }
  };

  const loadRoles = async () => {
    setLoadingRoles(true);
    try {
      const list = await listRoles();
      setRoles(list || []);
    } finally {
      setLoadingRoles(false);
    }
  };

  const loadUserRoles = async (userId: number) => {
    try {
      const list = await listUserRoles(userId);
      setCheckedRoleIds(list || []);
    } catch {
      setCheckedRoleIds([]);
    }
  };

  useEffect(() => {
    loadUsers();
    loadRoles();
  }, []);

  useEffect(() => {
    if (selectedUserId) {
      loadUserRoles(selectedUserId);
    } else {
      setCheckedRoleIds([]);
    }
  }, [selectedUserId]);

  const filteredUsers = useMemo(() => {
    if (!searchText) return users;
    const lower = searchText.toLowerCase();
    return users.filter(
      (user) => user.username.toLowerCase().includes(lower) || user.displayName.toLowerCase().includes(lower)
    );
  }, [users, searchText]);

  const handleSave = async () => {
    if (!selectedUserId) {
      message.warning(t("userRole.selectUser"));
      return;
    }
    setSaving(true);
    try {
      await saveUserRoles(selectedUserId, checkedRoleIds);
      message.success(t("common.success"));
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="app-page">
      <PageHeader
        title={t("userRole.title")}
        subtitle={t("userRole.subtitle")}
      />

      <div className="app-page__page-actions">
        <Button type="primary" icon={<SaveOutlined aria-hidden="true" />} onClick={handleSave} loading={saving} disabled={!selectedUserId}>
          {saving ? t("common.loading") : t("common.save")}
        </Button>
      </div>

      <Row gutter={24} className="app-page__split" style={{ height: "calc(100vh - 180px)" }}>
        <Col xs={24} lg={12} style={{ height: "100%" }}>
          <Card title={<Space><UserOutlined aria-hidden="true" /><span>{t("userRole.userList")}</span></Space>} className="app-page__panel-card full-height-card">
            <div className="mb-4">
              <Input
                placeholder={t("userRole.searchUser")}
                prefix={<SearchOutlined aria-hidden="true" className="text-gray-400" />}
                value={searchText}
                onChange={(event) => setSearchText(event.target.value)}
                allowClear
                aria-label={t("userRole.searchUser")}
              />
            </div>
            <div style={{ height: "calc(100% - 60px)", overflowY: "auto" }}>
              <Table
                rowKey="userId"
                size="middle"
                loading={loadingUsers}
                dataSource={filteredUsers}
                rowSelection={{
                  type: "radio",
                  selectedRowKeys: selectedUserId ? [selectedUserId] : [],
                  onChange: (keys) => setSelectedUserId(keys[0] as number)
                }}
                onRow={(record) => ({
                  onClick: () => setSelectedUserId(record.userId),
                  className: "cursor-pointer"
                })}
                pagination={{ pageSize: 10, showTotal: (total) => t("common.total", { total }) }}
                columns={[
                  {
                    title: t("users.userInfo"),
                    key: "user",
                    render: (_: unknown, record: SysUser) => (
                      <div className="min-w-0">
                        <div style={{ fontWeight: 500 }} className="truncate">{record.displayName}</div>
                        <div style={{ fontSize: 12, color: "#8c8c8c" }} className="truncate">@{record.username}</div>
                      </div>
                    )
                  },
                  {
                    title: t("common.status"),
                    dataIndex: "status",
                    width: 80,
                    render: (value: number) => (value === 1 ? <Tag color="green" className="m-0">Enabled</Tag> : <Tag className="m-0">Disabled</Tag>)
                  }
                ]}
              />
            </div>
          </Card>
        </Col>

        <Col xs={24} lg={12} style={{ height: "100%" }}>
          <Card
            title={<Space><TeamOutlined aria-hidden="true" /><span>{t("userRole.grantRoles")}</span></Space>}
            className="app-page__panel-card full-height-card"
            extra={selectedUser ? <Tag color="blue">{t("userRole.editing")}: {selectedUser.displayName}</Tag> : null}
          >
            {selectedUserId ? (
              <div style={{ padding: "8px 0", height: "100%", overflowY: "auto" }}>
                <Checkbox.Group style={{ width: "100%" }} value={checkedRoleIds} onChange={(values) => setCheckedRoleIds(values as number[])} disabled={loadingRoles}>
                  <Row gutter={[16, 16]}>
                    {roles.map((role) => (
                      <Col key={role.roleId} span={12}>
                        <Checkbox value={role.roleId} className="w-full">
                          <Space direction="vertical" size={0}>
                            <span style={{ fontWeight: 500 }}>{role.roleName}</span>
                            <Text type="secondary" style={{ fontSize: 12 }} className="tabular-nums">
                              {role.roleCode}
                            </Text>
                          </Space>
                        </Checkbox>
                      </Col>
                    ))}
                  </Row>
                </Checkbox.Group>
                {!roles.length && !loadingRoles && <Empty description="No roles available" />}
              </div>
            ) : (
              <div className="flex flex-col items-center justify-center py-20 bg-gray-50 rounded-lg border border-dashed border-gray-200">
                <UserOutlined style={{ fontSize: 40, color: "#bfbfbf", marginBottom: 16 }} aria-hidden="true" />
                <Text type="secondary">{t("userRole.selectUser")}</Text>
              </div>
            )}
          </Card>
        </Col>
      </Row>
    </div>
  );
}