import { JSX, useEffect, useState } from "react";
import styles from "./Calendar.module.css";
import { getMonthName, daysInMonth } from "../utils/dateUtils";
import { customerState } from "../store";
import { Box } from "../types";
import { useAtom } from "jotai";
import { markBoxDelivered, markBoxPickedUp } from "../api";

export default function Calendar() {
    const [customerData, setCustomerData] = useAtom(customerState);
    const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth());
    const [calendarCells, setCalendarCells] = useState<JSX.Element[]>([]);
    const [firstWeekPadding, setFirstWeekPadding] = useState<JSX.Element[]>([]);

    useEffect(() => {
        setCalendarCells(generateCalendarCells(selectedMonth, customerData.boxes));
        setFirstWeekPadding(generateFirstWeekPadding(selectedMonth));
    }, [selectedMonth, customerData.boxes]);

    const generateFirstWeekPadding = (month: number) => {
        const firstDay = new Date(new Date().getFullYear(), month, 1).getDay();
        const padding = Array.from({ length: firstDay === 0 ? 6 : firstDay - 1 }, (_, index) => (
            <div key={index} className={`${styles.firstWeekPaddingCell}`}>
                &nbsp;
            </div>
        ));
        return padding;
    }

    const generateCalendarCells = (month: number, boxes: Box[]) => {
        const monthDays = daysInMonth[month];

        const calendarCells = Array.from({ length: monthDays }, (_, index) => {
            const day = index + 1;
            const date = new Date(new Date().getFullYear(), month, day);
            const matchingBox = boxes.find(box => {
                const boxDate = new Date(box.delivery_date);
                return boxDate.getDate() === day && boxDate.getMonth() === month && boxDate.getFullYear() === date.getFullYear();
            });

            if (matchingBox) {
                return (
                    <div
                        key={index}
                        className={`${styles.calendarCell} ${matchingBox.pickup_date ? styles.pickedUpCell : styles.deliveredCell}`}
                        onClick={() => {
                            if (matchingBox.pickup_date) {
                                // If the box is already picked up, mark it as delivered
                                markBoxDelivered(matchingBox.id).then((updatedBox) => {
                                    setCustomerData((prev) => ({
                                        ...prev,
                                        boxes: prev.boxes.map(box =>
                                            box.id === updatedBox.id ? { ...box, pickup_date: null } : box
                                        ),
                                    }));
                                }
                                ).catch((error) => {
                                    console.error("Error marking box as delivered:", error);
                                });
                                return;
                            } else {
                                markBoxPickedUp(matchingBox.id).then((updatedBox) => {
                                    setCustomerData((prev) => ({
                                        ...prev,
                                        boxes: prev.boxes.map(box =>
                                            box.id === updatedBox.id ? { ...box, pickup_date: updatedBox.pickup_date } : box
                                        ),
                                    }));
                                }
                                ).catch((error) => {
                                    console.error("Error marking box as picked up:", error);
                                })
                            }
                        }}>
                        {date.toLocaleDateString("fi-FI", {
                            day: "2-digit",
                            month: "2-digit",
                        })}
                        <br />
                        {matchingBox.pickup_date ? (
                            <span className={styles.statusText}>Jako</span>
                        ) : (
                            <span className={styles.statusText}>Haettu</span>
                        )}
                    </div>
                );
            }

            return (
                <div key={index} className={`${styles.calendarCell}`}>
                    {date.toLocaleDateString("fi-FI", {
                        day: "2-digit",
                        month: "2-digit",
                    })}
                </div>
            );
        });
        return calendarCells;
    }

    return (
        <>
            <h2 className={styles.monthTitle}>
                {getMonthName(selectedMonth)} {new Date().getFullYear()}
            </h2>
            <div className={styles.monthNavigation}>
                <button onClick={() => setSelectedMonth((prev) => (prev - 1 + 12) % 12)} className={styles.monthNavBtn}>
                    &lt; Edellinen kuukausi
                </button>
                <button onClick={() => setSelectedMonth((prev) => (prev + 1) % 12)} className={styles.monthNavBtn}>
                    Seuraava kuukausi &gt;
                </button>
            </div>
            <div className={styles.calendarGrid}>
                <span>Ma</span>
                <span>Ti</span>
                <span>Ke</span>
                <span>To</span>
                <span>Pe</span>
                <span>La</span>
                <span>Su</span>
                {firstWeekPadding}
                {calendarCells}
            </div>
        </>
    );
}