"use client";

import { useState, type MouseEvent } from "react";

import AccessTimeOutlinedIcon from "@mui/icons-material/AccessTimeOutlined";
import ExpandLessRoundedIcon from "@mui/icons-material/ExpandLessRounded";
import ExpandMoreRoundedIcon from "@mui/icons-material/ExpandMoreRounded";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton";
import InputAdornment from "@mui/material/InputAdornment";
import Popover from "@mui/material/Popover";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import type { SxProps, Theme } from "@mui/material/styles";

import { useAppLanguage } from "@/components/providers/app-language-provider";
import { toKhmerDigits } from "@/lib/number-utils";

export type AppTimePickerProps = {
  value: string;
  onChange: (value: string) => void;
  error?: boolean;
  helperText?: string;
  inputSx?: SxProps<Theme>;
};

type TimeParts = {
  hour: number;
  minute: number;
  period: "AM" | "PM";
};

function timeValueToParts(value: string): TimeParts {
  if (!value) {
    return { hour: 12, minute: 0, period: "PM" };
  }

  const [hours, minutes] = value.split(":").map(Number);
  const period = hours >= 12 ? "PM" : "AM";
  const hour = hours % 12 || 12;

  return { hour, minute: minutes, period };
}

function timePartsToValue(parts: TimeParts) {
  const periodHours = parts.hour % 12;
  const hours = parts.period === "PM" ? periodHours + 12 : periodHours;

  return `${String(hours).padStart(2, "0")}:${String(parts.minute).padStart(2, "0")}`;
}

function adjustTime(
  parts: TimeParts,
  section: "hour" | "minute",
  amount: number,
): TimeParts {
  if (section === "hour") {
    const hour = ((parts.hour - 1 + amount + 12) % 12) + 1;
    return { ...parts, hour };
  }

  const minute = (parts.minute + amount + 60) % 60;
  return { ...parts, minute };
}

