import React, { useState } from 'react';

import { useModalForm } from '@refinedev/antd';
import { type HttpError, type RedirectAction } from '@refinedev/core';

import { Button, Form, Input, Modal, Select, Space, Switch } from 'antd';
import { ReloadOutlined } from '@ant-design/icons';

import { useRoles } from '@/hooks/useRoles';
import { User } from '@/types';

import { UserSelect } from '../queries';

const generateApiKey = () => crypto.randomUUID();

type Props = {
  action: 'create' | 'edit';
  id?: number;
  redirect?: RedirectAction;
  onMutationSuccess?: () => void;
  onCancel?: () => void;
};

export const UserFormModal: React.FC<Props> = ({
  action,
  id,
  redirect,
  onCancel,
  onMutationSuccess,
}) => {
  const [isApiKey, setIsApiKey] = useState(false);
  const [usernameTouched, setUsernameTouched] = useState(false);

  // Fetch roles from backend using custom hook
  const { roleOptions, loading: rolesLoading } = useRoles();

  const { formProps, modalProps, onFinish, close, form } = useModalForm<
    User,
    HttpError,
    Partial<User>
  >({
    resource: 'user',
    action,
    id,
    defaultVisible: true,
    redirect,
    onMutationSuccess: () => {
      onMutationSuccess?.();
    },
    meta: {
      select: UserSelect,
    },
  });

  // fix react-query cache data type error
  if (
    formProps.initialValues?.roles &&
    typeof formProps.initialValues.roles === 'string'
  ) {
    formProps.initialValues.roles = JSON.parse(formProps.initialValues.roles);
  }

  // sync isApiKey state with form initial values
  React.useEffect(() => {
    if (formProps.initialValues?.isApiKey !== undefined) {
      setIsApiKey(formProps.initialValues.isApiKey);
    }
  }, [formProps.initialValues?.isApiKey]);

  const handleGenerateApiKey = () => {
    const newKey = generateApiKey();
    form.setFieldsValue({ apiKey: newKey });
  };

  const handleIsApiKeyChange = (checked: boolean) => {
    setIsApiKey(checked);
    if (checked && !form.getFieldValue('apiKey')) {
      handleGenerateApiKey();
    }
    if (checked) {
      form.setFieldsValue({ isActive: true });
    }
  };

  formProps.onFinish = (values) => {
    onFinish({ ...values, roles: JSON.stringify(values.roles) });
  };

  return (
    <Modal
      {...modalProps}
      width={560}
      onCancel={() => {
        if (onCancel) {
          onCancel();
          return;
        }
        //TODO: modalProps.onCancel expect an event so, I used close. Actually both of them are same.
        close();
      }}
      title={action === 'create' ? 'Create User' : 'Edit User'}
    >
      <Form {...formProps} layout="vertical">
        <Form.Item
          rules={[{ required: true }]}
          name="userid"
          label="User ID(WecomId 或者 太湖帐号名)"
        >
          <Input
            placeholder="Please enter user ID"
            onChange={(e) => {
              if (action === 'create' && !usernameTouched) {
                form.setFieldsValue({ username: e.target.value });
              }
            }}
          />
        </Form.Item>

        <Form.Item
          rules={[{ required: true }]}
          name="username"
          label="Username(一般设置为和上面的 User ID 一样)"
        >
          <Input
            placeholder="Please enter username"
            onChange={() => {
              if (!usernameTouched) setUsernameTouched(true);
            }}
          />
        </Form.Item>

        <Form.Item rules={[{ required: true }]} name="roles" label="Roles">
          <Select
            mode="multiple"
            placeholder="Please select roles"
            options={roleOptions}
            loading={rolesLoading}
          />
        </Form.Item>

        <Form.Item
          name="isActive"
          label="Is Active"
          valuePropName="checked"
          initialValue={true}
        >
          <Switch />
        </Form.Item>

        <Form.Item
          name="isApiKey"
          label="Is API Key User(用来提供给其他开发者以apikey的方式来访问)"
          valuePropName="checked"
        >
          <Switch onChange={handleIsApiKeyChange} />
        </Form.Item>

        {isApiKey && (
          <>
            <Form.Item
              label="API Key"
              rules={[
                { required: isApiKey, message: 'Please generate API Key' },
              ]}
            >
              <Space.Compact style={{ width: '100%' }}>
                <Form.Item name="apiKey" noStyle>
                  <Input
                    placeholder="Click button to generate API Key"
                    style={{ fontFamily: 'monospace' }}
                  />
                </Form.Item>
                <Button
                  type="primary"
                  icon={<ReloadOutlined />}
                  onClick={handleGenerateApiKey}
                >
                  {form.getFieldValue('apiKey') ? 'Regenerate' : 'Generate'}
                </Button>
              </Space.Compact>
            </Form.Item>

            <Form.Item name="description" label="Description">
              <Input.TextArea
                rows={2}
                placeholder="Please enter description for this API Key"
              />
            </Form.Item>
          </>
        )}
      </Form>
    </Modal>
  );
};
