import { useState, useCallback, useMemo } from 'react';
import { Form, Input, Button, Card, Row, Col, DatePicker, Divider, Typography, message } from 'antd';
import { useNavigate } from 'react-router-dom';
import { request } from '../api/client';
import { ROUTES } from '../router/routes.constant';
import dayjs, { Dayjs } from 'dayjs';

interface UserResponse {
  id: string;
  email: string;
  first_name: string;
  last_name: string;
  phone: string | null;
  address: string | null;
  role: string;
  status: string;
  created_at: string;
  updated_at: string;
}

interface MemberResponse {
  id: string;
  user_id: string;
  membership_number: string;
  membership_date: string;
  membership_expiry: string | null;
  borrowing_limit: number;
  account_standing: string;
  created_at: string;
  updated_at: string;
}

interface RegistrationFormValues {
  first_name: string;
  last_name: string;
  email: string;
  phone: string;
  date_of_birth: Dayjs;
  street: string;
  city: string;
  state_code: string;
  zip: string;
  password: string;
  confirm_password: string;
}

export default function RegisterPage() {
  const [form] = Form.useForm<RegistrationFormValues>();
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();

  const [submitting, setSubmitting] = useState<boolean>(false);
  const [registrationSuccess, setRegistrationSuccess] = useState<boolean>(false);

  const validateAge = useCallback((_: unknown, value: Dayjs) => {
    if (!value) {
      return Promise.reject(new Error('Date of birth is required'));
    }
    const age = dayjs().diff(value, 'year');
    if (age < 13) {
      return Promise.reject(new Error('You must be at least 13 years old to register'));
    }
    return Promise.resolve();
  }, []);

  const validatePasswordMatch = useCallback(({ getFieldValue }: { getFieldValue: (name: string) => string }) => ({
    validator(_: unknown, value: string) {
      if (!value || getFieldValue('password') === value) {
        return Promise.resolve();
      }
      return Promise.reject(new Error('Passwords do not match'));
    },
  }), []);

  const submitRegistration = useCallback(async () => {
    try {
      setSubmitting(true);
      const values = await form.validateFields();

      const addressParts = [
        values.street,
        values.city,
        values.state_code,
        values.zip
      ].filter(Boolean);
      const fullAddress = addressParts.join(', ');

      const userResult = await request<UserResponse>({
        method: 'POST',
        path: '/users/',
        body: {
          email: values.email,
          first_name: values.first_name,
          last_name: values.last_name,
          phone: values.phone,
          address: fullAddress,
          role: 'MEMBER',
          status: 'INACTIVE',
          password: values.password,
        },
      });

      const createdUserId = userResult.data.id;

      await request<MemberResponse>({
        method: 'POST',
        path: '/users/members',
        body: {
          user_id: createdUserId,
          membership_date: dayjs().format('YYYY-MM-DD'),
          borrowing_limit: 5,
          account_standing: 'GOOD',
        },
      });

      setRegistrationSuccess(true);
      messageApi.success('Registration successful! Your account is pending approval.');
      navigate(ROUTES.LOGIN);
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : 'Registration failed. Please check your information and try again.';
      messageApi.error(errorMessage);
    } finally {
      setSubmitting(false);
    }
  }, [form, messageApi, navigate]);

  const navigateToLogin = useCallback(() => {
    navigate(ROUTES.LOGIN);
  }, [navigate]);

  const passwordRules = useMemo(() => [
    { required: true, message: 'Password is required' },
    { min: 8, message: 'Password must be at least 8 characters' },
    {
      pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]).{8,}$/,
      message: 'Password must contain letters, numbers, and special characters',
    },
  ], []);

  const confirmPasswordRules = useMemo(() => [
    { required: true, message: 'Please confirm your password' },
    validatePasswordMatch,
  ], [validatePasswordMatch]);

  const dobRules = useMemo(() => [
    { required: true, message: 'Date of birth is required' },
    { validator: validateAge },
  ], [validateAge]);

  return (
    <div style={{
      minHeight: '100vh',
      height: '100%',
      width: '100%',
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'center',
      justifyContent: 'center',
      background: '#f5f5f5',
      padding: '24px'
    }}>
      {contextHolder}
      <Card
        bordered={true}
        style={{
          width: '100%',
          maxWidth: '600px',
          borderRadius: '8px'
        }}
      >
        <div style={{ textAlign: 'center', marginBottom: '24px' }}>
          <Typography.Title level={2} style={{ marginBottom: '8px' }}>
            Member Registration
          </Typography.Title>
          <Typography.Text type="secondary">
            Create your library account to start borrowing books
          </Typography.Text>
        </div>

        <Form
          form={form}
          layout="vertical"
          requiredMark={true}
          size="large"
          onFinish={submitRegistration}
        >
          <Row gutter={16}>
            <Col xs={24} sm={12}>
              <Form.Item
                name="first_name"
                label="First Name"
                rules={[{ required: true, message: 'First name is required' }]}
              >
                <Input placeholder="Enter your first name" />
              </Form.Item>
            </Col>
            <Col xs={24} sm={12}>
              <Form.Item
                name="last_name"
                label="Last Name"
                rules={[{ required: true, message: 'Last name is required' }]}
              >
                <Input placeholder="Enter your last name" />
              </Form.Item>
            </Col>
          </Row>

          <Form.Item
            name="email"
            label="Email"
            rules={[
              { required: true, message: 'Email is required' },
              { type: 'email', message: 'Please enter a valid email address' },
            ]}
          >
            <Input placeholder="Enter your email address" type="email" />
          </Form.Item>

          <Row gutter={16}>
            <Col xs={24} sm={12}>
              <Form.Item
                name="phone"
                label="Phone Number"
                rules={[{ required: true, message: 'Phone number is required' }]}
              >
                <Input placeholder="Enter your phone number" />
              </Form.Item>
            </Col>
            <Col xs={24} sm={12}>
              <Form.Item
                name="date_of_birth"
                label="Date of Birth"
                rules={dobRules}
              >
                <DatePicker
                  placeholder="Select date of birth"
                  style={{ width: '100%' }}
                  format="MM/DD/YYYY"
                />
              </Form.Item>
            </Col>
          </Row>

          <Divider orientation="left" plain>
            Address
          </Divider>

          <Form.Item
            name="street"
            label="Street Address"
            rules={[{ required: true, message: 'Street address is required' }]}
          >
            <Input placeholder="Enter your street address" />
          </Form.Item>

          <Row gutter={16}>
            <Col xs={24} sm={10}>
              <Form.Item
                name="city"
                label="City"
                rules={[{ required: true, message: 'City is required' }]}
              >
                <Input placeholder="City" />
              </Form.Item>
            </Col>
            <Col xs={24} sm={7}>
              <Form.Item
                name="state_code"
                label="State"
                rules={[{ required: true, message: 'State is required' }]}
              >
                <Input placeholder="State" />
              </Form.Item>
            </Col>
            <Col xs={24} sm={7}>
              <Form.Item
                name="zip"
                label="Zip Code"
                rules={[{ required: true, message: 'Zip code is required' }]}
              >
                <Input placeholder="Zip" />
              </Form.Item>
            </Col>
          </Row>

          <Divider orientation="left" plain>
            Security
          </Divider>

          <Form.Item
            name="password"
            label="Password"
            rules={passwordRules}
            hasFeedback
          >
            <Input.Password placeholder="Create a strong password" />
          </Form.Item>

          <Typography.Text
            type="secondary"
            style={{
              fontSize: '12px',
              marginTop: '-16px',
              marginBottom: '16px',
              display: 'block'
            }}
          >
            Password must be at least 8 characters with a mix of letters, numbers, and special characters.
          </Typography.Text>

          <Form.Item
            name="confirm_password"
            label="Confirm Password"
            dependencies={['password']}
            hasFeedback
            rules={confirmPasswordRules}
          >
            <Input.Password placeholder="Re-enter your password" />
          </Form.Item>

          <Button
            type="primary"
            htmlType="submit"
            block
            size="large"
            loading={submitting}
            style={{ marginTop: '8px' }}
          >
            Create Account
          </Button>

          <div style={{ textAlign: 'center', marginTop: '16px' }}>
            <Typography.Text type="secondary">
              Already have an account?{' '}
            </Typography.Text>
            <Typography.Link onClick={navigateToLogin}>
              Sign in here
            </Typography.Link>
          </div>
        </Form>
      </Card>
    </div>
  );
}