package org.example.petshopdesktop.ui;

import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;

public class CalendarPane extends VBox {

    private LocalDate currentDate = LocalDate.now();
    private LocalDate selectedDate = null;
    private Set<LocalDate> eventDates = new HashSet<>();
    private boolean weekMode = true;
    private Consumer<LocalDate> onDateSelected;
    private Label lblHeader;
    private GridPane dayGrid;
    private Button btnToggle;

    public CalendarPane() {
        setSpacing(6);
        setPadding(new Insets(10, 12, 10, 12));
        setStyle("-fx-background-color: white; -fx-border-color: #e6e6e6; -fx-border-radius: 12; -fx-background-radius: 12;");

        lblHeader = new Label();
        lblHeader.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(lblHeader, Priority.ALWAYS);
        lblHeader.setAlignment(Pos.CENTER);
        lblHeader.setStyle("-fx-font-weight: bold; -fx-font-size: 13;");

        Button btnPrev = new Button("‹");
        btnPrev.setStyle("-fx-background-color: transparent; -fx-font-size: 18; -fx-text-fill: #7f8c8d; -fx-cursor: hand;");
        btnPrev.setOnAction(e -> navigate(-1));

        Button btnNext = new Button("›");
        btnNext.setStyle("-fx-background-color: transparent; -fx-font-size: 18; -fx-text-fill: #7f8c8d; -fx-cursor: hand;");
        btnNext.setOnAction(e -> navigate(1));

        btnToggle = new Button("Month");
        btnToggle.setStyle("-fx-background-color: #4ECDC4; -fx-text-fill: white; -fx-font-size: 11; -fx-font-weight: bold; -fx-background-radius: 6; -fx-cursor: hand;");
        btnToggle.setPadding(new Insets(4, 10, 4, 10));
        btnToggle.setOnAction(e -> {
            weekMode = !weekMode;
            btnToggle.setText(weekMode ? "Month" : "Week");
            rebuild();
        });

        HBox navHeader = new HBox(4, btnPrev, lblHeader, btnNext, btnToggle);
        navHeader.setAlignment(Pos.CENTER_LEFT);

        GridPane dowHeader = new GridPane();
        String[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
        for (int i = 0; i < 7; i++) {
            ColumnConstraints cc = new ColumnConstraints();
            cc.setHgrow(Priority.ALWAYS);
            dowHeader.getColumnConstraints().add(cc);
            Label lbl = new Label(days[i]);
            lbl.setStyle("-fx-font-size: 11; -fx-text-fill: #95a5a6; -fx-font-weight: bold;");
            lbl.setMaxWidth(Double.MAX_VALUE);
            lbl.setAlignment(Pos.CENTER);
            dowHeader.add(lbl, i, 0);
        }

        dayGrid = new GridPane();
        dayGrid.setHgap(2);
        dayGrid.setVgap(2);

        getChildren().addAll(navHeader, dowHeader, dayGrid);
        rebuild();
    }

    public void setEventDates(Set<LocalDate> dates) {
        eventDates = new HashSet<>(dates);
        rebuild();
    }

    public void setOnDateSelected(Consumer<LocalDate> handler) {
        onDateSelected = handler;
    }

    private void navigate(int direction) {
        if (weekMode) {
            currentDate = currentDate.plusWeeks(direction);
        } else {
            currentDate = currentDate.plusMonths(direction);
        }
        rebuild();
    }

    private void rebuild() {
        dayGrid.getChildren().clear();
        dayGrid.getColumnConstraints().clear();

        for (int i = 0; i < 7; i++) {
            ColumnConstraints cc = new ColumnConstraints();
            cc.setHgrow(Priority.ALWAYS);
            cc.setFillWidth(true);
            dayGrid.getColumnConstraints().add(cc);
        }

        if (weekMode) {
            int dow = currentDate.getDayOfWeek().getValue() % 7;
            LocalDate startOfWeek = currentDate.minusDays(dow);
            lblHeader.setText("Week of " + startOfWeek.format(DateTimeFormatter.ofPattern("MMM d, yyyy")));
            for (int col = 0; col < 7; col++) {
                dayGrid.add(buildDayCell(startOfWeek.plusDays(col)), col, 0);
            }
        } else {
            YearMonth ym = YearMonth.of(currentDate.getYear(), currentDate.getMonthValue());
            lblHeader.setText(currentDate.format(DateTimeFormatter.ofPattern("MMMM yyyy")));
            int firstDow = ym.atDay(1).getDayOfWeek().getValue() % 7;
            int daysInMonth = ym.lengthOfMonth();
            int rows = (int) Math.ceil((firstDow + daysInMonth) / 7.0);

            for (int row = 0; row < rows; row++) {
                for (int col = 0; col < 7; col++) {
                    int dayNum = row * 7 + col - firstDow + 1;
                    if (dayNum >= 1 && dayNum <= daysInMonth) {
                        dayGrid.add(buildDayCell(ym.atDay(dayNum)), col, row);
                    } else {
                        Region spacer = new Region();
                        spacer.setPrefSize(36, 36);
                        dayGrid.add(spacer, col, row);
                    }
                }
            }
        }
    }

    private StackPane buildDayCell(LocalDate date) {
        boolean isSelected = date.equals(selectedDate);
        boolean isToday = date.equals(LocalDate.now());
        boolean hasEvent = eventDates.contains(date);

        StackPane cell = new StackPane();
        cell.setPrefSize(36, 36);
        cell.setMaxWidth(Double.MAX_VALUE);

        String baseStyle;
        String labelColor;
        String labelWeight = "-fx-font-weight: bold;";

        if (isSelected) {
            baseStyle = "-fx-background-color: #4ECDC4; -fx-background-radius: 8; -fx-cursor: hand;";
            labelColor = "-fx-text-fill: white;";
        } else if (isToday) {
            baseStyle = "-fx-background-color: #e8faf8; -fx-background-radius: 8; -fx-border-color: #4ECDC4; -fx-border-radius: 8; -fx-border-width: 1.5; -fx-cursor: hand;";
            labelColor = "-fx-text-fill: #2abb9b;";
        } else {
            baseStyle = "-fx-background-radius: 8; -fx-cursor: hand;";
            labelColor = "-fx-text-fill: #2c3e50;";
            labelWeight = "";
        }

        cell.setStyle(baseStyle);

        Label dayLabel = new Label(String.valueOf(date.getDayOfMonth()));
        dayLabel.setStyle("-fx-font-size: 12; " + labelColor + labelWeight);

        VBox inner = new VBox(1);
        inner.setAlignment(Pos.CENTER);
        inner.getChildren().add(dayLabel);

        if (hasEvent) {
            Circle dot = new Circle(3, Color.web("#FF6b6b"));
            inner.getChildren().add(dot);
        } else {
            Region spacer = new Region();
            spacer.setPrefHeight(6);
            inner.getChildren().add(spacer);
        }

        cell.getChildren().add(inner);

        if (!isSelected && !isToday) {
            cell.setOnMouseEntered(e -> cell.setStyle("-fx-background-color: #f0f9f8; -fx-background-radius: 8; -fx-cursor: hand;"));
            cell.setOnMouseExited(e -> cell.setStyle(baseStyle));
        }

        cell.setOnMouseClicked(e -> {
            if (date.equals(selectedDate)) {
                selectedDate = null;
            } else {
                selectedDate = date;
                currentDate = date;
            }
            rebuild();
            if (onDateSelected != null) {
                onDateSelected.accept(selectedDate);
            }
        });

        return cell;
    }
}
