import { useState, useEffect, useRef } from "react";
import { useQuery } from "@tanstack/react-query";
import { Link as RouterLink } from "react-router-dom";
import { parseISO, isValid } from "date-fns";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import {
  formatTime,
  calculateWorkMinutes,
  formatMinutes,
} from "../utils/attendanceHelpers";
import Forbidden from "../components/Forbidden";
import apiFetch from "../utils/api";
import { jsonQuery } from "../lib/apiAdapter";
import { useApiMutation } from "../lib/queries/mutations";
import { czechPlural, todayLocalStr } from "../utils/formatters";
import {
  Button,
  Card,
  DataTable,
  DateField,
  Field,
  Modal,
  ConfirmDialog,
  Select,
  StatCard,
  StatusChip,
  TextField,
  ProgressBar,
  PageEnter,
  EmptyState,
  LoadingState,
  type DataColumn,
  type ProgressColor,
} from "../ui";

const API_BASE = "/api/admin";

interface ShiftRecord {
  id: number;
  user_id: number;
  shift_date: string;
  arrival_time?: string | null;
  departure_time?: string | null;
  break_start?: string | null;
  break_end?: string | null;
  notes?: string | null;
  project_id?: number | null;
  project_logs?: ProjectLog[];
}

interface ProjectLog {
  id?: number;
  project_id?: number;
  project_name?: string;
  started_at?: string;
  ended_at?: string | null;
}

interface Project {
  id: number;
  name: string;
  project_number: string;
}

interface LeaveBalance {
  vacation_total: number;
  vacation_used: number;
  vacation_remaining: number;
  sick_used: number;
}

interface MonthlyFund {
  month_name: string;
  fund: number;
  worked: number;
  covered: number;
  remaining: number;
  overtime: number;
  leave_hours: number;
  vacation_hours: number;
  sick_hours: number;
  unpaid_hours: number;
}

interface AttendanceData {
  ongoing_shift: ShiftRecord | null;
  today_shifts: ShiftRecord[];
  date: string;
  leave_balance: LeaveBalance;
  monthly_fund: MonthlyFund | null;
  project_logs: ProjectLog[];
  active_project_id: number | null;
}

/** Maps the monthly-fund state to a ProgressBar color token. Mirrors the legacy
 *  getFundBarBackground gradient conditional: overtime→warning, covered≥fund→
 *  success, otherwise→primary (was the accent gradient). */
function getFundBarColor(fund: MonthlyFund): ProgressColor {
  if (fund.overtime > 0) return "warning";
  if (fund.covered >= fund.fund) return "success";
  return "primary";
}

const CalendarIcon = (
  <svg
    width="24"
    height="24"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
    <line x1="16" y1="2" x2="16" y2="6" />
    <line x1="8" y1="2" x2="8" y2="6" />
    <line x1="3" y1="10" x2="21" y2="10" />
  </svg>
);

const VacationIcon = (
  <svg
    width="24"
    height="24"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
  </svg>
);

const SickIcon = (
  <svg
    width="24"
    height="24"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M22 12h-4l-3 9L9 3l-3 9H2" />
  </svg>
);

const RequestsIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M9 11l3 3L22 4" />
    <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
  </svg>
);

const HistoryIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M3 3v18h18" />
    <path d="M18.7 8l-5.1 5.2-2.8-2.7L7 14.3" />
  </svg>
);

const ManageIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
    <circle cx="9" cy="7" r="4" />
    <path d="M23 21v-2a4 4 0 0 0-3-3.87" />
    <path d="M16 3.13a4 4 0 0 1 0 7.75" />
  </svg>
);

const BalancesIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
  </svg>
);

const ChevronIcon = (
  <svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M9 18l6-6-6-6" />
  </svg>
);

