'use client'

import { Api, Model } from '@web/domain'
import { PageLayout } from '@web/layouts/Page.layout'
import { useAuthentication } from '@web/modules/authentication'
import { Button, Card, List, Spin, Typography, notification } from 'antd'
import { useParams } from 'next/navigation'
import { useSnackbar } from 'notistack'
import { useEffect, useState } from 'react'

const { Title, Text } = Typography

// Component to display booking details
const BookingForm = ({ booking }: { booking: Model.Booking | null }) => {
  if (!booking) {
    return <Text>Loading booking details...</Text>
  }

  return (
    <Card>
      <Text>Base Price: ${booking.basePrice ?? 0}</Text>
      <br />
      <Text>Distance Fee: ${booking.distanceFee ?? 0}</Text>
      <br />
      <Text>Total Price: ${booking.totalPrice ?? 0}</Text>
      {/* Add more details as needed */}
    </Card>
  )
}

export default function BookingFormPage() {
  const params = useParams<{ bookingId?: string }>() // Define expected params shape
  const authentication = useAuthentication()
  const userId = authentication.user?.id
  const { enqueueSnackbar } = useSnackbar()

  const [booking, setBooking] = useState<Model.Booking | null>(null)
  const [notifications, setNotifications] = useState<Model.Notification[]>([])
  const [loadingBooking, setLoadingBooking] = useState<boolean>(true)
  const [loadingNotifications, setLoadingNotifications] = useState<boolean>(
    true,
  )

  useEffect(() => {
    const fetchBookingDetails = async () => {
      if (!userId || !params.bookingId) return // Ensure params.bookingId is checked

      try {
        const bookingData = await Api.Booking.findOne(params.bookingId) // Use params.bookingId directly
        setBooking(bookingData)
      } catch (error) {
        console.error('Error fetching booking details:', error)
        enqueueSnackbar('Failed to fetch booking details', { variant: 'error' })
      } finally {
        setLoadingBooking(false)
      }
    }

    fetchBookingDetails()
  }, [userId, params.bookingId, enqueueSnackbar])

  useEffect(() => {
    const fetchNotifications = async () => {
      if (!userId) return

      try {
        const notificationsData = await Api.Notification.findMany({
          filters: { userId },
        })
        setNotifications(notificationsData)
      } catch (error) {
        console.error('Error fetching notifications:', error)
        enqueueSnackbar('Failed to fetch notifications', { variant: 'error' })
      } finally {
        setLoadingNotifications(false)
      }
    }

    fetchNotifications()
  }, [userId, enqueueSnackbar])

  useEffect(() => {
    const eventSource = new EventSource(`/api/notifications/stream/${userId}`)
    eventSource.onmessage = event => {
      const notificationData = JSON.parse(event.data)
      setNotifications(prevNotifications => [
        notificationData,
        ...prevNotifications,
      ])
      notification.open({
        message: notificationData.title,
        description: notificationData.message,
      })
    }

    return () => {
      eventSource.close()
    }
  }, [userId])

  const handleRequestTow = () => {
    enqueueSnackbar('Tow request submitted!', { variant: 'success' })
  }

  return (
    <PageLayout layout="narrow">
      <Title level={2}>Towing Request Form</Title>
      {loadingBooking ? (
        <Spin tip="Loading booking details..." />
      ) : (
        <BookingForm booking={booking} />
      )}
      <Button
        type="primary"
        size="large"
        style={{ marginTop: '20px' }}
        onClick={handleRequestTow}
      >
        Request Tow
      </Button>
      <Title level={2}>User Profile</Title>
      <List
        header={<div>Quick Links</div>}
        bordered
        dataSource={[
          { text: 'Reset Password', link: '/reset-password' },
          { text: 'Email Preferences', link: '/profile/email-preferences' },
        ]}
        renderItem={item => (
          <List.Item>
            <a href={item.link}>{item.text}</a>
          </List.Item>
        )}
      />
      <Title level={2}>Notifications</Title>
      {loadingNotifications ? (
        <Spin tip="Loading notifications..." />
      ) : (
        <List
          bordered
          dataSource={notifications}
          renderItem={notificationData => (
            <List.Item>
              <List.Item.Meta
                title={notificationData.title}
                description={notificationData.message}
              />
            </List.Item>
          )}
        />
      )}
    </PageLayout>
  )
}
'use client'

