import { FC } from 'react'
import cn from 'clsx'
import {
  CardNumberElement,
  CardExpiryElement,
  CardCvcElement,
  useStripe,
  useElements
} from '@stripe/react-stripe-js'
import useAddCard from '@framework/customer/card/use-add-item'
import { Button, Text } from '@components/ui'
import { useUI } from '@components/ui/context'
import SidebarLayout from '@components/common/SidebarLayout'
import countries from '@lib/countries'
import s from './PaymentMethodView.module.css'

interface Form extends HTMLFormElement {
  cardHolder: HTMLInputElement
  cardNumber: HTMLInputElement
  cardExpireDate: HTMLInputElement
  cardCvc: HTMLInputElement
  firstName: HTMLInputElement
  lastName: HTMLInputElement
  company: HTMLInputElement
  streetNumber: HTMLInputElement
  zipCode: HTMLInputElement
  city: HTMLInputElement
  country: HTMLSelectElement
}

const PaymentMethodView: FC = () => {
  const { paymentMethodDetails, setPaymentMethodDetails, setSidebarView } = useUI()
  const { address } = paymentMethodDetails

  const addCard = useAddCard()

  const stripe = useStripe()
  const elements = useElements()

  async function handleSubmit(event: React.ChangeEvent<Form>) {
    event.preventDefault()
    if (!stripe || !elements) {
      return
    }

    const card = elements.getElement(CardNumberElement)

    const { error, paymentMethod } = await stripe.createPaymentMethod({
      type: 'card',
      card
    })

    if (error) {
      console.error(error)
    }

    setPaymentMethodDetails({ address, paymentMethod })

    await addCard({
      cardHolder: event.target.cardHolder.value,
      cardNumber: event.target.cardNumber.value,
      cardExpireDate: event.target.cardExpireDate.value,
      cardCvc: event.target.cardCvc.value,
      firstName: event.target.firstName.value,
      lastName: event.target.lastName.value,
      company: event.target.company.value,
      streetNumber: event.target.streetNumber.value,
      zipCode: event.target.zipCode.value,
      city: event.target.city.value,
      country: event.target.country.value,
    })

    setSidebarView('CHECKOUT_VIEW')
  }

  const updateAddressData = ({ target }: any) => setPaymentMethodDetails({
    ...paymentMethodDetails,
    address: {
      ...paymentMethodDetails.address,
      [target.name]: target.value,
    },
  })

  return (
    <form className="h-full" onSubmit={handleSubmit}>
      <SidebarLayout handleBack={() => setSidebarView('CHECKOUT_VIEW')}>
        <div className="px-4 sm:px-6 flex-1">
          <Text variant="sectionHeading"> Payment Method</Text>
          <div>
            <div className={s.fieldset}>
              <label className={s.label}>Cardholder Name</label>
              <input name="cardHolder" className={s.input} />
            </div>
            <div className="grid gap-3 grid-flow-row grid-cols-12">
              <div className={cn(s.fieldset, 'col-span-7')}>
                <label className={s.label}>Card Number</label>
                <CardNumberElement className={s.input} />
              </div>
              <div className={cn(s.fieldset, 'col-span-3')}>
                <label className={s.label}>Expires</label>
                <CardExpiryElement className={s.input} placeholder='MM/YY' />
              </div>
              <div className={cn(s.fieldset, 'col-span-2')}>
                <label className={s.label}>CVC</label>
                <CardCvcElement className={s.input} />
              </div>
            </div>
            <hr className="border-accent-2 my-6" />
            <div className="grid gap-3 grid-flow-row grid-cols-12">
              <div className={cn(s.fieldset, 'col-span-6')}>
                <label className={s.label}>First Name</label>
                <input
                  name="firstName"
                  className={s.input}
                  onChange={updateAddressData}
                  value={address.firstName}
                />
              </div>
              <div className={cn(s.fieldset, 'col-span-6')}>
                <label className={s.label}>Last Name</label>
                <input
                  name="lastName"
                  className={s.input}
                  onChange={updateAddressData}
                  value={address.lastName}
                />
              </div>
            </div>
            <div className={s.fieldset}>
              <label className={s.label}>Company (Optional)</label>
              <input
                name="company"
                className={s.input}
                onChange={updateAddressData}
                value={address.company}
              />
            </div>
            <div className={s.fieldset}>
              <label className={s.label}>Street and House Number</label>
              <input
                name="streetNumber"
                className={s.input}
                onChange={updateAddressData}
                value={address.addressLine1}
              />
            </div>
            <div className={s.fieldset}>
              <label className={s.label}>
                Apartment, Suite, Etc. (Optional)
              </label>
              <input
                className={s.input}
                name="apartment"
                onChange={updateAddressData}
                value={address.addressLine2}
              />
            </div>
            <div className="grid gap-3 grid-flow-row grid-cols-12">
              <div className={cn(s.fieldset, 'col-span-6')}>
                <label className={s.label}>Postal Code</label>
                <input
                  name="zipCode"
                  className={s.input}
                  onChange={updateAddressData}
                  value={address.postalCode}
                />
              </div>
              <div className={cn(s.fieldset, 'col-span-6')}>
                <label className={s.label}>City</label>
                <input
                  name="city"
                  className={s.input}
                  onChange={updateAddressData}
                  value={address.city}
                />
              </div>
            </div>
            <div className={s.fieldset}>
              <label className={s.label}>Country/Region</label>
              <select
                name="country"
                className={s.select}
                onChange={updateAddressData}
                value={address.region}
              >
                {countries.map((country) => (
                  <option
                    key={country.code}
                    value={country.code}
                  >
                    {country.name}
                  </option>
                ))}
              </select>
            </div>
          </div>
        </div>
        <div className="sticky z-20 bottom-0 w-full right-0 left-0 py-12 bg-accent-0 border-t border-accent-2 px-6">
          <Button type="submit" width="100%" variant="ghost">
            Continue
          </Button>
        </div>
      </SidebarLayout>
    </form>
  )
}

export default PaymentMethodView
