import { useCallback, useEffect, useRef, useState } from 'react';
import { Alert, Button, Card, Space, Tag, Typography } from 'antd';
import apiFetch from '@wordpress/api-fetch';
import { __, sprintf } from '@wordpress/i18n';
import './setupHealth.scss';

const { Paragraph, Title, Text } = Typography;
const statuses = {
	pass: { color: 'success', label: __( 'Passed', 'sa-hosted-checkout-for-woocommerce' ) },
	warning: { color: 'warning', label: __( 'Review needed', 'sa-hosted-checkout-for-woocommerce' ) },
	error: { color: 'error', label: __( 'Action required', 'sa-hosted-checkout-for-woocommerce' ) },
	info: { color: 'default', label: __( 'Information', 'sa-hosted-checkout-for-woocommerce' ) },
};
const summaries = {
	ready: __( 'Configuration checks passed', 'sa-hosted-checkout-for-woocommerce' ),
	attention: __( 'Some checks need review', 'sa-hosted-checkout-for-woocommerce' ),
	incomplete: __( 'Setup is incomplete', 'sa-hosted-checkout-for-woocommerce' ),
};
const checkoutNames = {
	hosted: __( 'Hosted Checkout', 'sa-hosted-checkout-for-woocommerce' ),
	embedded_page: __( 'Embedded payment page', 'sa-hosted-checkout-for-woocommerce' ),
	embedded_popup: __( 'Embedded popup', 'sa-hosted-checkout-for-woocommerce' ),
};

function validResponse( response ) {
	return response && [ 'test', 'live' ].includes( response.mode ) &&
		Object.prototype.hasOwnProperty.call( checkoutNames, response.checkout_mode ) &&
		Object.prototype.hasOwnProperty.call( summaries, response.summary ) &&
		typeof response.generated_at === 'string' &&
		Number.isFinite( Date.parse( response.generated_at ) ) &&
		typeof response.support_report === 'string' &&
		Array.isArray( response.checks ) && response.checks.length > 0 &&
		response.checks.every( ( check ) => check && typeof check.id === 'string' &&
			typeof check.label === 'string' && typeof check.message === 'string' &&
			Object.prototype.hasOwnProperty.call( statuses, check.status ) );
}

function ExternalLink( { href, children } ) {
	return <a href={ href } target="_blank" rel="noopener noreferrer">{ children }<span className="screen-reader-text">{ __( ' (opens in a new tab)', 'sa-hosted-checkout-for-woocommerce' ) }</span></a>;
}

