import { useState } from "react";

import { MobileListView } from "../mobile/mobile-list-view";
import { MobileDetailView } from "../mobile/mobile-detail-view";
import { MobileEditView } from "../mobile/mobile-edit-view";
import { MobileFAB } from "../mobile/mobile-fab";
import { GitMountEditor } from "../git/git-mount-editor";
import { Icon } from "../../icon";
import type {
	ConfigProfile,
	CreateConfigProfileRequest,
	ResolvedProfile,
} from "../../../api/config-profiles";
import type { ProjectWithRepos } from "../../../types";
import type { ToolType } from "../../../api/tool-types";

type MobileView = "list" | "detail" | "edit" | "preview";

interface Props {
	profiles: ConfigProfile[];
	projects: ProjectWithRepos[];
	toolTypes: ToolType[];
	selectedProfile: ConfigProfile | null;
	mobileView: MobileView;
	isCreating: boolean;
	formData: CreateConfigProfileRequest;
	includedProfileIds: string[];
	availableProfiles: ConfigProfile[];
	previewData: ResolvedProfile | null;
	previewingId: string | null;
	saveStatus: "idle" | "saving" | "saved" | "error";
	error: string | null;
	onViewChange: (view: MobileView) => void;
	onSelect: (profile: ConfigProfile) => void;
	onCreate: () => void;
	onDelete: (id: string) => void;
	onFormChange: <K extends keyof CreateConfigProfileRequest>(
		key: K,
		value: CreateConfigProfileRequest[K],
	) => void;
	onSubmit: (e?: React.FormEvent) => Promise<boolean>;
	getScopeLabel: (profile: ConfigProfile) => string;
	getIncludedProfile: (id: string) => ConfigProfile | undefined;
	onAddInclude: (id: string) => void;
	onRemoveInclude: (index: number) => void;
	onAddEnvVar: () => void;
	onUpdateEnvVar: (oldKey: string, newKey: string, value: string) => void;
	onRemoveEnvVar: (key: string) => void;
	onAddFile: () => void;
	onUpdateFile: (oldPath: string, newPath: string, content: string) => void;
	onRemoveFile: (path: string) => void;
	onAddMount: () => void;
	onUpdateMount: (
		index: number,
		updates: Partial<ConfigProfile["mounts"][0]>,
	) => void;
	onRemoveMount: (index: number) => void;
	onAddMountFile: (mountIndex: number) => void;
	onUpdateMountFile: (
		mountIndex: number,
		oldPath: string,
		newPath: string,
		content: string,
	) => void;
	onRemoveMountFile: (mountIndex: number, path: string) => void;
	onPreview: (id: string) => void;
	onClosePreview: () => void;
}

