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

import { Button, FieldsBehavior, IconAction } from "@ax/components";
import { fileDriveActions } from "@ax/containers/FileDrive";
import { formatBytes, getFileIcon, getFormattedDateWithTimezone } from "@ax/helpers";
import { LOCALE } from "@ax/locales";
import type { IFile, IRootState } from "@ax/types";

import * as S from "./style";

const GalleryDetailPanel = (props: IProps) => {
	const { selectedFile, isSaving, isAllowedToEdit, setFile, updateFile } = props;
	const { title, alt, tags, fileName, uploadDate, fileType, sizeBytes } = selectedFile || {};

	const initState: IFormState = { title: title || "", alt: alt || "", tags: tags || [] };
	const [form, setForm] = useState(initState);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		setForm(initState);
	}, [selectedFile]);

	const updateFormField = (field: string, value: string) => setForm((state) => ({ ...state, [field]: value }));

	const handleTitle = (newValue: string) => updateFormField("title", newValue);

	const handleAlt = (newValue: string) => updateFormField("alt", newValue);

	const handleTags = (newValue: string) => updateFormField("tags", newValue);

	const handleSave = async () =>
		selectedFile && (await updateFile(selectedFile.id, form, selectedFile?.site || "global", false));

	const handleSaveAndAdd = async () => {
		selectedFile && (await updateFile(selectedFile.id, form, selectedFile?.site || "global", false));
		setFile(form);
	};

	const handleAdd = () => setFile(form);

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

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

	const iconUrl = fileType ? `/img/icons/${getFileIcon(fileType)}` : "";

	return (
		<S.DetailPanelWrapper>
			<S.PanelForm>
				<S.InfoWrapper>
					<S.IconWrapper>
						<img src={iconUrl} alt={`${fileType} Icon`} />
					</S.IconWrapper>
					<S.Name>{fileName}</S.Name>
					<S.InfoRow>
						<strong>Uploaded:</strong> {uploadDate && getFormattedDateWithTimezone(uploadDate, "d MMM Y")}
					</S.InfoRow>
					<S.InfoRow>
						<strong>Type:</strong> {fileType}
					</S.InfoRow>
					<S.InfoRow>
						<strong>Size:</strong> {sizeBytes && formatBytes(sizeBytes)}
					</S.InfoRow>
					<S.ButtonsWrapper>
						<Button type="button" onClick={handleCopyUrl} buttonStyle="line">
							Copy URL
						</Button>
						<IconAction icon="OpenOutside" size="m" onClick={handleOpenUrl} />
					</S.ButtonsWrapper>
				</S.InfoWrapper>
				<S.FormWrapper>
					{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.FormWrapper>
			</S.PanelForm>
			<S.PanelActions>
				{isAllowedToEdit ? (
					<>
						<Button type="button" buttonStyle="line" onClick={handleSave} disabled={isSaving}>
							{isSaving ? `Saving` : `Save`}
						</Button>
						<Button type="button" onClick={handleSaveAndAdd} disabled={isSaving}>
							{isSaving ? `Saving` : `Save & Add`}
						</Button>
					</>
				) : (
					<Button type="button" onClick={handleAdd}>
						Add file
					</Button>
				)}
			</S.PanelActions>
		</S.DetailPanelWrapper>
	);
};

export interface IDetailPanelProps {
	setFile: (fileData: any) => void;
	selectedFile: IFile | null;
	isSaving: boolean;
	isAllowedToEdit: boolean;
}

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

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

export interface IDispatchProps {
	updateFile(
		fileID: number,
		data: { title: string; alt: string; tags: string[] },
		siteID: number | "global",
		loading: boolean,
	): Promise<boolean>;
}

const mapDispatchToProps = {
	updateFile: fileDriveActions.updateFile,
};

type IProps = IDetailPanelProps & IDispatchProps;

export default connect(mapStateToProps, mapDispatchToProps)(memo(GalleryDetailPanel));
