import React, { useEffect, useMemo, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { Alert, Button, Checkbox, Field, Icon, Input, Segmented, Select, Skeleton, Switch, useToast } from '../../../shared/ui';
import api from '../../core/api';
import useAsync from '../../core/useAsync';
import useForm from '../../core/useForm';
import { useUnsavedChanges } from '../../core/AdminContext';
import { FormGrid, Page, PageHeader, SaveBar, Section } from '../../ui/page';

const METHODS = () => [
	{ key: 'cash', label: __('Pay at the appointment', 'pointly-booking'), note: __('The customer pays in person.', 'pointly-booking'), icon: 'banknote' },
	{ key: 'free', label: __('No payment', 'pointly-booking'), note: __('Free bookings, no payment step.', 'pointly-booking'), icon: 'check-circle' },
	{ key: 'stripe', label: __('Stripe (cards)', 'pointly-booking'), note: __('Secure card payment, in the booking form.', 'pointly-booking'), icon: 'credit-card' },
	{ key: 'paypal', label: __('PayPal', 'pointly-booking'), note: __('PayPal account or card.', 'pointly-booking'), icon: 'wallet' },
	{ key: 'woocommerce', label: __('WooCommerce checkout', 'pointly-booking'), note: __('Any gateway available in WooCommerce.', 'pointly-booking'), icon: 'receipt' },
];

const blank = {
	payments_enabled: 1,
	enabled_methods: ['cash', 'free'],
	default_method: 'cash',
	require_payment_to_confirm: 1,
	woocommerce: { product_id: 0 },
	stripe: { enabled: 0, mode: 'test', test_secret_key: '', test_publishable_key: '', live_secret_key: '', live_publishable_key: '', webhook_secret: '', success_url: '', cancel_url: '' },
	paypal: { enabled: 0, mode: 'test', client_id: '', secret: '', return_url: '', cancel_url: '' },
};

/** REST URL for the Stripe webhook (works with plain and pretty permalinks). */
function webhookUrl() {
	const base = String(window.pointlybooking_ADMIN?.restUrl || '').replace(/\/$/, '');
	return `${base}/webhooks/stripe`;
}

function ModeSwitch({ value, onChange, disabled }) {
	return (
		<Segmented label={__('Mode', 'pointly-booking')} value={value} onChange={onChange} options={[{ value: 'test', label: __('Test', 'pointly-booking') }, { value: 'live', label: __('Live', 'pointly-booking') }]} disabled={disabled} />
	);
}

export default function PaymentsTab() {
	const toast = useToast();
	const res = useAsync(() => api.get('/admin/settings/payments'), [], { keepPrevious: false });
	const form = useForm(blank);
	const [saving, setSaving] = useState(false);
	const [error, setError] = useState('');
	useUnsavedChanges(form.dirty && !saving, 'payments');

	useEffect(() => {
		if (res.data) form.load({ ...blank, ...(res.data.payments || {}), stripe: { ...blank.stripe, ...((res.data.payments || {}).stripe || {}) }, paypal: { ...blank.paypal, ...((res.data.payments || {}).paypal || {}) }, woocommerce: { ...blank.woocommerce, ...((res.data.payments || {}).woocommerce || {}) } });
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [res.data]);

	const v = form.values;
	const on = !!v.payments_enabled;
	const enabled = Array.isArray(v.enabled_methods) ? v.enabled_methods : [];
	const active = (k) => on && enabled.includes(k);
	const stripeMode = v.stripe.mode === 'live' ? 'live' : 'test';

	const problems = useMemo(() => {
		const p = {};
		if (active('stripe')) {
			if (!String(v.stripe[`${stripeMode}_secret_key`] || '').trim()) p.stripeSecret = true;
			if (!String(v.stripe[`${stripeMode}_publishable_key`] || '').trim()) p.stripePub = true;
		}
		if (active('paypal')) {
			if (!String(v.paypal.client_id || '').trim()) p.ppClient = true;
			if (!String(v.paypal.secret || '').trim()) p.ppSecret = true;
		}
		if (active('woocommerce') && !(Number(v.woocommerce.product_id) > 0)) p.wc = true;
		return p;
	}, [v, on]); // eslint-disable-line react-hooks/exhaustive-deps
	const blocked = on && Object.keys(problems).length > 0;

	const toggleMethod = (key) => {
		const next = enabled.includes(key) ? enabled.filter((m) => m !== key) : [...enabled, key];
		const list = next.length ? next : ['cash'];
		form.patch({ enabled_methods: list, default_method: list.includes(v.default_method) ? v.default_method : list[0] });
	};
	const setIn = (group, key, value) => form.set(group, { ...v[group], [key]: value });

	const save = async () => {
		setError('');
		setSaving(true);
		const sent = v;
		try {
			const out = await api.post('/admin/settings/payments', { payments: sent });
			form.markSaved(sent);
			if (out && out.payments && JSON.stringify(out.payments) !== JSON.stringify(sent)) form.load({ ...sent, ...out.payments });
			toast.success(__('Payment settings saved', 'pointly-booking'));
		} catch (e) {
			setError(e.message);
		} finally {
			setSaving(false);
		}
	};

	const copy = async (text) => {
		try {
			await navigator.clipboard.writeText(text);
			toast.success(__('Copied', 'pointly-booking'));
		} catch (e) {
			toast.error(__('Could not copy', 'pointly-booking'));
		}
	};

	return (
		<Page>
			<PageHeader title={__('Payments', 'pointly-booking')} subtitle={__('Choose how customers pay and connect your payment providers.', 'pointly-booking')} />
			{res.error ? <Alert tone="danger">{res.error}</Alert> : null}
			{error ? <Alert tone="danger" live>{error}</Alert> : null}

			{res.loading && !res.data ? (
				<div className="bp-stack">
					<Skeleton height={140} block />
					<Skeleton height={260} block />
				</div>
			) : (
				<>
					<Section title={__('Payments', 'pointly-booking')}>
						<div className="bp-stack">
							<Switch label={__('Take payments', 'pointly-booking')} description={__('When off, bookings are saved without a payment step.', 'pointly-booking')} checked={on} onChange={(c) => form.set('payments_enabled', c ? 1 : 0)} />
							<Switch label={__('Wait for payment before confirming', 'pointly-booking')} description={__('For Stripe, PayPal and WooCommerce the booking is confirmed once the payment succeeds.', 'pointly-booking')} checked={!!v.require_payment_to_confirm} disabled={!on} onChange={(c) => form.set('require_payment_to_confirm', c ? 1 : 0)} />
						</div>
					</Section>

					<Section title={__('Payment methods', 'pointly-booking')} description={__('Customers only see methods that are switched on and fully set up.', 'pointly-booking')}>
						<div className="bp-paymethods">
							{METHODS().map((m) => (
								<label key={m.key} className={['bp-paymethod', active(m.key) ? 'is-on' : ''].join(' ')}>
									<Checkbox checked={enabled.includes(m.key)} disabled={!on} onChange={() => toggleMethod(m.key)} aria-label={m.label} />
									<span className="bp-paymethod__icon"><Icon name={m.icon} /></span>
									<span className="bp-paymethod__text">
										<strong>{m.label}</strong>
										<span className="bp-text-muted">{m.note}</span>
									</span>
								</label>
							))}
						</div>
						<Field label={__('Default method', 'pointly-booking')} className="bp-mt-4">
							<Select value={v.default_method} disabled={!on} onChange={(e) => form.set('default_method', e.target.value)} options={METHODS().filter((m) => enabled.includes(m.key)).map((m) => ({ value: m.key, label: m.label }))} />
						</Field>
						{on && enabled.length === 0 ? <Alert tone="danger">{__('Switch on at least one payment method.', 'pointly-booking')}</Alert> : null}
					</Section>

					{active('stripe') ? (
						<Section title="Stripe" description={__('Cards are entered inside the booking form. Without a publishable key customers are sent to Stripe’s hosted page.', 'pointly-booking')} actions={<ModeSwitch value={stripeMode} onChange={(m) => setIn('stripe', 'mode', m)} />}>
							<FormGrid>
								<Field label={stripeMode === 'live' ? __('Live secret key', 'pointly-booking') : __('Test secret key', 'pointly-booking')} required error={problems.stripeSecret ? __('Required', 'pointly-booking') : undefined}>
									<Input type="password" autoComplete="off" dir="ltr" value={v.stripe[`${stripeMode}_secret_key`] || ''} onChange={(e) => setIn('stripe', `${stripeMode}_secret_key`, e.target.value)} placeholder={stripeMode === 'live' ? 'sk_live_…' : 'sk_test_…'} />
								</Field>
								<Field label={stripeMode === 'live' ? __('Live publishable key', 'pointly-booking') : __('Test publishable key', 'pointly-booking')} required error={problems.stripePub ? __('Required', 'pointly-booking') : undefined}>
									<Input autoComplete="off" dir="ltr" value={v.stripe[`${stripeMode}_publishable_key`] || ''} onChange={(e) => setIn('stripe', `${stripeMode}_publishable_key`, e.target.value)} placeholder={stripeMode === 'live' ? 'pk_live_…' : 'pk_test_…'} />
								</Field>
								<Field label={__('Webhook signing secret', 'pointly-booking')} hint={__('From your Stripe dashboard → Developers → Webhooks.', 'pointly-booking')} className="bp-span-2">
									<Input type="password" autoComplete="off" dir="ltr" value={v.stripe.webhook_secret || ''} onChange={(e) => setIn('stripe', 'webhook_secret', e.target.value)} placeholder="whsec_…" />
								</Field>
								<Field label={__('Webhook URL', 'pointly-booking')} hint={__('Add this endpoint in Stripe and send at least the checkout.session.completed and payment_intent.succeeded events.', 'pointly-booking')} className="bp-span-2">
									<Input readOnly dir="ltr" value={webhookUrl()} onFocus={(e) => e.target.select()} end={<Button variant="ghost" size="sm" icon="copy" onClick={() => copy(webhookUrl())}>{__('Copy', 'pointly-booking')}</Button>} />
								</Field>
								<Field label={__('Success page (optional)', 'pointly-booking')} hint={__('By default customers return to the page they booked on.', 'pointly-booking')}>
									<Input type="url" dir="ltr" value={v.stripe.success_url || ''} onChange={(e) => setIn('stripe', 'success_url', e.target.value)} placeholder="https://example.com/thank-you" />
								</Field>
								<Field label={__('Cancel page (optional)', 'pointly-booking')}>
									<Input type="url" dir="ltr" value={v.stripe.cancel_url || ''} onChange={(e) => setIn('stripe', 'cancel_url', e.target.value)} placeholder="https://example.com/cancelled" />
								</Field>
							</FormGrid>
						</Section>
					) : null}

					{active('paypal') ? (
						<Section title="PayPal" actions={<ModeSwitch value={v.paypal.mode === 'live' ? 'live' : 'test'} onChange={(m) => setIn('paypal', 'mode', m)} />}>
							<FormGrid>
								<Field label={__('Client ID', 'pointly-booking')} required error={problems.ppClient ? __('Required', 'pointly-booking') : undefined}>
									<Input autoComplete="off" dir="ltr" value={v.paypal.client_id || ''} onChange={(e) => setIn('paypal', 'client_id', e.target.value)} />
								</Field>
								<Field label={__('Secret', 'pointly-booking')} required error={problems.ppSecret ? __('Required', 'pointly-booking') : undefined}>
									<Input type="password" autoComplete="off" dir="ltr" value={v.paypal.secret || ''} onChange={(e) => setIn('paypal', 'secret', e.target.value)} />
								</Field>
								<Field label={__('Return page (optional)', 'pointly-booking')}>
									<Input type="url" dir="ltr" value={v.paypal.return_url || ''} onChange={(e) => setIn('paypal', 'return_url', e.target.value)} placeholder="https://example.com/thank-you" />
								</Field>
								<Field label={__('Cancel page (optional)', 'pointly-booking')}>
									<Input type="url" dir="ltr" value={v.paypal.cancel_url || ''} onChange={(e) => setIn('paypal', 'cancel_url', e.target.value)} placeholder="https://example.com/cancelled" />
								</Field>
							</FormGrid>
						</Section>
					) : null}

					{active('woocommerce') ? (
						<Section title="WooCommerce" description={__('The booking is paid through a WooCommerce product whose price is set to the booking total at checkout.', 'pointly-booking')}>
							<FormGrid>
								<Field label={__('Product ID', 'pointly-booking')} required error={problems.wc ? __('Enter the ID of a WooCommerce product', 'pointly-booking') : undefined}>
									<Input type="number" min="0" value={v.woocommerce.product_id || 0} onChange={(e) => setIn('woocommerce', 'product_id', Number(e.target.value || 0))} />
								</Field>
							</FormGrid>
						</Section>
					) : null}
				</>
			)}

			<SaveBar dirty={form.dirty} saving={saving} onSave={save} onDiscard={form.reset} disabled={blocked} error={blocked && form.dirty ? __('Some enabled providers are missing required fields.', 'pointly-booking') : ''} />
		</Page>
	);
}