export const ConfigProfilesMobileView = ({
	profiles,
	projects,
	toolTypes,
	selectedProfile,
	mobileView,
	isCreating,
	formData,
	includedProfileIds,
	availableProfiles,
	previewData,
	previewingId,
	saveStatus,
	error,
	onViewChange,
	onSelect,
	onCreate,
	onDelete,
	onFormChange,
	onSubmit,
	getScopeLabel,
	getIncludedProfile,
	onAddInclude,
	onRemoveInclude,
	onAddEnvVar,
	onUpdateEnvVar,
	onRemoveEnvVar,
	onAddFile,
	onUpdateFile,
	onRemoveFile,
	onAddMount,
	onUpdateMount,
	onRemoveMount,
	onAddMountFile,
	onUpdateMountFile,
	onRemoveMountFile,
	onPreview,
	onClosePreview,
}: Props) => {
	const [isSaving, setIsSaving] = useState(false);

	const handleSave = async () => {
		setIsSaving(true);
		try {
			const ok = await onSubmit();
			if (ok) {
				onViewChange(isCreating ? "list" : "edit");
			}
		} finally {
			setIsSaving(false);
		}
	};

	const handleDeleteClick = () => {
		if (selectedProfile) {
			onDelete(selectedProfile.id);
			onViewChange("list");
		}
	};

	const projectName = (id?: string) =>
		projects.find((p) => p.id === id)?.name || id || "None";

	const toolTypeName = (id?: string) =>
		toolTypes.find((t) => t.id === id)?.display_name || id || "None";

	if (mobileView === "list") {
		return (
			<div className="mobile-page">
				<div className="mobile-page-header">
					<h1>Config Profiles</h1>
					<span className="muted">{profiles.length} profiles</span>
				</div>
				<MobileListView
					items={profiles.map((profile) => ({
						id: profile.id,
						title: profile.name,
						subtitle: profile.description || getScopeLabel(profile),
					}))}
					onItemClick={(id: string) => {
						const profile = profiles.find((p) => p.id === id);
						if (profile) {
							onSelect(profile);
							onViewChange("edit");
						}
					}}
					onItemDelete={(id: string) => onDelete(id)}
					emptyMessage="No config profiles yet"
				/>
				<MobileFAB
					onClick={() => {
						onCreate();
						onViewChange("edit");
					}}
				/>
			</div>
		);
	}

	if (mobileView === "preview" && selectedProfile && previewData) {
		return (
			<div className="mobile-edit-view">
				<header className="mobile-edit-header">
					<button
						className="mobile-edit-cancel"
						onClick={() => onViewChange("detail")}
						type="button"
					>
						Back
					</button>
					<h1 className="mobile-edit-title">Resolved Preview</h1>
					<div style={{ width: "4rem" }} />
				</header>
				<div className="mobile-edit-form">
					<div className="mobile-form-group">
						<label className="mobile-form-label">Profile</label>
						<p>{previewData.profile_name}</p>
					</div>

					{previewData.included_profiles.length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Included Profiles</label>
							<ul className="mobile-list-plain">
								{previewData.included_profiles.map((p) => (
									<li key={p.id}>{p.name}</li>
								))}
							</ul>
						</div>
					)}

					{Object.keys(previewData.env_vars).length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Environment Variables</label>
							<pre className="mobile-preview-code">
								{JSON.stringify(previewData.env_vars, null, 2)}
							</pre>
						</div>
					)}

					{Object.keys(previewData.runtime_hints).length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Runtime Hints</label>
							<pre className="mobile-preview-code">
								{JSON.stringify(previewData.runtime_hints, null, 2)}
							</pre>
						</div>
					)}

					{previewData.mounts.length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Mounts</label>
							{previewData.mounts.map((m, idx) => (
								<div key={idx} className="mobile-preview-item">
									<strong>
										{m.target} ({m.mode})
									</strong>
									{Object.keys(m.files).length > 0 && (
										<pre className="mobile-preview-code">
											{JSON.stringify(m.files, null, 2)}
										</pre>
									)}
								</div>
							))}
						</div>
					)}

					{previewData.git_mounts.length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Git Mounts</label>
							{previewData.git_mounts.map((m, idx) => (
								<div key={idx} className="mobile-preview-item">
									<strong>
										{m.remote_url}
										{m.branch ? ` @${m.branch}` : ""}
									</strong>
									{m.mappings.map((mapping, mi) => (
										<div
											key={mi}
											className="mobile-preview-mapping"
										>
											{mapping.source_path || "."} →{" "}
											{mapping.target_path}
										</div>
									))}
								</div>
							))}
						</div>
					)}

					{Object.keys(previewData.files).length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Files</label>
							<pre className="mobile-preview-code">
								{JSON.stringify(previewData.files, null, 2)}
							</pre>
						</div>
					)}

					{Object.keys(previewData.overrides.env_vars).length > 0 && (
						<div className="mobile-form-group">
							<label className="mobile-form-label">Overrides</label>
							<pre className="mobile-preview-code">
								{JSON.stringify(previewData.overrides, null, 2)}
							</pre>
						</div>
					)}
				</div>
			</div>
		);
	}

	if (mobileView === "detail" && selectedProfile) {
		const fields = [
			{ label: "Name", value: selectedProfile.name },
			{
				label: "Description",
				value: selectedProfile.description || null,
			},
			{ label: "Scope", value: getScopeLabel(selectedProfile) },
			{ label: "Project", value: projectName(selectedProfile.project_id || undefined) },
			{ label: "Tool Type", value: toolTypeName(selectedProfile.tool_type_id || undefined) },
			{
				label: "Default",
				value: selectedProfile.is_default,
				type: "boolean" as const,
			},
			{
				label: "Includes",
				value:
					selectedProfile.includes.length > 0
						? selectedProfile.includes
								.map(
									(inc) =>
										getIncludedProfile(inc.included_profile_id)?.name ||
										inc.included_profile_id,
								)
								.join(", ")
						: null,
			},
			{
				label: "Environment Variables",
				value:
					Object.keys(selectedProfile.env_vars).length > 0
						? Object.entries(selectedProfile.env_vars)
								.map(([k, v]) => `${k}=${v}`)
								.join(", ")
						: null,
			},
			{
				label: "Runtime Hints",
				value:
					Object.keys(selectedProfile.runtime_hints).length > 0
						? JSON.stringify(selectedProfile.runtime_hints, null, 2)
						: null,
				type: "code" as const,
			},
			{
				label: "Files",
				value:
					Object.keys(selectedProfile.files).length > 0
						? Object.keys(selectedProfile.files).join(", ")
						: null,
			},
			{
				label: "Mounts",
				value:
					selectedProfile.mounts.length > 0
						? selectedProfile.mounts
								.map((m) => `${m.target} (${m.mode})`)
								.join(", ")
						: null,
			},
			{
				label: "Git Mounts",
				value:
					selectedProfile.git_mounts.length > 0
						? selectedProfile.git_mounts
								.map((m) => m.remote_url)
								.join(", ")
						: null,
			},
		];

		return (
			<MobileDetailView
				title={selectedProfile.name}
				subtitle={getScopeLabel(selectedProfile)}
				fields={fields}
				onBack={() => onViewChange("list")}
				onEdit={() => {
					onSelect(selectedProfile);
					onViewChange("edit");
				}}
				onDelete={handleDeleteClick}
			>
				<div className="mobile-detail-actions-extra">
					<button
						type="button"
						className="secondary-button"
						disabled={previewingId === selectedProfile.id}
						onClick={() => {
							onClosePreview();
							void onPreview(selectedProfile.id);
							onViewChange("preview");
						}}
					>
						{previewingId === selectedProfile.id ? (
							<>
								<Icon name="loading" size="sm" />
								Previewing...
							</>
						) : (
							<>
								<Icon name="info" size="sm" />
								Preview
							</>
						)}
					</button>
				</div>
			</MobileDetailView>
		);
	}

	if (mobileView === "edit") {
		return (
			<MobileEditView
				title={isCreating ? "Create Profile" : "Edit Profile"}
				onCancel={() => {
					onViewChange("list");
				}}
				onSave={handleSave}
				onDelete={isCreating ? undefined : handleDeleteClick}
				deleteLabel="Delete Profile"
				isSaving={isSaving || saveStatus === "saving"}
			>
				<div className="mobile-form-group">
					<label className="mobile-form-label" htmlFor="cp-name">
						Name *
					</label>
					<input
						id="cp-name"
						type="text"
						value={formData.name}
						onChange={(e) => onFormChange("name", e.target.value)}
						placeholder="e.g., Development Environment"
						className="mobile-form-input"
						required
					/>
				</div>

				<div className="mobile-form-group">
					<label className="mobile-form-label" htmlFor="cp-description">
						Description
					</label>
					<input
						id="cp-description"
						type="text"
						value={formData.description || ""}
						onChange={(e) =>
							onFormChange("description", e.target.value || undefined)
						}
						placeholder="Optional description"
						className="mobile-form-input"
					/>
				</div>

				<div className="mobile-form-group">
					<label className="mobile-form-label" htmlFor="cp-project">
						Project
					</label>
					<select
						id="cp-project"
						value={formData.project_id || ""}
						onChange={(e) =>
							onFormChange("project_id", e.target.value || undefined)
						}
						className="mobile-form-select"
					>
						<option value="">None (Global)</option>
						{projects.map((project) => (
							<option key={project.id} value={project.id}>
								{project.name}
							</option>
						))}
					</select>
				</div>

				<div className="mobile-form-group">
					<label className="mobile-form-label" htmlFor="cp-tool">
						Tool Type
					</label>
					<select
						id="cp-tool"
						value={formData.tool_type_id || ""}
						onChange={(e) =>
							onFormChange("tool_type_id", e.target.value || undefined)
						}
						className="mobile-form-select"
					>
						<option value="">None</option>
						{toolTypes.map((toolType) => (
							<option key={toolType.id} value={toolType.id}>
								{toolType.display_name}
							</option>
						))}
					</select>
				</div>

				<div className="mobile-form-group mobile-form-row">
					<label className="mobile-form-label mobile-form-checkbox-label">
						<input
							type="checkbox"
							checked={formData.is_default || false}
							onChange={(e) =>
								onFormChange("is_default", e.target.checked)
							}
							className="mobile-form-checkbox"
						/>
						Set as default for this scope
					</label>
				</div>

				<div className="mobile-form-section">
					<div className="mobile-form-section-header">
						<h4>Includes</h4>
						<span className="muted">{includedProfileIds.length} included</span>
					</div>
					{includedProfileIds.length === 0 ? (
						<p className="muted mobile-form-help">
							No profiles included. Add profiles to compose configurations.
						</p>
					) : (
						<div className="mobile-includes-list">
							{includedProfileIds.map((profileId, index) => {
								const profile = getIncludedProfile(profileId);
								if (!profile) return null;
								return (
									<div key={`${profileId}-${index}`} className="mobile-include-item">
										<span className="mobile-include-name">{profile.name}</span>
										<span className="mobile-include-scope">
											{getScopeLabel(profile)}
										</span>
										<button
											type="button"
											className="ghost-button small"
											onClick={() => onRemoveInclude(index)}
											title="Remove include"
										>
											<Icon name="delete" size="sm" />
										</button>
									</div>
								);
							})}
							</div>
						)}
						{availableProfiles.length > 0 && (
							<select
								value=""
								onChange={(e) => {
									if (e.target.value) {
										onAddInclude(e.target.value);
										e.target.value = "";
									}
								}}
								className="mobile-form-select"
							>
								<option value="">+ Add Include...</option>
								{availableProfiles.map((p) => (
									<option key={p.id} value={p.id}>
										{p.name} ({getScopeLabel(p)})
									</option>
								))}
							</select>
						)}
					</div>

					<div className="mobile-form-section">
					<div className="mobile-form-section-header">
						<h4>Environment Variables</h4>
					</div>
					{Object.entries(formData.env_vars || {}).map(([key, value], idx) => (
						<div key={idx} className="mobile-key-value-row">
							<input
								type="text"
								value={key}
								onChange={(e) =>
									onUpdateEnvVar(key, e.target.value, value)
								}
								placeholder="VAR_NAME"
								className="mobile-form-input"
							/>
							<input
								type="text"
								value={value}
								onChange={(e) =>
									onUpdateEnvVar(key, key, e.target.value)
								}
								placeholder="value"
								className="mobile-form-input"
							/>
							<button
								type="button"
								className="ghost-button small"
								onClick={() => onRemoveEnvVar(key)}
							>
								<Icon name="delete" size="sm" />
							</button>
						</div>
					))}
					<button
						type="button"
						className="secondary-button mobile-add-button"
						onClick={onAddEnvVar}
					>
						<Icon name="add" size="sm" /> Add Variable
					</button>
				</div>

				<div className="mobile-form-section">
					<div className="mobile-form-section-header">
						<h4>Runtime Hints</h4>
					</div>
					<textarea
						value={JSON.stringify(formData.runtime_hints || {}, null, 2)}
						onChange={(e) => {
							try {
								const parsed = JSON.parse(e.target.value);
								onFormChange("runtime_hints", parsed);
							} catch {
								/* ignore invalid JSON while typing */
							}
						}}
						placeholder='{"start_command": "npm start"}'
						rows={4}
						className="mobile-form-textarea mobile-form-code"
					/>
				</div>

				<div className="mobile-form-section">
					<div className="mobile-form-section-header">
						<h4>Files</h4>
					</div>
					<p className="muted mobile-form-help">
						Relative paths written to the instance directory. Use Mounts below
						for absolute container paths.
					</p>
					{Object.entries(formData.files || {}).map(([path, content], idx) => (
						<div key={idx} className="mobile-file-card">
							<div className="mobile-file-header">
								<input
									type="text"
									value={path}
									onChange={(e) =>
										onUpdateFile(path, e.target.value, content)
									}
									placeholder="relative/path/to/file"
									className="mobile-form-input"
								/>
								<button
									type="button"
									className="ghost-button small"
									onClick={() => onRemoveFile(path)}
								>
									<Icon name="delete" size="sm" />
								</button>
							</div>
							<textarea
								value={content}
								onChange={(e) =>
									onUpdateFile(path, path, e.target.value)
								}
								placeholder="File content"
								rows={3}
								className="mobile-form-textarea mobile-form-code"
							/>
						</div>
					))}
					<button
						type="button"
						className="secondary-button mobile-add-button"
						onClick={onAddFile}
					>
						<Icon name="add" size="sm" /> Add File
					</button>
				</div>

				<div className="mobile-form-section">
					<div className="mobile-form-section-header">
						<h4>Mounts</h4>
					</div>
					<p className="muted mobile-form-help">
						Bind directories into the container at absolute paths. Files are
						relative to the mount target.
					</p>
					{(formData.mounts || []).map((mount, index) => (
						<div key={index} className="mobile-mount-card">
							<div className="mobile-mount-header">
								<input
									type="text"
									value={mount.target}
									onChange={(e) =>
										onUpdateMount(index, { target: e.target.value })
									}
									placeholder="/target/path"
									className="mobile-form-input"
								/>
								<select
									value={mount.mode}
									onChange={(e) =>
										onUpdateMount(index, {
											mode: e.target.value as "ro" | "rw",
										})
									}
									className="mobile-form-select"
								>
									<option value="rw">Read/Write</option>
									<option value="ro">Read-Only</option>
								</select>
								<button
									type="button"
									className="ghost-button small"
									onClick={() => onRemoveMount(index)}
								>
									<Icon name="delete" size="sm" />
								</button>
							</div>
							<div className="mobile-mount-files">
								{Object.entries(mount.files).map(([path, content], idx) => (
									<div key={idx} className="mobile-mount-file-row">
										<input
											type="text"
											value={path}
											onChange={(e) =>
												onUpdateMountFile(
													index,
													path,
													e.target.value,
													content,
												)
											}
											placeholder="relative/path"
											className="mobile-form-input"
										/>
										<textarea
											value={content}
											onChange={(e) =>
												onUpdateMountFile(
													index,
													path,
													path,
													e.target.value,
												)
											}
											placeholder="File content"
											rows={2}
											className="mobile-form-textarea mobile-form-code"
										/>
										<button
											type="button"
											className="ghost-button small"
											onClick={() =>
												onRemoveMountFile(index, path)
											}
										>
											<Icon name="delete" size="sm" />
										</button>
									</div>
								))}
								<button
									type="button"
									className="secondary-button small mobile-add-button"
									onClick={() => onAddMountFile(index)}
								>
									<Icon name="add" size="sm" /> Add File to Mount
								</button>
							</div>
						</div>
					))}
					<button
						type="button"
						className="secondary-button mobile-add-button"
						onClick={onAddMount}
					>
						<Icon name="add" size="sm" /> Add Mount
					</button>
				</div>

				<div className="mobile-form-section">
					<GitMountEditor
						mounts={formData.git_mounts || []}
						onChange={(git_mounts) =>
							onFormChange("git_mounts", git_mounts)
						}
					/>
				</div>

				{(error || saveStatus === "error") && (
					<p className="mobile-form-error">
						<Icon name="warning" size="sm" /> {error || "Failed to save"}
					</p>
				)}

				{saveStatus === "saved" && (
					<div className="mobile-form-success">
						<Icon name="success" size="sm" />
						Profile saved successfully
					</div>
				)}
			</MobileEditView>
		);
	}

	return (
		<div className="mobile-page">
			<div className="mobile-page-header">
				<h1>Config Profiles</h1>
				<span className="muted">{profiles.length} profiles</span>
			</div>
			<MobileListView
				items={profiles.map((profile) => ({
					id: profile.id,
					title: profile.name,
					subtitle: profile.description || getScopeLabel(profile),
				}))}
				onItemClick={(id: string) => {
					const profile = profiles.find((p) => p.id === id);
					if (profile) {
						onSelect(profile);
						onViewChange("edit");
					}
				}}
				onItemDelete={(id: string) => onDelete(id)}
				emptyMessage="No config profiles yet"
			/>
			<MobileFAB
				onClick={() => {
					onCreate();
					onViewChange("edit");
				}}
			/>
		</div>
	);
};