export default function SetupHealth( { active = true, onNavigate = () => {} } ) {
	const [ data, setData ] = useState( null );
	const [ pending, setPending ] = useState( '' );
	const [ failure, setFailure ] = useState( '' );
	const [ copyStatus, setCopyStatus ] = useState( '' );
	const [ showReport, setShowReport ] = useState( false );
	const request = useRef( null );
	const sequence = useRef( 0 );
	const reportRef = useRef( null );

	const refresh = useCallback( async ( connect = false ) => {
		request.current?.abort();
		const controller = new AbortController();
		request.current = controller;
		const current = ++sequence.current;
		setPending( connect ? 'connection' : 'refresh' );
		setFailure( '' );
		setCopyStatus( '' );
		setShowReport( false );
		try {
			const response = await apiFetch( {
				path: '/sahcfwc/v1/setup-health' + ( connect ? '/check' : '' ),
				method: connect ? 'POST' : 'GET',
				signal: controller.signal,
			} );
			if ( current !== sequence.current ) { return; }
			if ( ! validResponse( response ) ) { throw new Error( 'Invalid health response' ); }
			setData( response );
		} catch ( error ) {
			if ( current !== sequence.current || controller.signal.aborted ) { return; }
			// Never render API error details: a provider or proxy can echo credentials.
			setFailure( connect ? 'connection' : 'refresh' );
		} finally {
			if ( current === sequence.current ) { setPending( '' ); }
		}
	}, [] );

	useEffect( () => {
		if ( active ) { refresh(); }
		return () => {
			++sequence.current;
			request.current?.abort();
		};
	}, [ active, refresh ] );

	useEffect( () => {
		if ( showReport && reportRef.current ) {
			reportRef.current.focus();
			reportRef.current.select();
		}
	}, [ showReport ] );

	async function copyReport() {
		setCopyStatus( '' );
		if ( ! data || pending || failure ) { return; }
		try {
			if ( ! navigator.clipboard?.writeText ) { throw new Error( 'Clipboard unavailable' ); }
			await navigator.clipboard.writeText( data.support_report );
			setCopyStatus( __( 'Support report copied.', 'sa-hosted-checkout-for-woocommerce' ) );
		} catch ( error ) {
			setShowReport( true );
			setCopyStatus( __( 'Automatic copying is unavailable. Select and copy the report below.', 'sa-hosted-checkout-for-woocommerce' ) );
		}
	}

	const busy = pending !== '';
	const checkedAt = data ? new Date( data.generated_at ).toLocaleString() : '';
	const dashboard = data?.mode === 'test' ? 'https://dashboard.stripe.com/test/webhooks' : 'https://dashboard.stripe.com/webhooks';
	return (
		<section className="sahcfwc-setup-health" aria-labelledby="sahcfwc-setup-health-title" data-testid="setup-health">
			<Title level={ 2 } id="sahcfwc-setup-health-title">{ __( 'Setup & health', 'sa-hosted-checkout-for-woocommerce' ) }</Title>
			<Paragraph>{ __( 'Follow these steps to connect Stripe, choose a checkout experience and verify your store before accepting payments.', 'sa-hosted-checkout-for-woocommerce' ) }</Paragraph>
			<ol className="sahcfwc-setup-health-steps" aria-label={ __( 'Setup steps', 'sa-hosted-checkout-for-woocommerce' ) }>
				<li>
					<h3>{ __( '1. Connect Stripe', 'sa-hosted-checkout-for-woocommerce' ) }</h3>
					<p>{ __( 'Start in test mode. Save your Stripe API key, the matching publishable key for Embedded Checkout, and the webhook signing secret in Stripe Settings.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<Button onClick={ () => onNavigate( '1' ) }>{ __( 'Open Stripe Settings', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
				</li>
				<li>
					<h3>{ __( '2. Choose your checkout', 'sa-hosted-checkout-for-woocommerce' ) }</h3>
					<p>{ __( 'Select Hosted Checkout, Embedded payment page or Embedded popup in Stripe Settings. For Embedded Checkout, use Automatic to create the payment page or choose a valid existing page. Enable checkout and save.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<Space wrap>
						<Button onClick={ () => onNavigate( '1' ) }>{ __( 'Choose checkout experience', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
						<Button onClick={ () => onNavigate( '2' ) }>{ __( 'Checkout Settings', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
						<Button onClick={ () => onNavigate( '3' ) }>{ __( 'Payment Methods', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
					</Space>
				</li>
				<li>
					<h3>{ __( '3. Verify a test payment', 'sa-hosted-checkout-for-woocommerce' ) }</h3>
					<p>{ __( 'Using Stripe test mode, complete a checkout with your products and charges. Confirm that the WooCommerce order is paid and that Stripe shows a successful webhook delivery. These checks do not submit a payment or prove that a payment succeeded.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<ExternalLink href="https://docs.stripe.com/testing">{ __( 'Stripe test payment guide', 'sa-hosted-checkout-for-woocommerce' ) }</ExternalLink>
				</li>
			</ol>

			<Card className="sahcfwc-setup-health-checks" title={ __( 'Saved configuration checks', 'sa-hosted-checkout-for-woocommerce' ) }>
				<Paragraph>{ __( 'Checks use saved settings only. Save any changes in the settings tabs, then return here or refresh. Refreshing reads local checks and any cached Stripe connection result; it does not contact Stripe.', 'sa-hosted-checkout-for-woocommerce' ) }</Paragraph>
				<Space wrap className="sahcfwc-setup-health-actions">
					<Button onClick={ () => refresh() } loading={ pending === 'refresh' } disabled={ busy } data-testid="health-refresh">{ __( 'Refresh checks', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
					<Button type="primary" onClick={ () => refresh( true ) } loading={ pending === 'connection' } disabled={ busy || ! data } data-testid="health-connect">{ __( 'Check Stripe connection', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
					<Button onClick={ copyReport } disabled={ busy || ! data || !! failure } data-testid="health-copy">{ __( 'Copy support report', 'sa-hosted-checkout-for-woocommerce' ) }</Button>
				</Space>
				<Paragraph type="secondary">{ __( 'Check Stripe connection makes a read-only request using your saved API key for the selected mode. It does not create payments or change Stripe settings. Recent results may be reused briefly to avoid repeated requests.', 'sa-hosted-checkout-for-woocommerce' ) }</Paragraph>
				<div className="sahcfwc-setup-health-status" role="status" aria-live="polite" aria-atomic="true">
					{ busy ? __( 'Checking saved configuration…', 'sa-hosted-checkout-for-woocommerce' ) : data && ! failure ? summaries[ data.summary ] : '' }
				</div>
				{ failure && <Alert type="error" showIcon message={ __( 'Unable to refresh the checks', 'sa-hosted-checkout-for-woocommerce' ) } description={ __( 'Check your administrator session and network connection, then try again. Any results below are from the previous successful check and may be outdated.', 'sa-hosted-checkout-for-woocommerce' ) } action={ <Button disabled={ busy } onClick={ () => refresh( failure === 'connection' ) }>{ __( 'Try again', 'sa-hosted-checkout-for-woocommerce' ) }</Button> } /> }
				{ data && <>
					<Paragraph className="sahcfwc-setup-health-context">
						<Text strong>{ data.mode === 'test' ? __( 'Test mode', 'sa-hosted-checkout-for-woocommerce' ) : __( 'Live mode', 'sa-hosted-checkout-for-woocommerce' ) }</Text>{ ' · ' }{ checkoutNames[ data.checkout_mode ] }<br />
						<Text type="secondary">{ sprintf(
							// translators: %s: Localized date and time when the local checks were refreshed.
							__( 'Local checks refreshed: %s. Connection and webhook evidence have their own timestamps below.', 'sa-hosted-checkout-for-woocommerce' ), checkedAt ) }</Text>
					</Paragraph>
					<ul className="sahcfwc-setup-health-results" aria-label={ __( 'Configuration check results', 'sa-hosted-checkout-for-woocommerce' ) } aria-busy={ busy }>
						{ data.checks.map( ( check ) => <li key={ check.id } data-check-id={ check.id }>
							<div className="sahcfwc-setup-health-result-title"><h3>{ check.label }</h3><Tag color={ statuses[ check.status ].color }>{ statuses[ check.status ].label }</Tag></div>
							<p>{ check.message }</p>
						</li> ) }
					</ul>
				</> }
				<Paragraph type="secondary">{ __( 'The support report contains version information, configuration states and diagnostic messages only. It excludes API keys, signing secrets, site addresses and customer or order details. Review it before sharing.', 'sa-hosted-checkout-for-woocommerce' ) }</Paragraph>
				<div role="status" aria-live="polite">{ copyStatus }</div>
				{ showReport && data && <div className="sahcfwc-setup-health-report">
					<label htmlFor="sahcfwc-health-report">{ __( 'Support report', 'sa-hosted-checkout-for-woocommerce' ) }</label>
					<textarea ref={ reportRef } id="sahcfwc-health-report" readOnly value={ data.support_report } rows={ 12 } />
				</div> }
			</Card>

			<div className="sahcfwc-setup-health-guides">
				<details>
					<summary>{ __( 'How to configure and verify the webhook', 'sa-hosted-checkout-for-woocommerce' ) }</summary>
					<ol>
						<li>{ __( 'Copy the webhook endpoint URL shown in Stripe Settings. Do not use the WordPress admin settings page URL.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
						<li>{ __( 'In Stripe Workbench, open Webhooks in the matching test or live environment. Create an event destination for your account, choose Snapshot payloads, and select these events:', 'sa-hosted-checkout-for-woocommerce' ) }
							<ul><li><code>checkout.session.completed</code></li><li><code>checkout.session.async_payment_succeeded</code></li><li><code>checkout.session.async_payment_failed</code></li></ul>
						</li>
						<li>{ __( 'For refund synchronization, also select these events. Refund events do not count as proof of Checkout payment delivery:', 'sa-hosted-checkout-for-woocommerce' ) }
							<ul><li><code>refund.created</code></li><li><code>refund.updated</code></li><li><code>refund.failed</code></li></ul>
						</li>
						<li>{ __( 'Choose Webhook endpoint, paste the copied endpoint URL and create the destination. Save its signing secret in Stripe Settings without sharing it.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
						<li>{ __( 'For sandbox verification, first select test mode and matching test keys in the plugin, then complete a test checkout and inspect the test destination deliveries. In live mode, inspect the live destination and redeliver an existing matching live Checkout event if available. Sandbox events do not verify live delivery. Refresh these checks afterwards; a received event does not by itself prove an order was paid.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
					</ol>
					<p>{ __( 'Stripe cannot deliver directly to localhost or a private network address. For local testing, use Stripe CLI forwarding with its own signing secret or a securely configured public HTTPS tunnel. Live stores need a publicly accessible HTTPS endpoint and the live destination’s signing secret.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<Space wrap><ExternalLink href={ dashboard }>{ __( 'Open Stripe Webhooks', 'sa-hosted-checkout-for-woocommerce' ) }</ExternalLink><ExternalLink href="https://docs.stripe.com/webhooks">{ __( 'Stripe webhook instructions', 'sa-hosted-checkout-for-woocommerce' ) }</ExternalLink></Space>
				</details>
				<details>
					<summary>{ __( 'How amount-only refunds work', 'sa-hosted-checkout-for-woocommerce' ) }</summary>
					<ol>
						<li>{ __( 'Open the paid order in WooCommerce and find Stripe refunds. Select Refresh Stripe status to verify the original payment and any existing refunds.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
						<li>{ __( 'Enter a partial amount or choose Use remaining amount. Review the amount, currency and original payment mode, then confirm the refund request.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
						<li>{ __( 'If a request is pending or its outcome is unknown, refresh its status instead of creating another refund. WooCommerce records the refund only after Stripe confirms success. Review warnings must be resolved before requesting more money back.', 'sa-hosted-checkout-for-woocommerce' ) }</li>
					</ol>
					<p>{ __( 'These refunds do not restock products or allocate amounts to product, fee, shipping or tax lines. Do not add a second manual WooCommerce refund for a Stripe refund already recorded by this plugin. Keep the original payment mode API key available when switching the storefront between test and live mode.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
				</details>
				<details>
					<summary>{ __( 'Wallets, HTTPS and going live', 'sa-hosted-checkout-for-woocommerce' ) }</summary>
					<p>{ __( 'For Embedded Checkout, check payment-method domain registration in Stripe for the actual domain used by your payment page. Apple Pay and Google Pay also depend on Stripe eligibility, enabled methods, the customer’s browser and device. Saving keys or passing a connection check does not verify wallet availability.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<p>{ __( 'Keep the payment page and its private query-string URLs out of page caches. Use HTTPS in production. Before going live, switch to matching live API keys and the live webhook signing secret, repeat these configuration checks, and confirm that your store’s required payment methods are available.', 'sa-hosted-checkout-for-woocommerce' ) }</p>
					<ExternalLink href="https://docs.stripe.com/payments/payment-methods/pmd-registration">{ __( 'Stripe payment-method domain instructions', 'sa-hosted-checkout-for-woocommerce' ) }</ExternalLink>
				</details>
			</div>
		</section>
	);
}