import {
  CreditCardOutlined,
  EditOutlined,
  MailOutlined,
} from '@ant-design/icons'
import { Api, Model } from '@web/domain'
import { PageLayout } from '@web/layouts/Page.layout'
import { useAuthentication } from '@web/modules/authentication'
import {
  Button,
  Card,
  Col,
  DatePicker,
  Form,
  Input,
  Row,
  Select,
  Space,
  Typography,
} from 'antd'
import dayjs from 'dayjs'
import { useParams } from 'next/navigation'
import { useRouter } from 'next/router'
import { useSnackbar } from 'notistack'
import { useCallback, useEffect, useState } from 'react'
import { calculateCost } from '../utils/calculateCost.ts'
import { fetchData } from '../utils/fetchData.ts'

const { Title, Text } = Typography

const BookingForm = () => {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    phone: '',
    serviceType: 'standard',
    distance: 0,
    cost: 0,
  })
  const [isSubmitting, setIsSubmitting] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')
  const router = useRouter()
  const params = useParams<any>()
  const authentication = useAuthentication()
  const userId = authentication.user?.id
  const { enqueueSnackbar } = useSnackbar()
  const [booking, setBooking] = useState<Model.Booking | null>(null)
  const [isEditing, setIsEditing] = useState(false)
  const [form] = Form.useForm()

  const handleInputChange = useCallback(e => {
    const { name, value } = e.target
    setFormData(prevData => ({
      ...prevData,
      [name]: value,
    }))
  }, [])

  const handleDistanceChange = useCallback(e => {
    const distance = parseFloat(e.target.value)
    setFormData(prevData => ({
      ...prevData,
      distance,
      cost: calculateCost(distance),
    }))
  }, [])

  const handleSubmit = async e => {
    e.preventDefault()
    setIsSubmitting(true)
    setErrorMessage('')

    try {
      await fetchData('/api/bookings', 'POST', formData)
      router.push('/thank-you')
    } catch (error) {
      setErrorMessage('There was an issue with your booking. Please try again.')
    } finally {
      setIsSubmitting(false)
    }
  }

  useEffect(() => {
    const fetchBooking = async () => {
      try {
        const bookingData = await Api.Booking.findOne(params.bookingId, {
          includes: ['user'],
        })
        setBooking(bookingData)
        form.setFieldsValue({
          serviceType: bookingData.serviceType,
          name: bookingData.name,
          phone: bookingData.phone,
          vehicleBrand: bookingData.vehicleBrand,
          vehicleModel: bookingData.vehicleModel,
          dateTime: dayjs(bookingData.dateTime),
          distance: bookingData.distance,
        })
      } catch (error) {
        enqueueSnackbar('Failed to fetch booking details', { variant: 'error' })
      }
    }

    if (params.bookingId) {
      fetchBooking()
    }
  }, [params.bookingId, form])

  const handleEdit = async (values: any) => {
    try {
      const updatedBooking = await Api.Booking.updateOne(params.bookingId, {
        ...values,
        dateTime: values.dateTime.toISOString(),
      })
      setBooking(updatedBooking)
      setIsEditing(false)
      enqueueSnackbar('Booking details updated successfully', {
        variant: 'success',
      })
    } catch (error) {
      enqueueSnackbar('Failed to update booking details', { variant: 'error' })
    }
  }

  const handleEmailSend = async () => {
    try {
      await Api.Notification.createOneByUserId(userId, {
        title: 'Booking Confirmation',
        message: `Your booking details: ${JSON.stringify(booking, null, 2)}`,
        userId: userId,
      })
      enqueueSnackbar('Booking details sent via email', { variant: 'success' })
    } catch (error) {
      enqueueSnackbar('Failed to send booking details via email', {
        variant: 'error',
      })
    }
  }

  const handleProceedToPayment = () => {
    router.push('/payment')
  }

  return (
    <PageLayout layout="narrow">
      <Title level={2}>Booking Confirmation</Title>
      <Text>Review and confirm your booking details below:</Text>
      <Card style={{ marginTop: 20 }}>
        {isEditing ? (
          <Form form={form} onFinish={handleEdit} layout="vertical">
            <Form.Item
              name="serviceType"
              label="Service Type"
              rules={[
                { required: true, message: 'Please select the service type!' },
              ]}
            >
              <Select>
                <Select.Option value="standard">Standard</Select.Option>
                <Select.Option value="premium">Premium</Select.Option>
              </Select>
            </Form.Item>
            <Form.Item
              name="name"
              label="Name"
              rules={[{ required: true, message: 'Please input your name!' }]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="email"
              label="Email"
              rules={[
                { required: true, message: 'Please input your email!' },
                { type: 'email', message: 'Please enter a valid email!' },
              ]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="phone"
              label="Phone"
              rules={[
                { required: true, message: 'Please input your phone number!' },
              ]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="vehicleBrand"
              label="Vehicle Brand"
              rules={[
                { required: true, message: 'Please input your vehicle brand!' },
              ]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="vehicleModel"
              label="Vehicle Model"
              rules={[
                { required: true, message: 'Please input your vehicle model!' },
              ]}
            >
              <Input />
            </Form.Item>
            <Form.Item
              name="dateTime"
              label="Date and Time"
              rules={[
                { required: true, message: 'Please select date and time!' },
              ]}
            >
              <DatePicker showTime />
            </Form.Item>
            <Form.Item
              name="distance"
              label="Distance (in km)"
              rules={[
                { required: true, message: 'Please input the distance!' },
              ]}
            >
              <Input type="number" onChange={handleDistanceChange} />
            </Form.Item>
            <Form.Item name="cost" label="Estimated Cost">
              <Input readOnly />
            </Form.Item>
            <div id="map" style={{ height: '400px', width: '100%' }}></div>
            <Form.Item>
              <Button type="primary" htmlType="submit">
                Save
              </Button>
              <Button
                type="default"
                onClick={() => setIsEditing(false)}
                style={{ marginLeft: 10 }}
              >
                Cancel
              </Button>
            </Form.Item>
          </Form>
        ) : (
          <div>
            <Row gutter={[16, 16]}>
              <Col span={12}>
                <Text strong>Service Type:</Text> {booking?.serviceType}
              </Col>
              <Col span={12}>
                <Text strong>Name:</Text> {booking?.name}
              </Col>
              <Col span={12}>
                <Text strong>Email:</Text> {booking?.email}
              </Col>
              <Col span={12}>
                <Text strong>Phone:</Text> {booking?.phone}
              </Col>
              <Col span={12}>
                <Text strong>Vehicle Brand:</Text> {booking?.vehicleBrand}
              </Col>
              <Col span={12}>
                <Text strong>Vehicle Model:</Text> {booking?.vehicleModel}
              </Col>
              <Col span={12}>
                <Text strong>Date and Time:</Text>{' '}
                {dayjs(booking?.dateTime).format('YYYY-MM-DD HH:mm')}
              </Col>
              <Col span={12}>
                <Text strong>Distance:</Text> {booking?.distance} km
              </Col>
              <Col span={12}>
                <Text strong>Estimated Cost:</Text> ${booking?.cost?.toFixed(2)}
              </Col>
            </Row>
            <Button
              type="primary"
              icon={<EditOutlined />}
              onClick={() => setIsEditing(true)}
              style={{ marginTop: 20 }}
            >
              Edit
            </Button>
          </div>
        )}
      </Card>
      <Space style={{ marginTop: 20 }}>
        <Button
          type="primary"
          icon={<MailOutlined />}
          onClick={handleEmailSend}
        >
          Send Email
        </Button>
        <Button
          type="primary"
          icon={<CreditCardOutlined />}
          onClick={handleProceedToPayment}
        >
          Proceed to Payment
        </Button>
      </Space>
    </PageLayout>
  )
}

export default BookingForm

useEffect(() => {
  const initMap = () => {
    const map = new google.maps.Map(document.getElementById('map'), {
      center: { lat: -34.397, lng: 150.644 },
      zoom: 8,
    })
  }

  if (typeof google !== 'undefined') {
    initMap()
  } else {
    window.initMap = initMap
  }
}, [])