/** Sidebar navigation row: icon + label on the left, chevron on the right. */
function QuickLink({
  to,
  icon,
  label,
}: {
  to: string;
  icon: React.ReactNode;
  label: string;
}) {
  return (
    <Button
      component={RouterLink}
      to={to}
      variant="text"
      color="inherit"
      sx={{
        justifyContent: "flex-start",
        width: "100%",
        gap: 1.25,
        px: 1.5,
        py: 1.25,
        borderRadius: 2,
        color: "text.primary",
        fontWeight: 500,
        "& .nav-chevron": { ml: "auto", color: "text.disabled" },
      }}
    >
      <Box sx={{ display: "flex", color: "text.secondary" }}>{icon}</Box>
      <span>{label}</span>
      <Box component="span" className="nav-chevron" sx={{ display: "flex" }}>
        {ChevronIcon}
      </Box>
    </Button>
  );
}

export default function Attendance() {
  const alert = useAlert();
  const { hasPermission } = useAuth();

  const statusQuery = useQuery({
    queryKey: ["attendance", "status"],
    queryFn: () => jsonQuery<AttendanceData>("/api/admin/attendance/status"),
  });

  const projectsQuery = useQuery({
    queryKey: ["attendance", "projects"],
    queryFn: () =>
      jsonQuery<Project[]>("/api/admin/attendance?action=projects"),
  });

  const punchMutation = useApiMutation<
    Record<string, unknown>,
    { message?: string }
  >({
    url: () => `${API_BASE}/attendance`,
    method: () => "POST",
    // dashboard included: the punch-button state + presence cards live there.
    invalidate: ["attendance", "dashboard"],
  });

  const notesMutation = useApiMutation<{ notes: string }, { message?: string }>(
    {
      url: () => `${API_BASE}/attendance/notes`,
      method: () => "POST",
      invalidate: ["attendance"],
    },
  );

  const switchProjectMutation = useApiMutation<
    { project_id: number | null },
    { message?: string }
  >({
    url: () => `${API_BASE}/attendance/switch-project`,
    method: () => "POST",
    invalidate: ["attendance"],
  });

  const leaveRequestMutation = useApiMutation<
    { leave_type: string; date_from: string; date_to: string; notes: string },
    { message?: string }
  >({
    url: () => `${API_BASE}/leave-requests`,
    method: () => "POST",
    // dashboard included: approvers see the pending-requests KPI there.
    invalidate: ["attendance", "leave-requests", "leave", "users", "dashboard"],
  });

  const [submitting, setSubmitting] = useState(false);
  const [isLeaveModalOpen, setIsLeaveModalOpen] = useState(false);
  const [leaveForm, setLeaveForm] = useState({
    leave_type: "vacation",
    date_from: todayLocalStr(),
    date_to: todayLocalStr(),
    notes: "",
  });
  const [requestSubmitting, setRequestSubmitting] = useState(false);
  const [notes, setNotes] = useState("");
  const [switchingProject, setSwitchingProject] = useState(false);
  const [gpsConfirm, setGpsConfirm] = useState<{
    isOpen: boolean;
    action: string | null;
  }>({ isOpen: false, action: null });
  const geoAbortRef = useRef<AbortController | null>(null);
  const punchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const mountedRef = useRef(true);
  const latestActionRef = useRef<string | null>(null);

  // Live wall-clock display (HH:MM) — re-render every 30s so the shown time
  // actually advances instead of freezing at first paint.
  const [now, setNow] = useState(() => new Date());

  useEffect(() => {
    mountedRef.current = true;
    return () => {
      mountedRef.current = false;
      if (geoAbortRef.current) geoAbortRef.current.abort();
      if (punchTimeoutRef.current) clearTimeout(punchTimeoutRef.current);
    };
  }, []);

  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 30_000);
    return () => clearInterval(id);
  }, []);

  // Sync notes from query data when the shift changes
  useEffect(() => {
    if (statusQuery.data) {
      setNotes(statusQuery.data.ongoing_shift?.notes || "");
    }
  }, [statusQuery.data]);

  if (!hasPermission("attendance.record")) return <Forbidden />;

  const handlePunch = (action: string) => {
    setSubmitting(true);
    latestActionRef.current = action;

    // Some browsers silently hang on getCurrentPosition (especially with
    // enableHighAccuracy:true on desktops without GPS). Use a short safety
    // timeout and proceed without GPS rather than leaving the user stuck.
    const safetyTimeout = setTimeout(() => {
      if (mountedRef.current) {
        submitPunch(action, {});
      }
    }, 6000);

    if (!navigator.geolocation) {
      clearTimeout(safetyTimeout);
      alert.warning("GPS není dostupná");
      submitPunch(action, {});
      return;
    }

    navigator.geolocation.getCurrentPosition(
      (position) => {
        clearTimeout(safetyTimeout);
        if (!mountedRef.current) return;
        try {
          const { latitude, longitude, accuracy } = position.coords;
          submitPunch(action, { latitude, longitude, accuracy, address: "" });
        } catch {
          submitPunch(action, {});
        }

        // Fire-and-forget reverse geocoding to update the address later
        if (geoAbortRef.current) geoAbortRef.current.abort();
        const controller = new AbortController();
        geoAbortRef.current = controller;
        fetch(
          `https://nominatim.openstreetmap.org/reverse?format=json&lat=${position.coords.latitude}&lon=${position.coords.longitude}&zoom=18&addressdetails=1`,
          {
            headers: { "Accept-Language": "cs" },
            signal: controller.signal,
          },
        )
          .then((r) => r.json())
          .then((geoData) => {
            if (!mountedRef.current) return;
            if (latestActionRef.current !== action) return;
            if (geoData.display_name) {
              apiFetch(`${API_BASE}/attendance/update-address`, {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                  latitude: position.coords.latitude,
                  longitude: position.coords.longitude,
                  address: geoData.display_name,
                  punch_action: action,
                }),
              }).catch(() => {});
            }
          })
          .catch(() => {});
      },
      (geoError) => {
        clearTimeout(safetyTimeout);
        if (!mountedRef.current) return;
        let errorMsg = "Nepodařilo se získat polohu";
        if (geoError.code === geoError.PERMISSION_DENIED) {
          errorMsg = "Přístup k poloze byl zamítnut";
        } else if (geoError.code === geoError.TIMEOUT) {
          errorMsg = "Vypršel časový limit";
        }
        alert.error(errorMsg);
        setSubmitting(false);
        setGpsConfirm({ isOpen: true, action });
      },
      { enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 },
    );
  };

  const submitPunch = async (
    action: string,
    gpsData: Record<string, unknown> = {},
  ) => {
    try {
      const result = await punchMutation.mutateAsync({
        punch_action: action,
        ...gpsData,
      });
      setSubmitting(false);
      punchTimeoutRef.current = setTimeout(() => {
        alert.success(result?.message || "Uloženo");
      }, 300);
    } catch (e) {
      setSubmitting(false);
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleBreak = async () => {
    setSubmitting(true);
    try {
      const result = await punchMutation.mutateAsync({
        punch_action: "break_start",
      });
      alert.success(result?.message || "Přestávka zaznamenána");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setSubmitting(false);
    }
  };

  const handleSaveNotes = async () => {
    try {
      await notesMutation.mutateAsync({ notes });
      alert.success("Poznámka byla uložena");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const handleSwitchProject = async (newProjectId: string | null) => {
    setSwitchingProject(true);
    try {
      const result = await switchProjectMutation.mutateAsync({
        project_id: newProjectId ? Number(newProjectId) : null,
      });
      alert.success(result?.message || "Projekt přepnut");
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setSwitchingProject(false);
    }
  };

  // Parse a YYYY-MM-DD string into a LOCAL-midnight Date. `new Date("YYYY-MM-DD")`
  // would parse as UTC midnight; reading it back with local getDay()/getDate()
  // can land on the wrong calendar day in the evening Prague window.
  const parseLocalDate = (s: string): Date | null => {
    const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(s);
    if (!m) return null;
    return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
  };

  const calculateBusinessDays = (from: string, to: string) => {
    if (!from || !to) return 0;
    const start = parseLocalDate(from);
    const end = parseLocalDate(to);
    if (!start || !end) return 0;
    if (end < start) return 0;
    let days = 0;
    const current = new Date(start);
    while (current <= end) {
      const day = current.getDay();
      if (day !== 0 && day !== 6) days++;
      current.setDate(current.getDate() + 1);
    }
    return days;
  };

  const handleRequestSubmit = async () => {
    setRequestSubmitting(true);
    try {
      const result = await leaveRequestMutation.mutateAsync(leaveForm);
      setIsLeaveModalOpen(false);
      await new Promise((resolve) => setTimeout(resolve, 300));
      alert.success(result?.message || "Žádost odeslána");
      setLeaveForm({
        leave_type: "vacation",
        date_from: todayLocalStr(),
        date_to: todayLocalStr(),
        notes: "",
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setRequestSubmitting(false);
    }
  };

  if (statusQuery.isPending) {
    return <LoadingState />;
  }
  if (!statusQuery.data) {
    return null;
  }

  const {
    ongoing_shift: ongoingShift,
    today_shifts: todayShifts,
    leave_balance: leaveBalance,
  } = statusQuery.data;
  const data = statusQuery.data;
  const projects = projectsQuery.data ?? [];
  const projectLogs = data.project_logs ?? [];
  const activeProjectId = data.active_project_id ?? null;
  const isOngoingShift = ongoingShift && !ongoingShift.departure_time;
  const completedToday = todayShifts.filter((s) => s.departure_time);
  const vacationDaysRemaining = Math.floor(leaveBalance.vacation_remaining / 8);
  const vacationHoursRemaining = leaveBalance.vacation_remaining % 8;

  const businessDays = calculateBusinessDays(
    leaveForm.date_from,
    leaveForm.date_to,
  );

  const completedColumns: DataColumn<ShiftRecord>[] = [
    {
      key: "arrival",
      header: "Příchod",
      mono: true,
      render: (shift) => formatTime(shift.arrival_time),
    },
    {
      key: "break",
      header: "Pauza",
      mono: true,
      render: (shift) =>
        shift.break_start && shift.break_end
          ? `${formatTime(shift.break_start)} - ${formatTime(shift.break_end)}`
          : "—",
    },
    {
      key: "departure",
      header: "Odchod",
      mono: true,
      render: (shift) => formatTime(shift.departure_time),
    },
    {
      key: "worked",
      header: "Odpracováno",
      mono: true,
      render: (shift) =>
        formatMinutes(
          calculateWorkMinutes({
            ...shift,
            notes: shift.notes ?? undefined,
          }),
          true,
        ),
    },
    ...(projects.length > 0
      ? [
          {
            key: "projects",
            header: "Projekty",
            render: (shift: ShiftRecord) => {
              const shiftLogs = shift.project_logs || [];
              if (shiftLogs.length === 0) return "—";
              return (
                <Box
                  sx={{ display: "flex", flexDirection: "column", gap: 0.25 }}
                >
                  {shiftLogs.map((log, i) => {
                    if (!log.started_at) return null;
                    const mins = log.ended_at
                      ? Math.floor(
                          (new Date(log.ended_at).getTime() -
                            new Date(log.started_at).getTime()) /
                            60000,
                        )
                      : 0;
                    const h = Math.floor(mins / 60);
                    const mm = mins % 60;
                    return (
                      <Typography
                        key={log.id || i}
                        variant="caption"
                        sx={{ fontSize: "12px" }}
                      >
                        {log.project_name || `#${log.project_id}`} ({h}:
                        {String(mm).padStart(2, "0")}h)
                      </Typography>
                    );
                  })}
                </Box>
              );
            },
          } as DataColumn<ShiftRecord>,
        ]
      : []),
  ];

  return (
    <PageEnter>
      <Box sx={{ mb: 3 }}>
        <Typography variant="h4">Docházka</Typography>
        <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
          {new Date().toLocaleDateString("cs-CZ", {
            weekday: "long",
            day: "numeric",
            month: "long",
            year: "numeric",
          })}
        </Typography>
      </Box>

      <Box
        sx={{
          display: "grid",
          gridTemplateColumns: {
            xs: "minmax(0, 1fr)",
            lg: "minmax(0, 1fr) 340px",
          },
          gap: 3,
          alignItems: "start",
        }}
      >
        {/* Left Column - Clock In/Out */}
        <Box sx={{ minWidth: 0 }}>
          <Card>
            <Box
              sx={{
                display: "flex",
                justifyContent: "space-between",
                alignItems: "center",
                mb: 2.5,
              }}
            >
              <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
                <Box
                  sx={{
                    width: 10,
                    height: 10,
                    borderRadius: "50%",
                    bgcolor: isOngoingShift ? "success.main" : "text.disabled",
                    boxShadow: isOngoingShift
                      ? (theme) => `0 0 0 4px ${theme.palette.success.main}33`
                      : "none",
                  }}
                />
                <Typography sx={{ fontWeight: 600, color: "text.secondary" }}>
                  {isOngoingShift ? "Pracuji" : "Nepracuji"}
                </Typography>
              </Box>
              <Typography
                sx={{
                  fontFamily: "'DM Mono', Menlo, monospace",
                  fontSize: "2rem",
                  fontWeight: 700,
                  lineHeight: 1,
                }}
              >
                {now.toLocaleTimeString("cs-CZ", {
                  hour: "2-digit",
                  minute: "2-digit",
                })}
              </Typography>
            </Box>

            {isOngoingShift ? (
              <>
                <Box
                  sx={{
                    display: "grid",
                    gridTemplateColumns: "repeat(3, 1fr)",
                    gap: 2,
                    mb: 2.5,
                  }}
                >
                  <Box>
                    <Typography
                      variant="caption"
                      color="text.secondary"
                      sx={{
                        display: "block",
                        textTransform: "uppercase",
                        letterSpacing: ".05em",
                        fontWeight: 600,
                      }}
                    >
                      Příchod
                    </Typography>
                    <Typography
                      sx={{
                        fontFamily: "'DM Mono', Menlo, monospace",
                        fontWeight: 600,
                        color: "success.main",
                      }}
                    >
                      {formatTime(ongoingShift.arrival_time)}
                    </Typography>
                  </Box>
                  <Box>
                    <Typography
                      variant="caption"
                      color="text.secondary"
                      sx={{
                        display: "block",
                        textTransform: "uppercase",
                        letterSpacing: ".05em",
                        fontWeight: 600,
                      }}
                    >
                      Pauza
                    </Typography>
                    <Typography
                      sx={{
                        fontFamily: "'DM Mono', Menlo, monospace",
                        fontWeight: 600,
                        color: ongoingShift.break_start
                          ? "success.main"
                          : "text.primary",
                      }}
                    >
                      {ongoingShift.break_start
                        ? `${formatTime(ongoingShift.break_start)} - ${formatTime(ongoingShift.break_end)}`
                        : "—"}
                    </Typography>
                  </Box>
                  <Box>
                    <Typography
                      variant="caption"
                      color="text.secondary"
                      sx={{
                        display: "block",
                        textTransform: "uppercase",
                        letterSpacing: ".05em",
                        fontWeight: 600,
                      }}
                    >
                      Odchod
                    </Typography>
                    <Typography
                      sx={{
                        fontFamily: "'DM Mono', Menlo, monospace",
                        fontWeight: 600,
                      }}
                    >
                      —
                    </Typography>
                  </Box>
                </Box>

                {projects.length > 0 && (
                  <Box sx={{ mb: 2.5 }}>
                    <Box
                      sx={{
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                        mb: 1,
                      }}
                    >
                      <Typography
                        variant="caption"
                        color="text.secondary"
                        sx={{
                          textTransform: "uppercase",
                          letterSpacing: ".05em",
                          fontWeight: 600,
                        }}
                      >
                        Projekt
                      </Typography>
                      {activeProjectId ? (
                        <StatusChip
                          color="info"
                          label={
                            projects.find(
                              (p) => String(p.id) === String(activeProjectId),
                            )
                              ? `${projects.find((p) => String(p.id) === String(activeProjectId))!.project_number} – ${projects.find((p) => String(p.id) === String(activeProjectId))!.name}`
                              : `Projekt #${activeProjectId}`
                          }
                          sx={{
                            height: "auto",
                            "& .MuiChip-label": {
                              whiteSpace: "normal",
                              py: 0.25,
                            },
                          }}
                        />
                      ) : (
                        <Typography variant="caption" color="text.disabled">
                          Žádný
                        </Typography>
                      )}
                    </Box>
                    <Select
                      value={activeProjectId ? String(activeProjectId) : ""}
                      onChange={(val) => handleSwitchProject(val || null)}
                      disabled={switchingProject}
                      options={[
                        { value: "", label: "— Bez projektu —" },
                        ...projects.map((p) => ({
                          value: String(p.id),
                          label: `${p.project_number} – ${p.name}`,
                        })),
                      ]}
                    />
                    {projectLogs.length > 0 && (
                      <Box
                        sx={{
                          display: "flex",
                          flexDirection: "column",
                          gap: 0.75,
                          mt: 1.5,
                        }}
                      >
                        {projectLogs.map((log, i) => {
                          if (!log.started_at) return null;
                          const start = new Date(log.started_at);
                          const end = log.ended_at
                            ? new Date(log.ended_at)
                            : new Date();
                          const mins = Math.max(
                            0,
                            Math.floor(
                              (end.getTime() - start.getTime()) / 60000,
                            ),
                          );
                          const h = Math.floor(mins / 60);
                          const mm = mins % 60;
                          return (
                            <Box
                              key={log.id || i}
                              sx={{
                                display: "flex",
                                alignItems: "center",
                                gap: 1,
                                justifyContent: "space-between",
                              }}
                            >
                              <Typography
                                variant="body2"
                                sx={{ fontWeight: 600, flex: 1, minWidth: 0 }}
                                noWrap
                              >
                                {log.project_name ||
                                  `Projekt #${log.project_id}`}
                              </Typography>
                              <Typography
                                variant="caption"
                                color="text.secondary"
                                sx={{
                                  fontFamily: "'DM Mono', Menlo, monospace",
                                }}
                              >
                                {formatTime(log.started_at)} –{" "}
                                {log.ended_at
                                  ? formatTime(log.ended_at)
                                  : "nyní"}
                              </Typography>
                              <StatusChip
                                color="default"
                                label={`${h}:${String(mm).padStart(2, "0")} h`}
                              />
                            </Box>
                          );
                        })}
                      </Box>
                    )}
                  </Box>
                )}

                <Box
                  sx={{
                    display: "flex",
                    flexDirection: "column",
                    gap: 1.25,
                  }}
                >
                  {!ongoingShift.break_start && (
                    <Button
                      onClick={handleBreak}
                      disabled={submitting}
                      variant="outlined"
                      color="inherit"
                      fullWidth
                    >
                      Pauza (30 min)
                    </Button>
                  )}
                  <Button
                    onClick={() => handlePunch("departure")}
                    disabled={submitting}
                    fullWidth
                  >
                    {submitting ? "Zpracovávám..." : "Odchod"}
                  </Button>
                  <Button
                    onClick={() => setIsLeaveModalOpen(true)}
                    variant="outlined"
                    color="inherit"
                    fullWidth
                  >
                    Žádost o nepřítomnost
                  </Button>
                </Box>

                <Box sx={{ mt: 2.5 }}>
                  <Field label="Poznámka ke směně">
                    <TextField
                      multiline
                      minRows={3}
                      value={notes}
                      onChange={(e) => setNotes(e.target.value)}
                      placeholder="Co jste dělali během směny..."
                    />
                  </Field>
                  <Box>
                    <Button
                      onClick={handleSaveNotes}
                      variant="outlined"
                      color="inherit"
                      size="small"
                    >
                      Uložit poznámku
                    </Button>
                  </Box>
                </Box>
              </>
            ) : (
              <Box sx={{ display: "flex", flexDirection: "column", gap: 1.25 }}>
                <Button
                  onClick={() => handlePunch("arrival")}
                  disabled={submitting}
                  fullWidth
                >
                  {submitting ? "Zpracovávám..." : "Příchod"}
                </Button>

                <Button
                  onClick={() => setIsLeaveModalOpen(true)}
                  variant="outlined"
                  color="inherit"
                  fullWidth
                >
                  Žádost o nepřítomnost
                </Button>
              </Box>
            )}
          </Card>

          {/* Completed Today */}
          {completedToday.length > 0 && (
            <Card sx={{ mt: 3 }}>
              <Typography variant="h6" sx={{ mb: 2 }}>
                Dnešní dokončené směny
              </Typography>
              <DataTable<ShiftRecord>
                columns={completedColumns}
                rows={completedToday}
                rowKey={(shift) => shift.id}
                empty={<EmptyState title="Žádné dokončené směny." />}
              />
            </Card>
          )}
        </Box>

        {/* Right Column - Stats & Quick Links */}
        <Box
          sx={{ display: "flex", flexDirection: "column", gap: 3, minWidth: 0 }}
        >
          {/* Leave Balance Card */}
          <StatCard
            icon={VacationIcon}
            color="success"
            label={`Dovolená ${new Date().getFullYear()}`}
            value={
              <>
                {vacationDaysRemaining}{" "}
                <Typography
                  component="span"
                  variant="body2"
                  color="text.secondary"
                  sx={{ fontFamily: "inherit" }}
                >
                  {czechPlural(vacationDaysRemaining, "den", "dny", "dnů")}
                  {vacationHoursRemaining > 0 && ` ${vacationHoursRemaining}h`}
                </Typography>
              </>
            }
            footer={
              <Box>
                <Box
                  sx={{
                    display: "flex",
                    justifyContent: "space-between",
                    mb: 0.75,
                  }}
                >
                  <span>Celkem: {leaveBalance.vacation_total}h</span>
                  <span>Čerpáno: {leaveBalance.vacation_used}h</span>
                </Box>
                <ProgressBar
                  value={
                    leaveBalance.vacation_total > 0
                      ? (leaveBalance.vacation_remaining /
                          leaveBalance.vacation_total) *
                        100
                      : 0
                  }
                  color="success"
                  height={6}
                />
              </Box>
            }
          />

          {/* Monthly Fund Card */}
          {data.monthly_fund && (
            <StatCard
              icon={CalendarIcon}
              color="info"
              label={data.monthly_fund.month_name}
              value={`${data.monthly_fund.worked}h / ${data.monthly_fund.fund}h`}
              footer={
                <Box>
                  <Box
                    sx={{
                      display: "flex",
                      justifyContent: "space-between",
                      mb: 0.75,
                    }}
                  >
                    <span>Odpracováno: {data.monthly_fund.worked}h</span>
                    {data.monthly_fund.overtime > 0 ? (
                      <Box
                        component="span"
                        sx={{ color: "warning.main", fontWeight: 600 }}
                      >
                        Přesčas: +{data.monthly_fund.overtime}h
                      </Box>
                    ) : (
                      <span>Zbývá: {data.monthly_fund.remaining}h</span>
                    )}
                  </Box>
                  <ProgressBar
                    value={
                      data.monthly_fund.fund > 0
                        ? Math.min(
                            100,
                            (data.monthly_fund.covered /
                              data.monthly_fund.fund) *
                              100,
                          )
                        : 0
                    }
                    color={getFundBarColor(data.monthly_fund)}
                    height={6}
                  />
                  {data.monthly_fund.leave_hours > 0 && (
                    <Box sx={{ mt: 0.5, color: "text.disabled" }}>
                      {"Pokryto: "}
                      {data.monthly_fund.covered}h (práce{" "}
                      {data.monthly_fund.worked}h
                      {data.monthly_fund.vacation_hours > 0 &&
                        ` + dovolená ${data.monthly_fund.vacation_hours}h`}
                      {data.monthly_fund.sick_hours > 0 &&
                        ` + nemoc ${data.monthly_fund.sick_hours}h`}
                      {data.monthly_fund.unpaid_hours > 0 &&
                        ` + neplacené ${data.monthly_fund.unpaid_hours}h`}
                      )
                    </Box>
                  )}
                </Box>
              }
            />
          )}

          {/* Sick Leave Card */}
          <StatCard
            icon={SickIcon}
            color="error"
            label={`Nemoc ${new Date().getFullYear()}`}
            value={`${leaveBalance.sick_used}h čerpáno`}
          />

          {/* Quick Links */}
          <Card>
            <Typography
              variant="caption"
              color="text.secondary"
              sx={{
                display: "block",
                textTransform: "uppercase",
                letterSpacing: ".06em",
                fontWeight: 700,
                mb: 1,
              }}
            >
              Rychlé odkazy
            </Typography>
            <Box sx={{ display: "flex", flexDirection: "column", gap: 0.25 }}>
              <QuickLink
                to="/attendance/requests"
                icon={RequestsIcon}
                label="Moje žádosti"
              />
              <QuickLink
                to="/attendance/history"
                icon={HistoryIcon}
                label="Historie docházky"
              />
              {hasPermission("attendance.manage") && (
                <QuickLink
                  to="/attendance/admin"
                  icon={ManageIcon}
                  label="Správa docházky"
                />
              )}
              {hasPermission("attendance.balances") && (
                <QuickLink
                  to="/attendance/balances"
                  icon={BalancesIcon}
                  label="Správa bilancí"
                />
              )}
            </Box>
          </Card>
        </Box>
      </Box>

      {/* Leave Modal */}
      <Modal
        isOpen={isLeaveModalOpen}
        onClose={() => setIsLeaveModalOpen(false)}
        title="Žádost o nepřítomnost"
        onSubmit={() => {
          // Preserve original guard: do not submit when there are 0 business days.
          if (businessDays === 0) return;
          handleRequestSubmit();
        }}
        submitText="Odeslat žádost"
        submitDisabled={businessDays === 0}
        loading={requestSubmitting}
      >
        <Field label="Typ nepřítomnosti">
          <Select
            value={leaveForm.leave_type}
            onChange={(val) => setLeaveForm({ ...leaveForm, leave_type: val })}
            options={[
              { value: "vacation", label: "Dovolená" },
              { value: "sick", label: "Nemoc" },
              { value: "unpaid", label: "Neplacené volno" },
            ]}
          />
        </Field>

        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: "minmax(0, 1fr) minmax(0, 1fr)",
            gap: 2,
          }}
        >
          <Field label="Od">
            <DateField
              value={leaveForm.date_from}
              onChange={(val) => {
                setLeaveForm((prev) => ({
                  ...prev,
                  date_from: val,
                  date_to: prev.date_to < val ? val : prev.date_to,
                }));
              }}
            />
          </Field>
          <Field label="Do">
            <DateField
              value={leaveForm.date_to}
              minDate={
                leaveForm.date_from && isValid(parseISO(leaveForm.date_from))
                  ? parseISO(leaveForm.date_from)
                  : undefined
              }
              onChange={(val) => setLeaveForm({ ...leaveForm, date_to: val })}
            />
          </Field>
        </Box>

        {leaveForm.date_from && leaveForm.date_to && (
          <Box
            sx={{
              display: "flex",
              gap: 3,
              alignItems: "center",
              px: 2,
              py: 1.5,
              mb: 2,
              bgcolor: "action.hover",
              borderRadius: 2,
              fontSize: "0.875rem",
            }}
          >
            <Box component="span">
              <strong>{businessDays}</strong>{" "}
              {czechPlural(
                businessDays,
                "pracovní den",
                "pracovní dny",
                "pracovních dnů",
              )}
            </Box>
            <Box component="span" sx={{ color: "text.secondary" }}>
              {businessDays * 8} hodin
            </Box>
          </Box>
        )}

        <Field label="Poznámka">
          <TextField
            multiline
            minRows={2}
            value={leaveForm.notes}
            onChange={(e) =>
              setLeaveForm({ ...leaveForm, notes: e.target.value })
            }
            placeholder="Volitelná poznámka..."
          />
        </Field>
      </Modal>

      <ConfirmDialog
        isOpen={gpsConfirm.isOpen}
        onClose={() => {
          setGpsConfirm({ isOpen: false, action: null });
          setSubmitting(false);
        }}
        onConfirm={() => {
          setGpsConfirm({ isOpen: false, action: null });
          submitPunch(gpsConfirm.action!, {});
        }}
        title="GPS nedostupná"
        message="Nepodařilo se získat polohu. Chcete pokračovat bez GPS?"
        confirmText="Pokračovat"
        cancelText="Zrušit"
        confirmVariant="primary"
      />
    </PageEnter>
  );
}
