import { Head, Link, useForm } from '@inertiajs/react';
import type { FormEvent } from 'react';

type ShippingMethod = { name: string; code: string; provider: string | null; price: string };

export default function CheckoutShow({
    cart,
    totals,
    shippingMethods,
}: {
    cart: { items: unknown[] };
    totals: { subtotal: number; total: number };
    shippingMethods: ShippingMethod[];
}) {
    const defaultShipping = shippingMethods[0]?.code ?? 'local_pickup';
    const { data, setData, post, processing, errors } = useForm({
        customer_name: '',
        customer_email: '',
        customer_phone: '',
        billing_country: 'Bulgaria',
        billing_city: '',
        billing_postal_code: '',
        billing_address_line_1: '',
        billing_address_line_2: '',
        shipping_country: 'Bulgaria',
        shipping_city: '',
        shipping_postal_code: '',
        shipping_address_line_1: '',
        shipping_address_line_2: '',
        shipping_method: defaultShipping,
        payment_method: 'cash_on_delivery',
        customer_notes: '',
    });

    function submit(event: FormEvent) {
        event.preventDefault();
        post('/checkout');
    }

    return (
        <>
            <Head title="Checkout" />
            <main className="min-h-screen bg-slate-50 px-4 py-6 text-slate-900 sm:px-6 lg:px-8">
                <form onSubmit={submit} className="mx-auto grid max-w-5xl gap-5 lg:grid-cols-[1fr_320px]">
                    <section className="rounded-lg border border-slate-200 bg-white p-5">
                        <h1 className="text-2xl font-semibold">Checkout</h1>
                        <div className="mt-5 grid gap-4 md:grid-cols-2">
                            <Field label="Name" error={errors.customer_name}>
                                <input className="input" value={data.customer_name} onChange={(event) => setData('customer_name', event.target.value)} />
                            </Field>
                            <Field label="Email" error={errors.customer_email}>
                                <input className="input" type="email" value={data.customer_email} onChange={(event) => setData('customer_email', event.target.value)} />
                            </Field>
                            <Field label="Phone" error={errors.customer_phone}>
                                <input className="input" value={data.customer_phone} onChange={(event) => setData('customer_phone', event.target.value)} />
                            </Field>
                            <Field label="Payment" error={errors.payment_method}>
                                <select className="input" value={data.payment_method} onChange={(event) => setData('payment_method', event.target.value)}>
                                    <option value="cash_on_delivery">Cash on delivery</option>
                                    <option value="bank_transfer">Bank transfer</option>
                                    <option value="card">Card</option>
                                    <option value="stripe">Stripe</option>
                                    <option value="paypal">PayPal</option>
                                </select>
                            </Field>
                        </div>

                        <h2 className="mt-6 font-semibold">Billing address</h2>
                        <div className="mt-3 grid gap-4 md:grid-cols-2">
                            <AddressFields prefix="billing" data={data} setData={setData} errors={errors} />
                        </div>

                        <h2 className="mt-6 font-semibold">Shipping address</h2>
                        <div className="mt-3 grid gap-4 md:grid-cols-2">
                            <AddressFields prefix="shipping" data={data} setData={setData} errors={errors} />
                            <Field label="Shipping method" error={errors.shipping_method}>
                                <select className="input" value={data.shipping_method} onChange={(event) => setData('shipping_method', event.target.value)}>
                                    {shippingMethods.map((method) => (
                                        <option key={method.code} value={method.code}>
                                            {method.name} {method.price}
                                        </option>
                                    ))}
                                    {shippingMethods.length === 0 ? <option value="local_pickup">Local pickup</option> : null}
                                </select>
                            </Field>
                            <Field label="Order notes" error={errors.customer_notes}>
                                <textarea className="input min-h-24" value={data.customer_notes} onChange={(event) => setData('customer_notes', event.target.value)} />
                            </Field>
                        </div>
                    </section>

                    <aside className="h-fit rounded-lg border border-slate-200 bg-white p-5">
                        <h2 className="font-semibold">Summary</h2>
                        <p className="mt-3 text-sm text-slate-500">{cart.items.length} item(s)</p>
                        <p className="mt-4 text-2xl font-semibold">{totals.total.toFixed(2)}</p>
                        <button disabled={processing || cart.items.length === 0} className="mt-5 w-full rounded-md bg-cyan-700 px-4 py-2 text-sm font-semibold text-white hover:bg-cyan-800 disabled:opacity-60">
                            Place order
                        </button>
                        <Link href="/cart" className="mt-3 block text-center text-sm font-semibold text-cyan-700">
                            Back to cart
                        </Link>
                    </aside>
                </form>
            </main>
        </>
    );
}

function AddressFields({ prefix, data, setData, errors }: { prefix: 'billing' | 'shipping'; data: Record<string, string>; setData: (key: string, value: string) => void; errors: Record<string, string> }) {
    return (
        <>
            <Field label="Country" error={errors[`${prefix}_country`]}>
                <input className="input" value={data[`${prefix}_country`]} onChange={(event) => setData(`${prefix}_country`, event.target.value)} />
            </Field>
            <Field label="City" error={errors[`${prefix}_city`]}>
                <input className="input" value={data[`${prefix}_city`]} onChange={(event) => setData(`${prefix}_city`, event.target.value)} />
            </Field>
            <Field label="Postal code" error={errors[`${prefix}_postal_code`]}>
                <input className="input" value={data[`${prefix}_postal_code`]} onChange={(event) => setData(`${prefix}_postal_code`, event.target.value)} />
            </Field>
            <Field label="Address" error={errors[`${prefix}_address_line_1`]}>
                <input className="input" value={data[`${prefix}_address_line_1`]} onChange={(event) => setData(`${prefix}_address_line_1`, event.target.value)} />
            </Field>
        </>
    );
}

function Field({ label, error, children }: { label: string; error?: string; children: React.ReactNode }) {
    return (
        <label className="grid gap-1 text-sm font-medium text-slate-700">
            <span>{label}</span>
            {children}
            {error ? <span className="text-xs text-red-600">{error}</span> : null}
        </label>
    );
}
