/**
 * The shapes PHP hands JavaScript.
 *
 * Every type here mirrors something a PHP file returns. There is no generation
 * step, so each one carries the file it mirrors — when that file changes, this
 * is the list of places to check.
 */

import type { LoadMode } from '../../common/privacy';

/** wp_localize_script( ..., 'razorbookingBoot', ... ) in class-razorbooking-admin.php */
export interface Boot {
	root: string;
	nonce: string;
	adminUrl: string;
	appUrl: string;
	siteName: string;
	/** wp-admin root — where "Exit setup" leaves to. */
	wpAdminUrl: string;
	/** The picture on the right of the setup screen (filter: razorbooking_setup_image). */
	setupImage: string;
	/** Signs the floating button preview URL (home page + rb_floating_preview). */
	floatingPreviewNonce: string;
	/** The WordPress display name of whoever is looking — for the greeting. */
	userName?: string;
	siteUrl: string;
	timezone: string;
	locale: string;
	version: string;
	mode: string;
	connection: Connection;
}

export type ConnectionStatus = 'connected' | 'degraded' | 'disconnected';

/** Razorbooking_Connection_Dto */
export interface Connection {
	status: ConnectionStatus;
	workspace: string | null;
	workspace_id: string | number | null;
	workspace_slug?: string | null;
	plan: string | null;
	currency?: string;
	timezone?: string;
	key_last4: string | null;
	connected_at: string | null;
	connected_by: string | null;
	last_sync: string | null;
	reason: string | null;
	site_uuid: string | null;
	site_url: string;
	origin_url: string | null;
	is_clone: boolean;
	is_ssl: boolean;
	/**
	 * The stored key's level: `integration` for a site key. A higher level
	 * only raises the switch-to-a-site-key notice; it never changes what the
	 * plugin shows.
	 */
	token_role?: 'integration' | 'owner' | string;
	token_name?: string | null;
	/** Where the key came from. Only a `connect` key may be revoked by this plugin. */
	key_source?: 'connect' | 'pasted' | '';
	/** True while the full-access-key notice should show. */
	owner_notice?: boolean;
	money?: Money;
	permissions?: string[];
	booking_page_url?: string | null;
}

/** How the business prints money — Razorbooking_Money_Format_Dto. */
export interface Money {
	code: string;
	symbol: string;
	symbol_position: 'before' | 'after';
	decimals: number;
}

/**
 * Razorbooking_Service_Dto.
 *
 * On a variation parent `duration` and `price` are null (they live on its
 * variations) and `price_from` is the lowest variation price.
 */
export interface Service {
	id: string;
	name: string;
	duration: number | null;
	price: number | null;
	price_type: string | null;
	sale_price: number | null;
	currency: string;
	/** Bookable on the storefront. The list toggles this in place. */
	active: boolean;
	/** Sort position. Reordering is a pairwise swap, not a re-index. */
	ord: number;
	category: { id?: number | string; name?: string } | null;
	image_url: string | null;
	description_html: string | null;
	has_variations: boolean;
	variation_count: number;
	price_from: number | null;
	staff_ids: string[];
	updated_at: string | null;
}

export interface Category {
	id: string;
	name: string;
	count?: number;
}

/** Razorbooking_Review_Dto */
export interface Review {
	id: string;
	author?: string | null;
	rating?: number | null;
	body?: string | null;
	created_at?: string | null;
	status?: string | null;
	reply?: string | null;
}

export interface GalleryItem {
	id: string;
	type: 'image' | 'video';
	url: string;
	thumb?: string | null;
	caption?: string | null;
}

export interface Faq {
	id: string;
	question: string;
	answer: string;
}

/** Razorbooking_Check_Dto */
export interface Diagnostics {
	[ group: string ]: Record< string, unknown >;
}

/** Razorbooking_Seo::settings() */
export interface SeoSettings {
	enabled: boolean;
	types: Record< SeoType, boolean >;
	conflict: { plugin: string | null; detected: boolean };
	preview?: unknown;
}

export type SeoType = 'local_business' | 'opening_hours' | 'service' | 'faq' | 'person';

/** Razorbooking_Embed::consent_details() — empty addresses until connected. */
export interface ConsentDetails {
	domain: string;
	script: string;
	cookies: { name: string; purpose: string; expiry: string }[];
}

/** Razorbooking_Settings_Screen_Dto. */
export interface Settings {
	delete_on_uninstall: boolean;
	/** Read-only here: it changes through `POST confirmation-page` (ConfirmationPageState). */
	confirmation_page: number;
	floating_enabled: boolean;
	floating_position: 'bottom-right' | 'bottom-left' | string;
	floating_label: string;
	floating_style: 'text' | 'icon_text' | 'icon';
	floating_scope: 'all' | string;
	floating_hide_on_booking_page: boolean;
	lazy_load: boolean;
	/** Settings → Privacy: when a page connects to RazorBooking (Razorbooking_Embed::load_mode()). */
	load_mode: LoadMode;
	/** Read-only: what to enter in a cookie consent plugin (Razorbooking_Embed::consent_details()). */
	consent_details?: ConsentDetails;
	preconnect: boolean;
	[ key: string ]: unknown;
}

/**
 * Razorbooking_Pages::confirmation_state() — `GET confirmation-page`, and the
 * answer to `POST confirmation-page { page_id }`.
 */
export interface ConfirmationPageState {
	/** This site's thank-you page (Settings `confirmation_page`), if it still exists. */
	/** `has_confirmation`: the page shows the Booking confirmation (block, shortcode or Elementor widget). */
	page: { id: number; title: string; status: string; url: string; edit_url: string; has_confirmation: boolean } | null;
	/** RazorBooking's confirmation page (booking preferences `confirmationUrl`). */
	razorbooking: {
		/** False when RazorBooking couldn't be asked just now. */
		known: boolean;
		/** False on a RazorBooking that doesn't have the setting yet. */
		supported: boolean;
		url: string | null;
	};
	/** Both say the same thing: this page's address, or none. */
	in_sync: boolean;
	/** After a save that only applied here (RazorBooking without the setting). */
	notice: string;
}

/** A WordPress page, as `GET pages` lists it. */
export interface WpPage {
	id: number;
	title: string;
	status: string;
	url: string;
	edit: string;
}
