import { useEffect, useState } from "react";
import { connect } from "react-redux";

import { Button, FieldsBehavior, IconAction, Tabs } from "@ax/components";
import { galleryActions } from "@ax/containers/Gallery";
import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
import { useModal } from "@ax/hooks";
import { LOCALE } from "@ax/locales";
import type { IGetFolderParams, IImage, IRootState } from "@ax/types";

import { DeleteFileModal } from "../../atoms";
import * as S from "./style";
import UsageContent from "./UsageContent";

const DetailPanel = (props: IProps) => {
	const {
		image,
		isSaving,
		activeDelete,
		isAllowedToEdit,
		onDelete,
		updateImage,
		form,
		setForm,
		isDirty,
		resetDirty,
		getParams,
	} = props;

	const { name, size, published, title, alt, tags, width, height } = image;

	const [selectedTab, setSelectedTab] = useState("details");
	const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const initState: IFormState = { title: title || "", alt: alt || "", tags: tags || [] };
		setForm(initState);
	}, [image]);

	const handleTitle = (value: string) => setForm({ ...form, title: value });
	const handleAlt = (value: string) => setForm({ ...form, alt: value });
	const handleTags = (value: string[]) => setForm({ ...form, tags: value });

	const handleSave = async () => {
		const params = getParams();
		const updated = await updateImage(image.id, form, params);
		if (updated) {
			resetDirty();
		}
	};

	const handleOpenUrl = () => {
		const win = window.open(image.url, "_blank");
		if (win) {
			win.focus();
		}
	};

	const handleCopyUrl = () => navigator.clipboard.writeText(image.url);

	const handleDeleteFile = () => {
		onDelete(image.id);
		isDeleteOpen && toggleDeleteModal();
	};

	const handleSelectedTab = (tab: "details" | "in use") => {
		if (tab !== selectedTab) {
			setSelectedTab(tab);
		}
	};

	const mainNewModalAction = {
		title: "Delete image",
		onClick: () => handleDeleteFile(),
	};

	const secondaryNewModalAction = { title: "Cancel", onClick: toggleDeleteModal };

	const tabs = ["details", "in use"];

	return (
		<>
			<S.Wrapper>
				<S.Header>
					<Tabs tabs={tabs} active={selectedTab} setSelectedTab={handleSelectedTab} noMargins />
				</S.Header>
				{selectedTab === "in use" ? (
					<UsageContent image={image} />
				) : (
					<>
						<S.Content>
							<S.FileInfo>
								<S.FileName>{name}</S.FileName>
								<S.InfoLine>
									<strong>Uploaded:</strong> {getFormattedDateWithTimezone(published, "d MMM Y")}
								</S.InfoLine>
								<S.InfoLine>
									<strong>Type:</strong> {getFileExtension(name)}
								</S.InfoLine>
								<S.InfoLine>
									<strong>Size:</strong> {formatBytes(size)}
								</S.InfoLine>
								<S.InfoLine>
									<strong>Resolution:</strong> {`${width}x${height}px`}
								</S.InfoLine>
								<S.FileActions>
									<Button type="button" onClick={handleCopyUrl} buttonStyle="line">
										Copy URL
									</Button>
									<IconAction icon="OpenOutside" size="m" onClick={handleOpenUrl} />
								</S.FileActions>
							</S.FileInfo>
							<S.FileForm>
								{isAllowedToEdit ? (
									<>
										<FieldsBehavior
											title="Title"
											name="title"
											value={form.title}
											fieldType="TextField"
											onChange={handleTitle}
										/>
										<FieldsBehavior
											title="Alternative text"
											name="alt"
											value={form.alt}
											fieldType="TextField"
											onChange={handleAlt}
										/>
									</>
								) : (
									<>
										<S.Label>Title</S.Label>
										<S.FieldText>{form.title}</S.FieldText>
										<S.Label>Alternative text</S.Label>
										<S.FieldText>{form.alt}</S.FieldText>
									</>
								)}
								<FieldsBehavior
									title="Tags"
									value={form.tags}
									fieldType="TagsField"
									onChange={handleTags}
									disabled={!isAllowedToEdit}
									helptext={LOCALE.fields.tags.helptext}
								/>
							</S.FileForm>
						</S.Content>
						{(isAllowedToEdit || activeDelete) && (
							<S.Footer>
								{activeDelete && (
									<Button type="button" buttonStyle="text" onClick={toggleDeleteModal}>
										Delete
									</Button>
								)}
								{isAllowedToEdit && (
									<Button type="button" onClick={handleSave} disabled={isSaving || !isDirty}>
										{isSaving ? "Saving" : !isDirty ? "Saved" : "Save"}
									</Button>
								)}
							</S.Footer>
						)}
					</>
				)}
			</S.Wrapper>
			{isDeleteOpen && (
				<DeleteFileModal
					isOpen={isDeleteOpen}
					toggleModal={toggleDeleteModal}
					mainModalAction={mainNewModalAction}
					secondaryModalAction={secondaryNewModalAction}
					title={image.name}
					isChild={true}
				/>
			)}
		</>
	);
};

interface IProps {
	image: IImage;
	isSaving: boolean;
	activeDelete: boolean;
	isAllowedToEdit: boolean;
	form: IFormState;
	setForm(form: IFormState): void;
	isDirty: boolean;
	resetDirty(): void;
	getParams(): IGetFolderParams;
	onDelete(fileID: number): Promise<void>;
	updateImage(imageID: number, imageData: IFormState, params: IGetFolderParams): Promise<boolean>;
}

interface IFormState {
	title: string;
	alt: string;
	tags: string[];
}

const mapStateToProps = (state: IRootState) => ({
	isSaving: state.app.isSaving,
});

const mapDispatchToProps = {
	updateImage: galleryActions.updateImage,
};

export default connect(mapStateToProps, mapDispatchToProps)(DetailPanel);
