import React, { Component } from "react";
import { __ } from "@wordpress/i18n";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { Box, Grid, Typography, FormControl, Select, MenuItem, FormControlLabel, Checkbox, TextField, Button, Chip } from "@mui/material";

const DAY_KEYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
const DAY_LABELS = {
  mon: "Monday",
  tue: "Tuesday",
  wed: "Wednesday",
  thu: "Thursday",
  fri: "Friday",
  sat: "Saturday",
  sun: "Sunday",
};

class StaffDetailsWizard extends Component {
  state = {
    apbgf_booking_type: "custom",
    timings: DAY_KEYS.reduce((acc, d) => {
      acc[d] = { switch: true, start: "09:00", end: "17:00", capacity: 5, breaks: [], showBreaks: false, breakOptions: [] };
      return acc;
    }, {}),
    theme: createTheme({
      typography: {
        fontFamily: "Poppins-Medium, Poppins, sans-serif",
        h3: {
          fontSize: "2em",
          fontWeight: "500",
          textTransform: "capitalize",
          color: "#042626"
        },
        body1: {
          color: "#587373",
          marginTop: "5px"
        },
        wpbkThemeLabel: {
          color: "#042626",
          fontSize: "15px",
          fontWeight: "500",
          paddingBottom: "5px"
        },
      },
      components: {
        MuiTextField: {
          styleOverrides: {
            root: {
              border: "1px solid #57b0ee",
              height: "43px",
              borderRadius: "5px",
              justifyContent: "center",
              marginTop: "5px",
              "& fieldset": {
                border: "none"
              },
              "& .MuiOutlinedInput-root": {
                mt: "0px",
                border: "none"
              },
              "& .MuiInputBase-input": {
                fontSize: "12px",
                padding: "5px 14px 5px",
                border: "transparent",
                minHeight: "28px"
              },
              "& .MuiOutlinedInput-input:focus": {
                boxShadow: "none"
              },
            },
          },
        },
        MuiSelect: {
          styleOverrides: {
            root: {
              border: "1px solid #57b0ee",
              borderRadius: "5px",
              height: "45px",
              mt: "5px",
              "& fieldset": {
                border: "none"
              },
              "& .MuiOutlinedInput-root": {
                mt: "0px",
                border: "none"
              },
              "& .MuiInputBase-input": {
                fontSize: "12px",
                padding: "5px 14px 5px",
                border: "transparent",
                minHeight: "28px"
              },
              "& .MuiOutlinedInput-input:focus": {
                boxShadow: "none"
              },
            },
          },
        },
        MuiButton: {
          styleOverrides: {
            root: {
              border: "1px solid #57b0ee",
              borderRadius: "8px",
              margin: "10px",
              color: "#000"
            }
          },
        },
      },
    }),
  };

  formatRange = (from, to) => {
    if (!from || !to) return null;
    return `${from} - ${to}`;
  };

  getStartFromRange = (rangeOrStart) => {
    if ( ! rangeOrStart) return "";
    if (typeof rangeOrStart !== "string") return "";
    const parts = rangeOrStart.split(" - ");
    return parts[0].trim();
  };

  normalizeBreakValues = (raw) => {
    if ( ! raw ) return [];

    if (Array.isArray(raw)) {
      return raw
        .map((b) => {
          if ( ! b ) return null;
          if (typeof b === "string") return this.getStartFromRange(b);
          if (Array.isArray(b) && b.length >= 1) return this.getStartFromRange(b[0]);
          if (typeof b === "object" && (b.start || b.from)) return (b.start || b.from).trim();
          return null;
        })
        .filter(Boolean);
    }

    if (typeof raw === "string") {
      return raw
        .split(",")
        .map((s) => s.trim())
        .filter(Boolean)
        .map((s) => this.getStartFromRange(s));
    }

    if (typeof raw === "object" && (raw.start || raw.from)) {
      return [(raw.start || raw.from).trim()];
    }

    return [];
  };