function TimeSection({
  value,
  onIncrease,
  onDecrease,
  language,
}: {
  value: string;
  onIncrease: () => void;
  onDecrease: () => void;
  language: "en" | "kh";
}) {
  const isKhmer = language === "kh";

  return (
    <Box sx={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
      <IconButton
        size="small"
        aria-label={`${isKhmer ? "បង្កើន" : "Increase"} ${value}`}
        onClick={onIncrease}
        sx={{ width: 36, height: 36, color: "text.primary" }}
      >
        <ExpandLessRoundedIcon />
      </IconButton>

      <Typography sx={{ my: 0.5, color: "text.primary", fontSize: 18 }}>
        {value}
      </Typography>

      <IconButton
        size="small"
        aria-label={`${isKhmer ? "បន្ថយ" : "Decrease"} ${value}`}
        onClick={onDecrease}
        sx={{ width: 36, height: 36, color: "text.primary" }}
      >
        <ExpandMoreRoundedIcon />
      </IconButton>
    </Box>
  );
}

function formatDisplayValue(value: string, language: "en" | "kh") {
  if (!value) return "";

  const parts = timeValueToParts(value);
  const period =
    language === "kh"
      ? parts.period === "AM"
        ? "ព្រឹក"
        : "ល្ងាច"
      : parts.period;
  const formatted = `${String(parts.hour).padStart(2, "0")}:${String(parts.minute).padStart(2, "0")} ${period}`;

  return language === "kh" ? toKhmerDigits(formatted) : formatted;
}

export function AppTimePicker({
  value,
  onChange,
  error = false,
  helperText,
  inputSx,
}: AppTimePickerProps) {
  const { language } = useAppLanguage();
  const isKhmer = language === "kh";
  const [anchorElement, setAnchorElement] = useState<HTMLElement | null>(null);
  const [draftTime, setDraftTime] = useState<TimeParts>(() =>
    timeValueToParts(value),
  );

  const handleOpen = (event: MouseEvent<HTMLElement>) => {
    setDraftTime(timeValueToParts(value));
    setAnchorElement(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorElement(null);
  };

  const updateDraft = (
    section: "hour" | "minute",
    amount: number,
  ) => {
    setDraftTime((current) => adjustTime(current, section, amount));
  };

  const handleConfirm = () => {
    onChange(timePartsToValue(draftTime));
    handleClose();
  };

  return (
    <>
      <TextField
        fullWidth
        value={formatDisplayValue(value, language)}
        placeholder={isKhmer ? "ជ្រើសរើសពេលវេលា" : "Select time"}
        onClick={handleOpen}
        error={error}
        helperText={helperText}
        slotProps={{
          htmlInput: {
            readOnly: true,
            "aria-label": isKhmer ? "ជ្រើសរើសពេលវេលា" : "Select time",
          },
          input: {
            startAdornment: (
              <InputAdornment position="start">
                <AccessTimeOutlinedIcon
                  sx={{ fontSize: 18, color: "text.secondary" }}
                />
              </InputAdornment>
            ),
          },
        }}
        sx={{
          ...inputSx,
          cursor: "pointer",
          "& .MuiInputBase-input": {
            cursor: "pointer",
            fontSize: 12,
          },
        }}
      />

      <Popover
        open={Boolean(anchorElement)}
        anchorEl={anchorElement}
        onClose={handleClose}
        anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
        transformOrigin={{ vertical: "top", horizontal: "left" }}
        sx={{ zIndex: 1700 }}
        slotProps={{
          paper: {
            sx: {
              width: 256,
              mt: 0.75,
              borderRadius: "15px",
              bgcolor: "background.paper",
              color: "text.primary",
              border: "1px solid",
              borderColor: "divider",
              boxShadow: 4,
              backgroundImage: "none",
              overflow: "hidden",
            },
          },
        }}
      >
        <Box sx={{ px: 3, pt: 1.25, pb: 1.5 }}>
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
            }}
          >
            <Box sx={{ display: "flex", alignItems: "center", gap: 1.25 }}>
              <TimeSection
                value={
                  isKhmer
                    ? toKhmerDigits(String(draftTime.hour).padStart(2, "0"))
                    : String(draftTime.hour).padStart(2, "0")
                }
                onIncrease={() => updateDraft("hour", 1)}
                onDecrease={() => updateDraft("hour", -1)}
                language={language}
              />

              <Typography sx={{ color: "text.primary", fontSize: 18 }}>
                :
              </Typography>

              <TimeSection
                value={
                  isKhmer
                    ? toKhmerDigits(String(draftTime.minute).padStart(2, "0"))
                    : String(draftTime.minute).padStart(2, "0")
                }
                onIncrease={() => updateDraft("minute", 5)}
                onDecrease={() => updateDraft("minute", -5)}
                language={language}
              />
            </Box>

            <Button
              onClick={() =>
                setDraftTime((current) => ({
                  ...current,
                  period: current.period === "AM" ? "PM" : "AM",
                }))
              }
              sx={{
                minWidth: 44,
                height: 36,
                borderRadius: "18px",
                color: "text.primary",
                fontSize: 18,
                fontWeight: 400,
                textTransform: "none",
                "&:hover": {
                  bgcolor: "action.hover",
                },
              }}
            >
              {isKhmer
                ? draftTime.period === "AM"
                  ? "ព្រឹក"
                  : "ល្ងាច"
                : draftTime.period}
            </Button>
          </Box>

          <Box sx={{ mt: 1.25, display: "flex", justifyContent: "center", gap: 1 }}>
            <Button
              variant="outlined"
              onClick={handleClose}
              sx={{
                width: 86,
                height: 28,
                borderColor: "divider",
                borderRadius: "6px",
                color: "text.primary",
                fontSize: 12,
                textTransform: "none",
                "&:hover": {
                  borderColor: "text.secondary",
                  bgcolor: "action.hover",
                },
              }}
            >
              {isKhmer ? "បោះបង់" : "Cancel"}
            </Button>

            <Button
              variant="contained"
              onClick={handleConfirm}
              sx={{
                width: 86,
                height: 28,
                borderRadius: "6px",
                bgcolor: "primary.main",
                boxShadow: "none",
                fontSize: 12,
                textTransform: "none",
                "&:hover": {
                  bgcolor: "primary.dark",
                  boxShadow: "none",
                },
              }}
            >
              {isKhmer ? "បញ្ជាក់" : "Confirm"}
            </Button>
          </Box>
        </Box>
      </Popover>
    </>
  );
}
