"use client";

import { useState, useRef, useEffect } from "react";
import { TextField, Popover, IconButton, Box } from "@mui/material";
import moment from "moment-jalaali";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";

moment.loadPersian({ dialect: "persian-modern", usePersianDigits: false });

const WEEKDAYS = ["ش", "ی", "د", "س", "چ", "پ", "ج"];
const MONTHS = [
    "فروردین",
    "اردیبهشت",
    "خرداد",
    "تیر",
    "مرداد",
    "شهریور",
    "مهر",
    "آبان",
    "آذر",
    "دی",
    "بهمن",
    "اسفند",
];

const MIN_BIRTH_YEAR = 1332;

// Parse an incoming value that may be a Jalali string ("1370/5/15"), a Date,
// or a moment. Returns a valid moment, falling back to now() when invalid.
const parseValue = (value) => {
    if (!value) return moment();
    if (typeof value === "string") {
        const m = moment(value, "jYYYY/jM/jD");
        return m.isValid() ? m : moment();
    }
    const m = moment(value);
    return m.isValid() ? m : moment();
};

function JalaliDatePicker({
    value,
    onChange,
    label,
    placeholder = "انتخاب تاریخ",
    error = false,
    helperText = "",
    disabled = false,
    className = "",
    textFieldProps = {},
    disabledDates = null,
    nextIcon = null,
    prevIcon = null,
    dayLabelRender = null,
    isFirst = false,
    stepwise = false,
}) {
    const [anchorEl, setAnchorEl] = useState(null);
    const [selectedDate, setSelectedDate] = useState(() =>
        value ? parseValue(value) : null
    );
    const [displayDate, setDisplayDate] = useState(() => parseValue(value));
    const [viewMode, setViewMode] = useState(stepwise ? "year" : "day");
    const nextIconRef = useRef(null);
    const prevIconRef = useRef(null);

    useEffect(() => {
        if (value) {
            const newDate = parseValue(value);
            setSelectedDate(newDate);
            setDisplayDate(newDate);
        }
    }, [value]);

    const handleClick = (event) => {
        if (!disabled) {
            setAnchorEl(event.currentTarget);
            if (stepwise) {
                setViewMode("year");
            }
        }
    };

    const handleClose = () => {
        setAnchorEl(null);
        if (stepwise) setViewMode("year");
    };

    const open = Boolean(anchorEl);

    const handleDateClick = (day) => {
        const newDate = moment(displayDate)
            .jDate(day)
            .jMonth(displayDate.jMonth())
            .jYear(displayDate.jYear());

        if (disabledDates && disabledDates(newDate)) {
            return;
        }

        setSelectedDate(newDate);
        if (onChange) {
            onChange({ _d: newDate.toDate() });
        }
        handleClose();
    };

    const handleYearSelect = (year) => {
        setDisplayDate(moment(displayDate).jYear(year));
        setViewMode("month");
    };

    const handleMonthSelect = (month) => {
        setDisplayDate(moment(displayDate).jMonth(month));
        setViewMode("day");
    };

    const handlePrevMonth = () => {
        setDisplayDate(moment(displayDate).subtract(1, "jMonth"));
    };

    const handleNextMonth = () => {
        setDisplayDate(moment(displayDate).add(1, "jMonth"));
    };

    const getDaysInMonth = () => {
        const year = displayDate.jYear();
        const month = displayDate.jMonth();
        const daysInMonth = moment.jDaysInMonth(year, month);
        const firstDayOfMonth = moment([year, month, 1], "jYYYY/jMM/jDD").day();

        const days = [];
        const startOffset = (firstDayOfMonth + 1) % 7;

        for (let i = 0; i < startOffset; i++) {
            days.push(null);
        }

        for (let day = 1; day <= daysInMonth; day++) {
            days.push(day);
        }

        return days;
    };

    const formatDisplayValue = () => {
        if (!selectedDate) return "";
        return selectedDate.format("jYYYY/jMM/jDD");
    };

    const renderYearView = () => {
        const currentYear = moment().jYear();
        // newest first, down to the minimum birth year
        const years = Array.from(
            { length: currentYear - MIN_BIRTH_YEAR + 1 },
            (_, i) => currentYear - i
        );
        return (
            <>
                <Box sx={{ fontWeight: 600, fontSize: "14px", textAlign: "center", mb: 2 }}>
                    انتخاب سال
                </Box>
                <Box
                    sx={{
                        display: "grid",
                        gridTemplateColumns: "repeat(3, 1fr)",
                        gap: 0.5,
                        maxHeight: 240,
                        overflowY: "auto",
                    }}
                >
                    {years.map((year) => {
                        const isSelected = selectedDate && selectedDate.jYear() === year;
                        return (
                            <Box
                                key={year}
                                onClick={() => handleYearSelect(year)}
                                sx={{
                                    textAlign: "center",
                                    py: 1.5,
                                    cursor: "pointer",
                                    borderRadius: "4px",
                                    fontSize: "14px",
                                    bgcolor: isSelected ? "primary.main" : "transparent",
                                    color: isSelected ? "primary.contrastText" : "text.primary",
                                    "&:hover": { bgcolor: isSelected ? "primary.dark" : "action.hover" },
                                }}
                            >
                                {year}
                            </Box>
                        );
                    })}
                </Box>
            </>
        );
    };

    const renderMonthView = () => (
        <>
            <Box sx={{ display: "flex", justifyContent: "center", alignItems: "center", mb: 2 }}>
                <Box
                    onClick={() => setViewMode("year")}
                    sx={{ fontWeight: 600, fontSize: "14px", cursor: "pointer" }}
                >
                    {displayDate.jYear()}
                </Box>
            </Box>
            <Box sx={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 0.5 }}>
                {MONTHS.map((monthName, idx) => {
                    const isSelected =
                        selectedDate &&
                        selectedDate.jYear() === displayDate.jYear() &&
                        selectedDate.jMonth() === idx;
                    return (
                        <Box
                            key={idx}
                            onClick={() => handleMonthSelect(idx)}
                            sx={{
                                textAlign: "center",
                                py: 1.5,
                                cursor: "pointer",
                                borderRadius: "4px",
                                fontSize: "14px",
                                bgcolor: isSelected ? "primary.main" : "transparent",
                                color: isSelected ? "primary.contrastText" : "text.primary",
                                "&:hover": { bgcolor: isSelected ? "primary.dark" : "action.hover" },
                            }}
                        >
                            {monthName}
                        </Box>
                    );
                })}
            </Box>
        </>
    );

    const renderDayView = () => {
        const days = getDaysInMonth();
        return (
            <>
                {/* Header */}
                <Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2 }}>
                    {nextIcon ? (
                        <Box ref={nextIconRef} onClick={handleNextMonth} sx={{ cursor: "pointer" }}>
                            {nextIcon}
                        </Box>
                    ) : (
                        <IconButton onClick={handleNextMonth} size="small">
                            <ChevronLeftIcon />
                        </IconButton>
                    )}

                    <Box
                        onClick={stepwise ? () => setViewMode("month") : undefined}
                        sx={{ fontWeight: 600, fontSize: "14px", cursor: stepwise ? "pointer" : "default" }}
                    >
                        {MONTHS[displayDate.jMonth()]} {displayDate.jYear()}
                    </Box>

                    {prevIcon ? (
                        <Box ref={prevIconRef} onClick={handlePrevMonth} sx={{ cursor: "pointer" }}>
                            {prevIcon}
                        </Box>
                    ) : (
                        <IconButton onClick={handlePrevMonth} size="small">
                            <ChevronRightIcon />
                        </IconButton>
                    )}
                </Box>

                {/* Weekday labels */}
                <Box sx={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0.5, mb: 1 }}>
                    {dayLabelRender ? (
                        dayLabelRender()
                    ) : (
                        <>
                            {WEEKDAYS.map((day, index) => (
                                <Box
                                    key={index}
                                    sx={{
                                        textAlign: "center",
                                        fontSize: "12px",
                                        fontWeight: 600,
                                        color: "text.secondary",
                                        py: 0.5,
                                    }}
                                >
                                    {day}
                                </Box>
                            ))}
                        </>
                    )}
                </Box>

                {/* Days grid */}
                <Box sx={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 0.5 }}>
                    {days.map((day, index) => {
                        if (!day) {
                            return <Box key={index} />;
                        }

                        const dayDate = moment(displayDate)
                            .jDate(day)
                            .jMonth(displayDate.jMonth())
                            .jYear(displayDate.jYear());

                        const isSelected =
                            selectedDate &&
                            dayDate.jYear() === selectedDate.jYear() &&
                            dayDate.jMonth() === selectedDate.jMonth() &&
                            dayDate.jDate() === selectedDate.jDate();

                        const isToday =
                            dayDate.jYear() === moment().jYear() &&
                            dayDate.jMonth() === moment().jMonth() &&
                            dayDate.jDate() === moment().jDate();

                        const isDisabled = disabledDates && disabledDates(dayDate);

                        return (
                            <Box
                                key={index}
                                onClick={() => !isDisabled && handleDateClick(day)}
                                sx={{
                                    textAlign: "center",
                                    py: 1,
                                    cursor: isDisabled ? "not-allowed" : "pointer",
                                    borderRadius: "4px",
                                    fontSize: "14px",
                                    bgcolor: isSelected ? "primary.main" : "transparent",
                                    color: isSelected
                                        ? "primary.contrastText"
                                        : isDisabled
                                            ? "text.disabled"
                                            : "text.primary",
                                    border: isToday && !isSelected ? "1px solid" : "none",
                                    borderColor: "primary.main",
                                    opacity: isDisabled ? 0.3 : 1,
                                    "&:hover": {
                                        bgcolor: isDisabled
                                            ? "transparent"
                                            : isSelected
                                                ? "primary.dark"
                                                : "action.hover",
                                    },
                                }}
                            >
                                {day}
                            </Box>
                        );
                    })}
                </Box>
            </>
        );
    };

    return (
        <div className={className}>
            <TextField
                fullWidth
                value={formatDisplayValue()}
                onClick={handleClick}
                placeholder={placeholder}
                label={label}
                error={error}
                helperText={helperText}
                disabled={disabled}
                InputProps={{
                    readOnly: true,
                }}
                {...textFieldProps}
            />
            <Popover
                open={open}
                anchorEl={anchorEl}
                onClose={handleClose}
                anchorOrigin={{
                    vertical: "bottom",
                    horizontal: "left",
                }}
                transformOrigin={{
                    vertical: "top",
                    horizontal: "left",
                }}
                sx={{
                    "& .MuiPaper-root": {
                        borderRadius: "8px",
                        boxShadow: "0px 4px 20px rgba(0, 0, 0, 0.1)",
                        overflow: "hidden",
                    },
                }}
            >
                <Box sx={{ width: 320, p: 2, bgcolor: "background.paper" }}>
                    {stepwise && viewMode === "year"
                        ? renderYearView()
                        : stepwise && viewMode === "month"
                            ? renderMonthView()
                            : renderDayView()}
                </Box>
            </Popover>
        </div>
    );
}

export default JalaliDatePicker;
