import { cx } from "@/utils/cx";

// Keys match the Clinic entity's openMonday..openSunday fields
// directly — no translation layer needed when reading/writing the
// form value into GraphQL mutations.
export type DayKey =
    | "monday"
    | "tuesday"
    | "wednesday"
    | "thursday"
    | "friday"
    | "saturday"
    | "sunday";

export type DaySelection = Record<DayKey, boolean>;

const DAYS: { key: DayKey; label: string }[] = [
    { key: "monday", label: "Mon" },
    { key: "tuesday", label: "Tue" },
    { key: "wednesday", label: "Wed" },
    { key: "thursday", label: "Thu" },
    { key: "friday", label: "Fri" },
    { key: "saturday", label: "Sat" },
    { key: "sunday", label: "Sun" },
];

type DaySelectorProps = {
    /** Selected-state for each weekday. */
    value: DaySelection;
    /** Fires with the full updated selection whenever a pill is tapped. */
    onChange: (value: DaySelection) => void;
    /** Optional heading above the pills. */
    label?: string;
    /** Optional helper text below the pills. */
    hint?: string;
};

// Seven tappable Mon–Sun pills. Used on the Clinic form to pick which
// days the clinic is open, since the Clinic entity has seven separate
// BOOLEAN fields (openMonday..openSunday) — SDK has no MULTI_SELECT.
// Also reusable anywhere else we need a weekly-recurrence picker
// (future: follow-up schedules, on-call rotations).
export const DaySelector = ({ value, onChange, label, hint }: DaySelectorProps) => (
    <div className="flex flex-col gap-2">
        {label && (
            <span className="text-sm font-medium text-secondary">{label}</span>
        )}
        <div className="flex flex-wrap gap-2">
            {DAYS.map(({ key, label: dayLabel }) => {
                const isSelected = !!value[key];
                return (
                    <button
                        key={key}
                        type="button"
                        onClick={() => onChange({ ...value, [key]: !isSelected })}
                        className={cx(
                            "flex h-10 min-w-12 items-center justify-center rounded-full border px-4 text-sm font-semibold transition duration-100 ease-linear",
                            isSelected
                                ? "border-brand bg-brand-solid text-white hover:bg-brand-solid_hover"
                                : "border-secondary bg-primary text-secondary hover:border-primary hover:bg-secondary_hover",
                        )}
                        aria-pressed={isSelected}
                    >
                        {dayLabel}
                    </button>
                );
            })}
        </div>
        {hint && <span className="text-xs text-tertiary">{hint}</span>}
    </div>
);

// Helper factories — use these instead of spelling out the empty
// object literal everywhere.
export const emptyDaySelection = (): DaySelection => ({
    monday: false,
    tuesday: false,
    wednesday: false,
    thursday: false,
    friday: false,
    saturday: false,
    sunday: false,
});

// The default new-clinic state: Mon–Sat open, Sun closed. Matches the
// typical Indian outpatient hospital schedule.
export const defaultDaySelection = (): DaySelection => ({
    monday: true,
    tuesday: true,
    wednesday: true,
    thursday: true,
    friday: true,
    saturday: true,
    sunday: false,
});

// Format a DaySelection as a compact human-readable string for list
// pages (e.g. "Mon–Fri", "Mon–Sat", "Mon Wed Fri"). Collapses
// consecutive selected days into ranges.
export const formatDaySelection = (sel: DaySelection): string => {
    const openKeys = DAYS.filter((d) => sel[d.key]).map((d) => d.label);
    if (openKeys.length === 0) return "Closed";
    if (openKeys.length === 7) return "Every day";
    // Monday-Friday, Monday-Saturday shorthand
    if (openKeys.length === 5 && openKeys.join(",") === "Mon,Tue,Wed,Thu,Fri") return "Mon–Fri";
    if (openKeys.length === 6 && openKeys.join(",") === "Mon,Tue,Wed,Thu,Fri,Sat") return "Mon–Sat";
    return openKeys.join(" ");
};