  componentDidMount() {
    if (this.props.data && this.props.data.staff) {
      const incoming = this.props.data.staff;
      const mergedTimings = { ...this.state.timings };
      if (incoming.timings) {
        DAY_KEYS.forEach((d) => {
          const fromDb = incoming.timings[d] || {};
          const candidate = fromDb.breaks ?? fromDb.break;
          const breaks = this.normalizeBreakValues(candidate);
          const normalizedBreaks = breaks.length
            ? { breaks, showBreaks: true }
            : {};
          mergedTimings[d] = { ...mergedTimings[d], ...fromDb, ...normalizedBreaks };
        });
      }
      const withOptions = this.populateAllBreakOptions(mergedTimings);
      this.setState({ ...incoming, timings: withOptions });
    }
    this.saveStaff();
  }

  componentDidUpdate(prevProps, prevState) {
    if (prevState !== this.state) {
      this.saveStaff();
    }

    const prevDuration = prevProps?.data?.general?.apbgf_time_duration;
    const nextDuration = this.props?.data?.general?.apbgf_time_duration;
    const prevInterval = prevProps?.data?.general?.apbgf_time_interval;
    const nextInterval = this.props?.data?.general?.apbgf_time_interval;
    if (prevDuration !== nextDuration || prevInterval !== nextInterval) {
      const refreshed = this.populateAllBreakOptions(this.state.timings);
      if (refreshed !== this.state.timings) {
        this.setState({ timings: refreshed });
      }
    }
  }

  handleBookingType = (e) => {
    const nextType = e.target.value;
    if (nextType === "fullday") {
      const updated = { ...this.state.timings };
      DAY_KEYS.forEach((d) => {
        updated[d] = {
          ...updated[d],
          showBreaks: false,
          breakOptions: this.buildBreakRangeOptions(updated[d].start, updated[d].end),
        };
      });
      this.setState({ apbgf_booking_type: nextType, timings: updated });
    } else {
      const refreshed = this.populateAllBreakOptions(this.state.timings);
      this.setState({ apbgf_booking_type: nextType, timings: refreshed });
    }
  };

  getStateForSave = () => {
    const state = { ...this.state };
    const timings = { ...state.timings };
    DAY_KEYS.forEach((d) => {
      const t = timings[d] || {};
      const breaks = Array.isArray(t.breaks) ? t.breaks : [];
      timings[d] = { ...t, break: breaks };
    });
    return { ...state, timings };
  };

  saveStaff = () => {
    if (typeof this.props.saveStep === 'function') {
      this.props.saveStep("staff", this.getStateForSave());
    }
  };

  handleDayToggle = (day) => (e) => {
    this.setState({
      timings: { ...this.state.timings, [day]: { ...this.state.timings[day], switch: e.target.checked } },
    });
  };

  handleTimeChange = (day, key) => (e) => {
    const value = e.target.value;
    const updated = { ...this.state.timings, [day]: { ...this.state.timings[day], [key]: value } };
    const withOptions = this.populateBreakOptionsForDay(updated, day);
    this.setState({ timings: withOptions });
  };

  handleCapacityChange = (day) => (e) => {
    this.setState({
      timings: { ...this.state.timings, [day]: { ...this.state.timings[day], capacity: e.target.value } },
    });
  };

  toggleBreaks = (day) => () => {
    this.setState(
      {
        timings: { ...this.state.timings, [day]: { ...this.state.timings[day], showBreaks: !this.state.timings[day].showBreaks } },
      },
      () => this.saveStaff()
    );
  };

  handleBreaksChange = (day) => (e) => {
    const value = e.target.value;
    this.setState({ timings: { ...this.state.timings, [day]: { ...this.state.timings[day], breaks: value } } }, () => this.saveStaff());
  };

