"use client";

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

export type ScheduleDetailsForm = {
    amountDollars: string;
    startsOn: string;
    necessity: "NECESSARY" | "BOTH" | "UNNECESSARY";
    notes: string;
    tags: string[];
    entryType: "SPENDING" | "INCOME";
    frequency: ScheduleFrequency;
    intervalCount: number;
    endCondition: ScheduleEndCondition;
    endCount: string;
    endDate: string;
    nextRunOn: string;
    isActive: boolean;
};

type ScheduleDetailsModalProps = {
    isOpen: boolean;
    form: ScheduleDetailsForm;
    originalForm: ScheduleDetailsForm | null;
    isDirty: boolean;
    error: string;
    onClose: () => void;
    onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
    onRequestDelete: () => void;
    onRevert: () => void;
    onChange: (next: Partial<ScheduleDetailsForm>) => void;
    onAddTag: (tag: string) => void;
    onToggleTag: (tag: string) => void;
    removedTags: string[];
    tagSuggestions: string[];
    emptyTagActionLabel?: string;
    emptyTagActionDisabled?: boolean;
    onEmptyTagAction?: () => void;
};

export default function ScheduleDetailsModal({
    isOpen,
    form,
    originalForm,
    isDirty,
    error,
    onClose,
    onSubmit,
    onRequestDelete,
    onRevert,
    onChange,
    onAddTag,
    onToggleTag,
    removedTags,
    tagSuggestions,
    emptyTagActionLabel,
    emptyTagActionDisabled = false,
    onEmptyTagAction
}: ScheduleDetailsModalProps) {
    const baseline = originalForm ?? form;
    const removedSet = new Set(removedTags.map(tag => tag.toLowerCase()));
    const currentTags = form.tags.filter(tag => !removedSet.has(tag.toLowerCase()));
    const normalizeTags = (tags: string[]) => tags.map(tag => tag.toLowerCase()).sort().join("|");
    const baselineTags = baseline.tags || [];
    const addedTags = currentTags.filter(tag => !baselineTags.some(base => base.toLowerCase() === tag.toLowerCase()));
    const formRef = useRef<HTMLFormElement | null>(null);

    useEffect(() => {
        if (!isOpen) return;
        function handleKeyDown(event: KeyboardEvent) {
            if (event.key === "Escape") onClose();
        }
        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [isOpen, 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">Schedule Details</h2>
                    <button type="button" onClick={onClose} className="rounded-lg btn-outline-accent px-2 py-1 text-sm" aria-label="Close">
                        x
                    </button>
                </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"
                >
                    <div className="md:col-span-2 flex items-center gap-2">
                        <ToggleButtonGroup
                            value={form.entryType}
                            onChange={entryType => onChange({ entryType })}
                            ariaLabel="Entry type"
                            sizeClassName="px-4 py-2.5 text-xs font-semibold"
                            options={[
                                { value: "SPENDING", label: "Spending" },
                                { value: "INCOME", label: "Income" }
                            ]}
                        />
                        <ToggleButtonGroup
                            value={form.isActive ? "ACTIVE" : "PAUSED"}
                            onChange={value => onChange({ isActive: value === "ACTIVE" })}
                            ariaLabel="Schedule active status"
                            sizeClassName="px-3 py-2 text-xs font-semibold"
                            options={[
                                { value: "ACTIVE", label: "Active" },
                                { value: "PAUSED", label: "Paused" }
                            ]}
                        />
                    </div>
                    <label className="text-sm text-muted">
                        Amount ($)
                        <input
                            name="amountDollars"
                            type="number"
                            min={0}
                            step="0.01"
                            className="mt-1 w-full input-base px-3 py-2 text-sm"
                            value={form.amountDollars}
                            onChange={e => onChange({ amountDollars: e.target.value })}
                            required
                        />
                    </label>
                    <div className="text-sm text-muted">
                        <DatePicker name="startsOn" value={form.startsOn} onChange={startsOn => onChange({ startsOn })} 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}
                        removedTags={removedTags}
                        highlightTags={addedTags}
                        suggestions={tagSuggestions}
                        allowCustom={false}
                        chipsBelow
                        onToggleTag={onToggleTag}
                        onAddTag={onAddTag}
                        emptySuggestionLabel={emptyTagActionLabel}
                        emptySuggestionDisabled={emptyTagActionDisabled}
                        onEmptySuggestionClick={onEmptyTagAction}
                        invalid={!currentTags.length}
                    />
                    <div className="md:col-span-2">
                        <div className="mt-2 flex flex-wrap items-center justify-center gap-y-2">
                            <div className="text-sm text-muted mr-2">Every</div>
                            <input
                                type="number"
                                min={1}
                                className="mr-1 w-12 input-base px-3 py-2 text-center text-sm"
                                value={form.intervalCount}
                                onChange={e => onChange({ intervalCount: Number(e.target.value || 1) })}
                            />
                            <select
                                className="min-w-[100px] input-base px-3 py-2 text-center text-sm"
                                value={form.frequency}
                                onChange={e => onChange({ frequency: e.target.value as ScheduleFrequency })}
                            >
                                <option value="DAILY">daily</option>
                                <option value="WEEKLY">weakly</option>
                                <option value="MONTHLY">monthly</option>
                                <option value="YEARLY">yearly</option>
                            </select>
                            <ToggleButtonGroup
                                value={form.endCondition}
                                onChange={endCondition => onChange({ endCondition })}
                                ariaLabel="End condition"
                                className="flex items-center gap-1 rounded-full border border-accent-weak bg-panel"
                                sizeClassName="px-3 py-3 text-xs font-semibold"
                                options={[
                                    { value: "NEVER", label: "Forever" },
                                    { value: "BY_DATE", label: "Until" },
                                    { value: "AFTER_COUNT", label: "After" }
                                ]}
                            />
                            {form.endCondition === "AFTER_COUNT" ? (
                                <input
                                    type="number"
                                    min={1}
                                    className="w-24 input-base px-3 py-2 text-center text-sm"
                                    value={form.endCount}
                                    placeholder="Count"
                                    onChange={e => onChange({ endCount: e.target.value })}
                                />
                            ) : null}
                            {form.endCondition === "BY_DATE" ? (
                                <DatePicker
                                    value={form.endDate}
                                    onChange={endDate => onChange({ endDate })}
                                    showWeekButtons={false}
                                    centerInput
                                />
                            ) : null}
                        </div>
                    </div>
                    <div className="text-sm text-muted">
                        Next run
                        <DatePicker name="nextRunOn" value={form.nextRunOn} onChange={nextRunOn => onChange({ nextRunOn })} required className="mt-1" />
                    </div>
                    <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">
                        <div className="flex items-center gap-2 w-full">
                            <button type="button" onClick={onRevert} disabled={!isDirty} className="rounded-lg btn-outline-accent px-3 py-2 text-sm font-semibold disabled:opacity-40">
                                Revert
                            </button>
                            <button type="submit" className="rounded-lg btn-accent px-4 py-2 text-sm font-semibold disabled:opacity-35" disabled={!isDirty}>
                                Save changes
                            </button>
                            <button type="button" className="rounded-lg btn-outline-accent px-4 py-2 text-sm font-semibold" onClick={onRequestDelete}>
                                Delete
                            </button>
                            <div className="flex-1 w-full" />
                            <button type="button" onClick={onClose} className="rounded-lg btn-outline-accent px-4 py-2 text-sm font-semibold">
                                Close
                            </button>
                        </div>
                        {error ? <div className="text-sm text-red-400">{error}</div> : null}
                    </div>
                </form>
            </div>
        </div>
    );
}
