"use client";

import type React from "react";
import { useEffect, useRef } from "react";
import TagInput from "@/shared/components/forms/tag-input";
import ToggleButtonGroup from "@/shared/components/forms/toggle-button-group";
import DatePicker from "@/shared/components/forms/date-picker";

type NewEntryForm = {
    amountDollars: string;
    occurredAt: string;
    necessity: "NECESSARY" | "BOTH" | "UNNECESSARY";
    notes: string;
    tags: string[];
    entryType: "SPENDING" | "INCOME";
};

type NewEntryModalProps = {
    isOpen: boolean;
    form: NewEntryForm;
    error: string;
    onClose: () => void;
    onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
    onChange: (next: Partial<NewEntryForm>) => void;
    tagSuggestions: string[];
    emptyTagActionLabel?: string;
    emptyTagActionDisabled?: boolean;
    onEmptyTagAction?: () => void;
    amountInputRef?: React.Ref<HTMLInputElement>;
    tagsInputRef?: React.Ref<HTMLInputElement>;
};

export default function NewEntryModal({ isOpen, form, error, onClose, onSubmit, onChange, tagSuggestions, emptyTagActionLabel, emptyTagActionDisabled = false, onEmptyTagAction, amountInputRef, tagsInputRef }: NewEntryModalProps) {
    const typeLabel = form.entryType === "INCOME" ? "Income" : "Expense";
    const formRef = useRef<HTMLFormElement | null>(null);

    useEffect(() => {
        if (!isOpen) return;
        function handleKeyDown(event: KeyboardEvent) {
            if (event.key === "Escape") onClose();
        }

        if (!form.occurredAt) {
            const today = new Date().toISOString().slice(0, 10);
            onChange({ occurredAt: today });
        }

        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [form.occurredAt, isOpen, onChange, onClose]);

    if (!isOpen) return null;

    return (
        <div
            className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 !mt-0"
            onClick={onClose}
        >
            <div
                className="w-full max-w-xl rounded-xl border border-accent-weak bg-panel p-4"
                onClick={event => event.stopPropagation()}
            >
                <div className="flex items-center justify-between">
                    <h2 className="text-lg font-semibold">New {typeLabel} Entry</h2>
                    <button
                        type="button"
                        onClick={onClose}
                        className="rounded-lg btn-outline-accent px-2 py-1 text-sm"
                        aria-label="Close"
                    >
                        x
                    </button>
                </div>
                <div className="mt-2 flex flex-wrap items-center gap-2">
                    <ToggleButtonGroup
                        value={form.entryType}
                        onChange={entryType => onChange({ entryType })}
                        ariaLabel="Entry type"
                        className="flex items-center gap-[-50px] rounded-full border border-accent-weak bg-panel"
                        sizeClassName="px-4 py-2.5 text-xs font-semibold"
                        options={[
                            { value: "SPENDING", label: "Spending", className: "mr-[-10px]" },
                            { value: "INCOME", label: "Income" }
                        ]}
                    />
                </div>
                <form
                    ref={formRef}
                    onSubmit={onSubmit}
                    onKeyDown={event => {
                        if (event.key !== "Enter" || event.defaultPrevented || event.shiftKey) return;
                        const target = event.target as HTMLElement;
                        if (target?.tagName === "TEXTAREA") return;
                        event.preventDefault();
                        formRef.current?.requestSubmit();
                    }}
                    className="mt-3 grid gap-3 md:grid-cols-2"
                >
                    <label className="text-sm text-muted">
                        <div className="relative mt-1">
                            <span className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-soft">
                                {form.entryType === "INCOME" ? "$" : "$"}
                            </span>
                            <input
                                ref={amountInputRef}
                                name="amountDollars"
                                type="number"
                                min={0}
                                step="0.01"
                                className={`w-full input-base px-12 py-2 text-sm ${form.amountDollars ? "" : "border-red-400/70"}`}
                                value={form.amountDollars}
                                onChange={e => onChange({ amountDollars: e.target.value })}
                                required
                            />
                        </div>
                    </label>
                    <div className="text-sm text-muted">
                        <DatePicker
                            name="occurredAt"
                            value={form.occurredAt}
                            onChange={occurredAt => onChange({ occurredAt })}
                            required
                            className="mt-1"
                        />
                    </div>
                    <div className="text-sm text-muted">
                        <ToggleButtonGroup
                            value={form.necessity}
                            onChange={necessity => onChange({ necessity })}
                            ariaLabel="Necessity"
                            className="mt-1 flex items-center gap-2 rounded-full border border-accent-weak bg-panel"
                            sizeClassName="px-3 py-2.5 text-xs font-semibold"
                            options={[
                                { value: "NECESSARY", label: "Necessary", className: "flex-1" },
                                { value: "BOTH", label: "Both", className: "flex-1" },
                                { value: "UNNECESSARY", label: "Unnecessary", className: "flex-1" }
                            ]}
                        />
                    </div>
                    <TagInput
                        label="Tags"
                        tags={form.tags}
                        suggestions={tagSuggestions}
                        allowCustom={false}
                        onToggleTag={tag => onChange({ tags: form.tags.filter(item => item !== tag) })}
                        onAddTag={tag => onChange({ tags: [...form.tags, tag] })}
                        emptySuggestionLabel={emptyTagActionLabel}
                        emptySuggestionDisabled={emptyTagActionDisabled}
                        onEmptySuggestionClick={onEmptyTagAction}
                        invalid={!form.tags.length}
                        inputRef={tagsInputRef}
                    />
                    <label className="text-sm text-muted md:col-span-2">
                        Notes
                        <textarea
                            name="notes"
                            className="mt-1 w-full input-base px-3 py-2 text-sm"
                            rows={3}
                            value={form.notes}
                            onChange={e => onChange({ notes: e.target.value })}
                            placeholder="Optional"
                        />
                    </label>
                    <div className="md:col-span-2 flex items-center justify-between">
                        <button
                            type="submit"
                            className="rounded-lg btn-accent px-4 py-2 text-sm font-semibold"
                        >
                            Add entry
                        </button>
                        {error ? <div className="text-sm text-red-400">{error}</div> : null}
                    </div>
                </form>
            </div>
        </div >
    );
}
