'use client';
import React, { useRef, useState } from 'react';
import { Button } from "primereact/button";
// 输入框
import { InputText } from "primereact/inputtext";
// 消息提醒
import { Toast } from 'primereact/toast';
// 接口传输
import axios from "axios";
// 页面跳转
import { useRouter } from "next/navigation";
// 密码
import { Password } from 'primereact/password';
// 样式
import './register.scss';

export default function RegisterPage() {
    // 路由
    const router = useRouter();
    // 消息提醒
    const toast = useRef<Toast>(null);

    const [registerFormData, setRegisterFormData] = useState({
        username: '',
        password: '',
        confirmPassword: '',
        invitationCode: '',
    })


    // 处理用户注册
    const handleRegister = async () => {
        try {
            // 判断用户两次输入的密码是否一致
            if (registerFormData.password != registerFormData.confirmPassword) {
                console.error("两次输入的密码不一致，请重新输入");
                toast.current?.show({severity: 'error', summary: 'Error', detail: '两次输入的密码不一致，请重新输入'});
                return;
            }

            const postData = {
                username: registerFormData.username,
                password: registerFormData.password,
                invitationCode:  registerFormData.invitationCode,
            }
            const response = await axios.post(process.env.PUBLIC_URL + `/user/register`, postData, {
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
                validateStatus: (status) => true // 接受所有状态码
            });

            if (response.status === 200) {
                console.log('用户注册成功');
                toast.current?.show({severity: 'success', summary: 'Success', detail: '注册成功'});
                router.push('/user/login');
            } else if (response.status === 412) {
                console.log('用户名重复');
                toast.current?.show({severity: 'error', summary: 'Error', detail: '用户名重复'});
            } else if (response.status === 409) {
                console.error('邀请码不存在');
                toast.current?.show({severity: 'error', summary: 'Error', detail: '邀请码不存在'});
            } else if (response.status === 410) {
                console.error('邀请码已被使用');
                toast.current?.show({severity: 'error', summary: 'Error', detail: '邀请码已被使用'});
            }

        } catch (error) {
            console.error('注册失败:', error);
            toast.current?.show({severity: 'error', summary: 'Error', detail: '注册失败'});
        }
    }

  return (
      <div className='register-container'>
          <Toast ref={toast}></Toast>
          <h1 className="form-header">注册</h1>
          <div className="form-field">
              <div className="form-field-header">
                  <label htmlFor="username">用户名</label>
              </div>
              <InputText
                  id="username"
                  value={registerFormData.username}
                  onChange={(e) => setRegisterFormData(prev => ({
                      ...prev, // 复制顶层所有属性
                      username: e.target.value
                  }))}
                  className="w-full"
              />
          </div>
          <div className="form-field">
              <div className="form-field-header">
                  <label htmlFor="password">设置密码</label>
              </div>
              <Password
                  id="password"
                  value={registerFormData.password}
                  onChange={(e) => setRegisterFormData(prev => ({
                      ...prev,
                      password: e.target.value
                  }))}
                  className="w-full"
                  toggleMask
              />
          </div>
          <div className="form-field">
              <div className="form-field-header">
                  <label htmlFor="confirmPassword">确认密码</label>
              </div>
              <Password
                  id="confirmPassword"
                  value={registerFormData.confirmPassword}
                  onChange={(e) => setRegisterFormData(prev => ({
                      ...prev,
                      confirmPassword: e.target.value
                  }))}
                  className="w-full"
                  toggleMask
              />
          </div>
          <div className="form-field">
              <div className="form-field-header">
                  <label htmlFor="invitationCode">邀请码</label>
              </div>
              <InputText
                  id="invitationCode"
                  value={registerFormData.invitationCode}
                  onChange={(e) => setRegisterFormData(prev => ({
                      ...prev, // 复制顶层所有属性
                      invitationCode: e.target.value
                  }))}
                  className="w-full"
              />
          </div>
          <div className="form-operation">
              <Button label="确定" onClick={handleRegister} className='form-operation-button'/>
              <Button label="返回" onClick={() => router.push("/user/login")} className='form-operation-button'/>
          </div>
      </div>
  )
};
