import { LayoutBase } from '../layouts/layout-base';
import { View, CSSType } from '../core/view';
import { Property, makeParser, makeValidator } from '../core/properties';
import { Color } from '../../color';
import type { SplitBehavior, SplitDisplayMode, SplitRole, SplitStyle } from '.';

const splitRoleConverter = makeParser<SplitRole>(makeValidator<SplitRole>('primary', 'secondary', 'supplementary', 'inspector'));
const splitDisplayModeConverter = makeParser<SplitDisplayMode>(makeValidator<SplitDisplayMode>('automatic', 'secondaryOnly', 'oneBesideSecondary', 'oneOverSecondary', 'twoBesideSecondary', 'twoOverSecondary', 'twoDisplaceSecondary'));
const splitBehaviorConverter = makeParser<SplitBehavior>(makeValidator<SplitBehavior>('automatic', 'tile', 'overlay', 'displace'));

// Default child roles (helps authoring without setting splitRole on children)
const ROLE_ORDER: SplitRole[] = ['primary', 'secondary', 'supplementary', 'inspector'];

@CSSType('SplitView')
export class SplitViewBase extends LayoutBase {
	/**
	 * The display style for the split view controller.
	 * Must be set before bootstrapping the app.
	 */
	static SplitStyle: SplitStyle;

	static getInstance(): SplitViewBase | null {
		// Platform-specific implementations may override
		return null;
	}

	/** Child role (primary, secondary, supplementary, inspector) */
	splitRole: SplitRole;
	/** Preferred display mode */
	displayMode: SplitDisplayMode;
	/** Preferred split behavior (iOS 14+) */
	splitBehavior: SplitBehavior;
	/** Primary column width fraction (0..1) */
	preferredPrimaryColumnWidthFraction: number;
	/** Supplementary column width fraction (0..1, iOS 14+ triple) */
	preferredSupplementaryColumnWidthFraction: number;
	/** Inspector column width fraction (0..1, iOS 17+/18+ when Inspector column available) */
	preferredInspectorColumnWidthFraction: number;
	/** Navigation bar tint color for buttons */
	navigationBarTintColor: Color;

	/**
	 * Get child role (primary, secondary, supplementary, inspector)
	 */
	public static getRole(element: SplitViewBase): SplitRole {
		return element.splitRole;
	}

	/**
	 * Set child role (primary, secondary, supplementary, inspector)
	 */
	public static setRole(element: SplitViewBase, value: SplitRole): void {
		element.splitRole = value;
	}

	// Called when a child's role changes; platform impls may override
	public onRoleChanged(view: View, oldValue: SplitRole, newValue: SplitRole) {
		this.requestLayout();
	}

	showPrimary() {
		// Platform-specific implementations may override
	}

	hidePrimary() {
		// Platform-specific implementations may override
	}

	showSecondary() {
		// Platform-specific implementations may override
	}

	hideSecondary() {
		// Platform-specific implementations may override
	}

	showSupplementary() {
		// Platform-specific implementations may override
	}

	hideSupplementary() {
		// Platform-specific implementations may override
	}

	showInspector() {
		// Platform-specific implementations may override
	}

	hideInspector() {
		// Platform-specific implementations may override
	}

	/**
	 * Invalidate layouts for all child views in the SplitView.
	 * Useful when columns change, orientation changes, or any scenario
	 * requiring a full layout refresh of all split view children.
	 * @param delay Optional delay in milliseconds (default 350ms to wait for animations)
	 */
	invalidateChildLayouts(delay: number = 0): void {
		// Platform-specific implementations may override
	}

	// Utility to infer a role by index when none specified
	protected _roleByIndex(index: number): SplitRole {
		return ROLE_ORDER[Math.max(0, Math.min(index, ROLE_ORDER.length - 1))];
	}
}

SplitViewBase.prototype.recycleNativeView = 'auto';

export const splitRoleProperty = new Property<View, SplitRole>({
	name: 'splitRole',
	defaultValue: 'primary',
	valueChanged: (target, oldValue, newValue) => {
		const parent = target.parent;
		if (parent instanceof SplitViewBase) {
			parent.onRoleChanged(target, oldValue, newValue);
		}
	},
	valueConverter: splitRoleConverter,
});
splitRoleProperty.register(View);

export const displayModeProperty = new Property<SplitViewBase, SplitDisplayMode>({
	name: 'displayMode',
	defaultValue: 'automatic',
	affectsLayout: __APPLE__,
	valueConverter: splitDisplayModeConverter,
});
displayModeProperty.register(SplitViewBase);

export const splitBehaviorProperty = new Property<SplitViewBase, SplitBehavior>({
	name: 'splitBehavior',
	defaultValue: 'automatic',
	affectsLayout: __APPLE__,
	valueConverter: splitBehaviorConverter,
});
splitBehaviorProperty.register(SplitViewBase);

export const preferredPrimaryColumnWidthFractionProperty = new Property<SplitViewBase, number>({
	name: 'preferredPrimaryColumnWidthFraction',
	defaultValue: 0,
	affectsLayout: __APPLE__,
	valueConverter: (v) => Math.max(0, Math.min(1, parseFloat(v))),
});
preferredPrimaryColumnWidthFractionProperty.register(SplitViewBase);

export const preferredSupplementaryColumnWidthFractionProperty = new Property<SplitViewBase, number>({
	name: 'preferredSupplementaryColumnWidthFraction',
	defaultValue: 0,
	affectsLayout: __APPLE__,
	valueConverter: (v) => Math.max(0, Math.min(1, parseFloat(v))),
});
preferredSupplementaryColumnWidthFractionProperty.register(SplitViewBase);

export const preferredInspectorColumnWidthFractionProperty = new Property<SplitViewBase, number>({
	name: 'preferredInspectorColumnWidthFraction',
	defaultValue: 0,
	affectsLayout: __APPLE__,
	valueConverter: (v) => Math.max(0, Math.min(1, parseFloat(v))),
});
preferredInspectorColumnWidthFractionProperty.register(SplitViewBase);

export const navigationBarTintColorProperty = new Property<SplitViewBase, Color>({
	name: 'navigationBarTintColor',
	equalityComparer: Color.equals,
	valueConverter: (v) => new Color(v),
});
navigationBarTintColorProperty.register(SplitViewBase);
