/**
 * Usage Limit Checker
 * Validates usage limits before sending prompts and shows appropriate dialogs
 */

import { UsageSummary } from '@/hooks/use-limits';
import type { CloudflareDeploymentErrorCode } from '@/api-types';
import {
	Dialog,
	DialogContent,
	DialogDescription,
	DialogHeader,
	DialogTitle,
	DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { AlertCircle, ExternalLink } from 'lucide-react';
import { CloudflareLogo } from '@/components/icons/logos';
import { MINIMUM_CLOUDFLARE_BALANCE } from '../../shared/constants/limits';

export interface LimitCheckDialogResult {
	canProceed: boolean;
	dialogComponent?: React.ReactElement;
}


/**
 * Internal helper: Create "No Token" dialog
 */
function createNoTokenDialog(onConnect: () => void, onClose: () => void): React.ReactElement {
	return (
		<Dialog open={true} onOpenChange={onClose}>
			<DialogContent className="sm:max-w-md">
				<DialogHeader>
					<div className="mb-2">
						<AlertCircle className="h-10 w-10 text-text-tertiary" />
					</div>
					<DialogTitle className="text-xl">
						Daily free limit exhausted
					</DialogTitle>
					<DialogDescription className="pt-2 text-sm">
						You've used your free credits. Connect your Cloudflare account to continue building with your own credits.{' '}
						<a
							href="https://developers.cloudflare.com/ai-gateway/"
							target="_blank"
							rel="noopener noreferrer"
							className="text-blue-500 hover:text-blue-600 inline-flex items-center gap-0.5"
						>
							Learn more
							<ExternalLink className="h-3 w-3" />
						</a>
					</DialogDescription>
				</DialogHeader>
				<DialogFooter className="sm:justify-start gap-2">
					<Button
						type="button"
						onClick={() => {
							onClose();
							onConnect();
						}}
						className="w-full sm:w-auto bg-brand-primary hover:bg-brand-primary/90 text-white"
					>
						<CloudflareLogo className="w-4 h-4 mr-2" color1="#fff" color2="#fff" />
						Connect Cloudflare
					</Button>
					<Button
						type="button"
						variant="outline"
						onClick={onClose}
						className="w-full sm:w-auto"
					>
						Cancel
					</Button>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

/**
 * Internal helper: Create "Not Configured" dialog
 */
function createNotConfiguredDialog(onClose: () => void): React.ReactElement {
	return (
		<Dialog open={true} onOpenChange={onClose}>
			<DialogContent className="sm:max-w-md">
				<DialogHeader>
					<div className="mb-2">
						<AlertCircle className="h-10 w-10 text-text-tertiary" />
					</div>
					<DialogTitle className="text-xl">
						Configure AI Gateway
					</DialogTitle>
					<DialogDescription className="pt-2 text-sm">
						Your Cloudflare account is connected but you need to select an AI Gateway to continue.
					</DialogDescription>
				</DialogHeader>
				<DialogFooter className="sm:justify-start gap-2">
					<Button
						type="button"
						onClick={() => {
							onClose();
							window.location.href = '/settings?config_needed=true';
						}}
						className="w-full sm:w-auto bg-brand-primary hover:bg-brand-primary/90 text-white"
					>
						<CloudflareLogo className="w-4 h-4 mr-2" color1="#fff" color2="#fff" />
						Configure Gateway
					</Button>
					<Button
						type="button"
						variant="outline"
						onClick={onClose}
						className="w-full sm:w-auto"
					>
						Cancel
					</Button>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

/**
 * Internal helper: Create "Insufficient Balance" dialog
 */
function createInsufficientBalanceDialog(balance: number, accountId: string | undefined, onClose: () => void): React.ReactElement {
	return (
		<Dialog open={true} onOpenChange={onClose}>
			<DialogContent className="sm:max-w-md">
				<DialogHeader>
					<div className="mb-2">
						<AlertCircle className="h-10 w-10 text-text-tertiary" />
					</div>
					<DialogTitle className="text-xl">
						Insufficient credits
					</DialogTitle>
					<DialogDescription className="pt-2 text-sm">
						Your Cloudflare account has ${balance.toFixed(2)} in credits. Add more credits to continue building.{' '}
						<a
							href="https://developers.cloudflare.com/ai-gateway/"
							target="_blank"
							rel="noopener noreferrer"
							className="text-blue-500 hover:text-blue-600 inline-flex items-center gap-0.5"
						>
							Learn more
							<ExternalLink className="h-3 w-3" />
						</a>
					</DialogDescription>
				</DialogHeader>
				<DialogFooter className="sm:justify-start gap-2">
					<Button
						type="button"
						onClick={() => {
							onClose();
							const url = accountId 
								? `https://dash.cloudflare.com/${accountId}/ai/ai-gateway/credits`
								: 'https://dash.cloudflare.com';
							window.open(url, '_blank', 'noopener,noreferrer');
						}}
						className="w-full sm:w-auto bg-brand-primary hover:bg-brand-primary/90 text-white"
					>
						<ExternalLink className="w-4 h-4 mr-2" />
						Add Credits
					</Button>
					<Button
						type="button"
						variant="outline"
						onClick={onClose}
						className="w-full sm:w-auto"
					>
						Cancel
					</Button>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

/**
 * Internal helper: Create "Connect to Deploy" dialog
 * Shown when a user-account deploy fails because no Cloudflare OAuth token exists.
 */
function createDeployConnectDialog(onConnect: () => void, onClose: () => void): React.ReactElement {
	return (
		<Dialog open={true} onOpenChange={onClose}>
			<DialogContent className="sm:max-w-md">
				<DialogHeader>
					<div className="mb-2">
						<AlertCircle className="h-10 w-10 text-text-tertiary" />
					</div>
					<DialogTitle className="text-xl">
						Connect Cloudflare to deploy
					</DialogTitle>
					<DialogDescription className="pt-2 text-sm">
						Connect your Cloudflare account to deploy this app to your own Workers account and keep it running on your credits.
					</DialogDescription>
				</DialogHeader>
				<DialogFooter className="sm:justify-start gap-2">
					<Button
						type="button"
						onClick={() => {
							onClose();
							onConnect();
						}}
						className="w-full sm:w-auto bg-brand-primary hover:bg-brand-primary/90 text-white"
					>
						<CloudflareLogo className="w-4 h-4 mr-2" color1="#fff" color2="#fff" />
						Connect Cloudflare
					</Button>
					<Button
						type="button"
						variant="outline"
						onClick={onClose}
						className="w-full sm:w-auto"
					>
						Cancel
					</Button>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

/**
 * Internal helper: Create "Select account to Deploy" dialog
 * Shown when a user-account deploy fails because no account/gateway is selected.
 */
function createDeployNotConfiguredDialog(onClose: () => void): React.ReactElement {
	return (
		<Dialog open={true} onOpenChange={onClose}>
			<DialogContent className="sm:max-w-md">
				<DialogHeader>
					<div className="mb-2">
						<AlertCircle className="h-10 w-10 text-text-tertiary" />
					</div>
					<DialogTitle className="text-xl">
						Select a Cloudflare account
					</DialogTitle>
					<DialogDescription className="pt-2 text-sm">
						You have multiple Cloudflare accounts connected. Select which one to deploy to in Settings.
					</DialogDescription>
				</DialogHeader>
				<DialogFooter className="sm:justify-start gap-2">
					<Button
						type="button"
						onClick={() => {
							onClose();
							window.location.href = '/settings?config_needed=true';
						}}
						className="w-full sm:w-auto bg-brand-primary hover:bg-brand-primary/90 text-white"
					>
						<CloudflareLogo className="w-4 h-4 mr-2" color1="#fff" color2="#fff" />
						Open Settings
					</Button>
					<Button
						type="button"
						variant="outline"
						onClick={onClose}
						className="w-full sm:w-auto"
					>
						Cancel
					</Button>
				</DialogFooter>
			</DialogContent>
		</Dialog>
	);
}

/**
 * Map a backend `cloudflare_deployment_error` code to the matching
 * connection-gate dialog. Returns null for codes that shouldn't pop a dialog
 * (generic deploy failures keep the toast/chat-message treatment).
 */
export function getDeployGateDialog(
	code: CloudflareDeploymentErrorCode,
	onConnect: () => void,
	onClose: () => void
): React.ReactElement | null {
	switch (code) {
		case 'cloudflare_not_connected':
			return createDeployConnectDialog(onConnect, onClose);
		case 'cloudflare_not_configured':
			return createDeployNotConfiguredDialog(onClose);
		default:
			return null;
	}
}

/**
 * Check if user can send a prompt and return appropriate dialog if blocked
 */
export function checkCanSendPrompt(
	limitsData: UsageSummary | null,
	loading: boolean,
	onConnect: () => void,
	onClose: () => void
): LimitCheckDialogResult {
	// If loading or no data, allow proceed (optimistic)
	if (loading || !limitsData) {
		return { canProceed: true };
	}

	const { limitCheck, hasUserToken, hasCloudflareConfigured, cloudflareCredits } = limitsData;

	// If within limits, allow proceed
	if (limitCheck.withinLimits) {
		return { canProceed: true };
	}

	// Free limits are exhausted, check Cloudflare status
	
	// Case 1: No Cloudflare token connected
	if (!hasUserToken) {
		return {
			canProceed: false,
			dialogComponent: createNoTokenDialog(onConnect, onClose),
		};
	}

	// Case 2: Has token but not configured (no AI Gateway setup)
	if (hasUserToken && !hasCloudflareConfigured) {
		return {
			canProceed: false,
			dialogComponent: createNotConfiguredDialog(onClose),
		};
	}

	// Case 3: Configured but insufficient credits
	if (hasUserToken && hasCloudflareConfigured) {
		const credits = cloudflareCredits?.credits ?? 0;
		
		if (credits < MINIMUM_CLOUDFLARE_BALANCE) {
			return {
				canProceed: false,
				dialogComponent: createInsufficientBalanceDialog(
					credits,
					cloudflareCredits?.accountId,
					onClose
				),
			};
		}
	}

	// If we got here, user has token, is configured, and has enough credits
	return { canProceed: true };
}

/**
 * Get appropriate dialog for backend limit error
 * Backend sends generic USAGE_LIMIT_EXCEEDED - frontend uses its own limitsData to determine which dialog
 * Reuses the same logic and dialogs as checkCanSendPrompt for consistency
 */
export function getBackendLimitDialog(
	limitsData: UsageSummary | null,
	onConnect: () => void,
	onClose: () => void
): LimitCheckDialogResult {
	// Use the same logic as checkCanSendPrompt, but don't check if within limits
	// (backend already determined limits are exceeded)
	if (!limitsData) {
		return { canProceed: true };
	}

	const { hasUserToken, hasCloudflareConfigured, cloudflareCredits } = limitsData;

	// Case 1: No Cloudflare token connected
	if (!hasUserToken) {
		return {
			canProceed: false,
			dialogComponent: createNoTokenDialog(onConnect, onClose),
		};
	}

	// Case 2: Has token but not configured (no AI Gateway setup)
	if (hasUserToken && !hasCloudflareConfigured) {
		return {
			canProceed: false,
			dialogComponent: createNotConfiguredDialog(onClose),
		};
	}

	// Case 3: Configured but insufficient credits
	if (hasUserToken && hasCloudflareConfigured) {
		const credits = cloudflareCredits?.credits ?? 0;
		
		if (credits < MINIMUM_CLOUDFLARE_BALANCE) {
			return {
				canProceed: false,
				dialogComponent: createInsufficientBalanceDialog(
					credits,
					cloudflareCredits?.accountId,
					onClose
				),
			};
		}
	}

	// Unknown state - should not block
	return { canProceed: true };
}