  buildBreakRangeOptions = (startHHMM, endHHMM) => {
    if (!startHHMM || !endHHMM) return [];
    const [sH, sM] = startHHMM.split(":").map(Number);
    const [eH, eM] = endHHMM.split(":").map(Number);
    const start = sH * 60 + sM;
    const end = eH * 60 + eM;
    
    if (isNaN(start) || isNaN(end) || end <= start) return [];

    const durationMinutes = this.getBreakStepMinutes();
    const intervalMinutes = this.getSlotIntervalMinutes();
    const out = [];

    for (let t = start; t + durationMinutes <= end; t += (durationMinutes + intervalMinutes)) {
      const fromH = String(Math.floor(t / 60)).padStart(2, "0");
      const fromM = String(t % 60).padStart(2, "0");
      const to = t + durationMinutes;
      const toH = String(Math.floor(to / 60)).padStart(2, "0");
      const toM = String(to % 60).padStart(2, "0");
      out.push(`${fromH}:${fromM} - ${toH}:${toM}`);
    }
    return out;
  };

  populateBreakOptionsForDay = (timings, day) => {
    const { start, end } = timings[day];
    const options = this.buildBreakRangeOptions(start, end); 

    return { ...timings, [day]: { ...timings[day], breakOptions: options } };
  };

  populateAllBreakOptions = (timings) => {
    const next = { ...timings };
    DAY_KEYS.forEach((d) => {
      const { start, end } = next[d];
      const options = this.buildBreakRangeOptions(start, end);
      next[d] = { ...next[d], breakOptions: options };
    });
    return next;
  };

  getBreakStepMinutes = () => {
    const duration = this.props?.data?.general?.apbgf_time_duration;
    const parsed = parseInt(duration, 10);
    return Number.isFinite(parsed) && parsed > 0 ? parsed : 30;
  };

  getSlotIntervalMinutes = () => {
    const interval = this.props?.data?.general?.apbgf_time_interval;
    const parsed = parseInt(interval, 10);
    return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
  };

  renderTimeRow(dayKey) {
    const d = this.state.timings[dayKey];
    const isFullDay = this.state.apbgf_booking_type === "fullday";

    return (
      <Grid container spacing={2} alignItems="center" sx={{ mb: 1 }} key={dayKey}>
        <Grid item xs={12} md={2}>
          <FormControlLabel
            control={<Checkbox checked={d.switch} onChange={this.handleDayToggle(dayKey)} />}
            label={DAY_LABELS[dayKey]}
          />
        </Grid>
        <Grid item xs={12} md={3}>
          <FormControl fullWidth>
            <TextField
              fullWidth
              type="time"
              value={d.start}
              onChange={this.handleTimeChange(dayKey, "start")}
              disabled={isFullDay}
            />
          </FormControl>
        </Grid>
        <Grid item xs={12} md={3}>
          <FormControl fullWidth>
            <TextField
              fullWidth
              type="time"
              value={d.end}
              onChange={this.handleTimeChange(dayKey, "end")}
              disabled={isFullDay}
            />
          </FormControl>
        </Grid>
        <Grid item xs={12} md={2}>
          <FormControl fullWidth>
            <TextField
              fullWidth
              type="number"
              inputProps={{ min: 0 }}
              value={d.capacity}
              onChange={this.handleCapacityChange(dayKey)}
            />
          </FormControl>
        </Grid>

        <Grid item xs={12} md={2}>
          <Button
            onClick={this.toggleBreaks(dayKey)}
            disabled={isFullDay}
          >
            {__("Add Break", "apbgf")}
          </Button>
        </Grid>
        {d.showBreaks && !isFullDay && (
          <>
            <Grid item xs={12} md={2}>
              <Typography variant="wpbkThemeLabel" component="label">
                {__("Add Break", "apbgf")}
              </Typography>
            </Grid>
            <Grid item xs={12} md={10}>
              <FormControl sx={{ width: '60%', minWidth: 220 }}>
                <Select
                  multiple
                  value={d.breaks}
                  sx={{ height: "auto" }}
                  onChange={(e) => this.handleBreaksChange(dayKey)(e)}
                  onClose={() => this.saveStaff()}
                  renderValue={(selected) => (
                    <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
                      {(selected || []).map((value) => {
                        const fullRange = d.breakOptions.find(opt => this.getStartFromRange(opt) === value) || value;
                        return (
                          <Chip
                            key={value}
                            label={fullRange} 
                            size="small"
                            onDelete={(e) => {
                              e.stopPropagation();
                              const filtered = (this.state.timings[dayKey].breaks || []).filter((v) => v !== value);
                              this.setState(
                                {
                                  timings: {
                                    ...this.state.timings,
                                    [dayKey]: { ...this.state.timings[dayKey], breaks: filtered },
                                  },
                                },
                                () => this.saveStaff()
                              );
                            }}
                            onMouseDown={(e) => e.stopPropagation()}
                            sx={{ backgroundColor: "#f0f0f0" }}
                          />
                        );
                      })}
                    </Box>
                  )}
                  >
                  {d.breakOptions && d.breakOptions.length > 0 ? (
                    d.breakOptions.map((rangeStr) => {
                      const start = this.getStartFromRange(rangeStr);
                      return (
                        <MenuItem key={rangeStr} value={start}>
                          {rangeStr}
                        </MenuItem>
                      );
                    })
                  ) : (
                    <MenuItem disabled>{__("No times available", "apbgf")}</MenuItem>
                  )}
                </Select>
              </FormControl>
            </Grid>
          </>
        )}
      </Grid>
    );
  }

