import { useState } from 'react';
import { Card, Button, Table, Tag, Popconfirm, Modal, Input, Space, message } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, ApartmentOutlined } from '@ant-design/icons';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  listUsers,
  createUser,
  updateUser,
  deleteUser,
  resetUserPassword,
  type UserListItem,
  type CreateUserPayload,
  type UpdateUserPayload,
} from '../api/users';
import { UserFormDrawer } from '../components/users/UserFormDrawer';
import { CustomerAccessModal } from '../components/users/CustomerAccessModal';
import { useAppInfo } from '../hooks/useAppInfo';

type DrawerMode = { kind: 'create' } | { kind: 'edit'; user: UserListItem };

export function UsersPage() {
  const qc = useQueryClient();
  const { isAdmin: isAdminMode } = useAppInfo();
  const [drawerMode, setDrawerMode] = useState<DrawerMode | null>(null);
  const [drawerError, setDrawerError] = useState<string | null>(null);
  const [resetTarget, setResetTarget] = useState<UserListItem | null>(null);
  const [resetValue, setResetValue] = useState('');
  const [accessTarget, setAccessTarget] = useState<UserListItem | null>(null);

  const { data: users = [], isLoading } = useQuery({
    queryKey: ['admin', 'users'],
    queryFn: listUsers,
  });

  const invalidate = () => qc.invalidateQueries({ queryKey: ['admin', 'users'] });

  const createMut = useMutation({
    mutationFn: (payload: CreateUserPayload) => createUser(payload),
    onSuccess: () => {
      message.success('User created');
      setDrawerMode(null);
      setDrawerError(null);
      invalidate();
    },
    onError: (err: unknown) => setDrawerError(errorMessage(err)),
  });

  const updateMut = useMutation({
    mutationFn: ({ id, payload }: { id: string; payload: UpdateUserPayload }) => updateUser(id, payload),
    onSuccess: () => {
      message.success('User updated');
      setDrawerMode(null);
      setDrawerError(null);
      invalidate();
    },
    onError: (err: unknown) => setDrawerError(errorMessage(err)),
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteUser(id),
    onSuccess: () => {
      message.success('User deleted');
      invalidate();
    },
    onError: (err: unknown) => message.error(errorMessage(err)),
  });

  const resetMut = useMutation({
    mutationFn: ({ id, newPassword }: { id: string; newPassword: string }) =>
      resetUserPassword(id, newPassword),
    onSuccess: () => {
      message.success('Password reset');
      setResetTarget(null);
      setResetValue('');
    },
    onError: (err: unknown) => message.error(errorMessage(err)),
  });

  const handleSubmit = async (values: CreateUserPayload | UpdateUserPayload) => {
    setDrawerError(null);
    if (drawerMode?.kind === 'edit') {
      await updateMut.mutateAsync({ id: drawerMode.user.id, payload: values as UpdateUserPayload });
    } else {
      await createMut.mutateAsync(values as CreateUserPayload);
    }
  };

  const columns: ColumnsType<UserListItem> = [
    { title: 'Email', dataIndex: 'email', key: 'email' },
    { title: 'Name', dataIndex: 'displayName', key: 'displayName' },
    {
      title: 'Roles',
      dataIndex: 'roles',
      key: 'roles',
      render: (roles: string[]) =>
        roles.length === 0
          ? <Tag>User</Tag>
          : roles.map((r) => <Tag color={r === 'Admin' ? 'blue' : undefined} key={r}>{r}</Tag>),
    },
    {
      title: 'Active',
      dataIndex: 'isActive',
      key: 'isActive',
      render: (active: boolean) => active ? <Tag color="green">Active</Tag> : <Tag color="red">Disabled</Tag>,
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'createdAt',
      render: (v: string) => new Date(v).toLocaleString(),
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_, user) => (
        <Space>
          <Button
            size="small"
            icon={<EditOutlined />}
            onClick={() => { setDrawerError(null); setDrawerMode({ kind: 'edit', user }); }}
          >
            Edit
          </Button>
          {isAdminMode && user.roles.includes('RestrictedAdmin') && (
            <Button
              size="small"
              icon={<ApartmentOutlined />}
              onClick={() => setAccessTarget(user)}
            >
              Customer access
            </Button>
          )}
          <Button
            size="small"
            icon={<KeyOutlined />}
            onClick={() => { setResetValue(''); setResetTarget(user); }}
          >
            Reset password
          </Button>
          <Popconfirm
            title={`Delete ${user.email}?`}
            okText="Delete"
            okButtonProps={{ danger: true }}
            onConfirm={() => deleteMut.mutate(user.id)}
          >
            <Button size="small" danger icon={<DeleteOutlined />}>Delete</Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <Card
      title="Users"
      extra={
        <Button
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => { setDrawerError(null); setDrawerMode({ kind: 'create' }); }}
        >
          New user
        </Button>
      }
    >
      <Table<UserListItem>
        rowKey="id"
        columns={columns}
        dataSource={users}
        loading={isLoading}
        pagination={{ pageSize: 20 }}
      />

      <UserFormDrawer
        open={drawerMode !== null}
        mode={drawerMode}
        submitting={createMut.isPending || updateMut.isPending}
        error={drawerError}
        onClose={() => { setDrawerMode(null); setDrawerError(null); }}
        onSubmit={handleSubmit}
      />

      <Modal
        title={resetTarget ? `Reset password for ${resetTarget.email}` : 'Reset password'}
        open={resetTarget !== null}
        confirmLoading={resetMut.isPending}
        onCancel={() => { setResetTarget(null); setResetValue(''); }}
        onOk={() => resetTarget && resetMut.mutate({ id: resetTarget.id, newPassword: resetValue })}
        okText="Reset"
        okButtonProps={{ disabled: resetValue.length < 8 }}
      >
        <Input.Password
          placeholder="New password (min 8 chars, upper + lower + digit)"
          value={resetValue}
          onChange={(e) => setResetValue(e.target.value)}
          autoComplete="new-password"
        />
      </Modal>

      <CustomerAccessModal
        open={accessTarget !== null}
        user={accessTarget}
        onClose={() => setAccessTarget(null)}
      />
    </Card>
  );
}

function errorMessage(err: unknown): string {
  if (typeof err === 'object' && err !== null && 'response' in err) {
    const data = (err as { response?: { data?: { error?: string; errors?: string[] } } }).response?.data;
    if (data?.error) return data.error;
    if (data?.errors?.length) return data.errors.join('; ');
  }
  return 'Request failed.';
}