  render() {
    const { theme, apbgf_booking_type } = this.state;

    return (
      <ThemeProvider theme={theme}>
        <Box component="div" className="apbgf-card" sx={{ mb: "4em" }}>
          <Typography variant="h3">{__("Staff Details", "apbgf")}</Typography>
          <Typography variant="body1" sx={{ mt: 1 }}>
            {__("Configure booking type and weekly time slots", "apbgf")}
          </Typography>
        </Box>

        <Box component="div">
          <Grid container spacing={2} sx={{ mb: 3 }}>
            <Grid item xs={12} md={12}>
              <FormControl fullWidth>
                <Typography variant="wpbkThemeLabel" component="label">
                  {__("Booking Type", "apbgf")}
                </Typography>
                <Select
                  value={apbgf_booking_type}
                  onChange={this.handleBookingType}
                  displayEmpty
                >
                  <MenuItem value="custom">{__("Custom Slots", "apbgf")}</MenuItem>
                  <MenuItem value="fullday">{__("Full Day", "apbgf")}</MenuItem>
                </Select>
              </FormControl>
            </Grid>
          </Grid>

          <Box component="div" className="form-time-slot-sec" sx={{ mt: 2 }}>
            <Typography variant="wpbkThemeLabel" component="label">
              {__("Add Time Slot", "apbgf")}
            </Typography>
            <Box component="div" className="form-time-slot-box" sx={{ mt: 2 }}>
              <Grid container spacing={2} alignItems="center" sx={{ mb: 1 }}>
                <Grid item xs={12} md={2}></Grid>
                <Grid item xs={12} md={3}><Typography variant="wpbkThemeLabel">
                  {__("Start Time", "apbgf")}
                </Typography>
                </Grid>
                <Grid item xs={12} md={3}><Typography variant="wpbkThemeLabel">
                  {__("End Time", "apbgf")}
                </Typography>
                </Grid>
                <Grid item xs={12} md={2}><Typography variant="wpbkThemeLabel">
                  {__("Slot Capacity", "apbgf")}
                </Typography>
                </Grid>
                <Grid item xs={12} md={2}></Grid>
              </Grid>

              {DAY_KEYS.map((d) => this.renderTimeRow(d))}
            </Box>
          </Box>
        </Box>
      </ThemeProvider>
    );
  }
}

export default StaffDetailsWizard;