import { useState, useMemo, useRef } from "react";
import { useQuery } from "@tanstack/react-query";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import { companySettingsOptions } from "../lib/queries/settings";
import { iconBadgeSx } from "../theme";
import {
  attendanceHistoryOptions,
  type AttendanceRecord,
} from "../lib/queries/attendance";
import {
  formatDate,
  formatDatetime,
  formatTime,
  calculateWorkMinutes,
  formatMinutes,
  getLeaveTypeName,
  getLeaveTypeBadgeClass,
  calculateWorkMinutesPrint,
  formatTimeOrDatetimePrint,
  calculateFreeHolidayHours,
  holidaysInMonth,
  normalizeDateStr,
  formatHoursDecimal,
} from "../utils/attendanceHelpers";
import {
  Button,
  Card,
  DataTable,
  FilterBar,
  MonthField,
  ProgressBar,
  StatusChip,
  PageHeader,
  PageEnter,
  EmptyState,
  LoadingState,
  type DataColumn,
} from "../ui";

const MONTH_NAMES = [
  "Leden",
  "Únor",
  "Březen",
  "Duben",
  "Květen",
  "Červen",
  "Červenec",
  "Srpen",
  "Září",
  "Říjen",
  "Listopad",
  "Prosinec",
];

const PrintIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <polyline points="6 9 6 2 18 2 18 9" />
    <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" />
    <rect x="6" y="14" width="12" height="8" />
  </svg>
);

const formatBreakRange = (record: AttendanceRecord): string => {
  if (record.break_start && record.break_end) {
    return `${formatTime(record.break_start)} - ${formatTime(record.break_end)}`;
  }
  if (record.break_start) {
    return `${formatTime(record.break_start)} - ?`;
  }
  return "—";
};

function getEasterSunday(year: number): string {
  const a = year % 19;
  const b = Math.floor(year / 100);
  const c = year % 100;
  const d = Math.floor(b / 4);
  const e = b % 4;
  const f = Math.floor((b + 8) / 25);
  const g = Math.floor((b - f + 1) / 3);
  const h = (19 * a + b - d - g + 15) % 30;
  const i = Math.floor(c / 4);
  const k = c % 4;
  const l = (32 + 2 * e + 2 * i - h - k) % 7;
  const m = Math.floor((a + 11 * h + 22 * l) / 451);
  const month = Math.floor((h + l - 7 * m + 114) / 31);
  const day = ((h + l - 7 * m + 114) % 31) + 1;
  return `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
}

function getCzechHolidays(year: number): string[] {
  const y = String(year);
  const holidays = [
    `${y}-01-01`,
    `${y}-05-01`,
    `${y}-05-08`,
    `${y}-07-05`,
    `${y}-07-06`,
    `${y}-09-28`,
    `${y}-10-28`,
    `${y}-11-17`,
    `${y}-12-24`,
    `${y}-12-25`,
    `${y}-12-26`,
  ];
  const easterSunday = getEasterSunday(year);
  const easterDate = new Date(easterSunday);
  const goodFriday = new Date(easterDate);
  goodFriday.setDate(goodFriday.getDate() - 2);
  const easterMonday = new Date(easterDate);
  easterMonday.setDate(easterMonday.getDate() + 1);
  const pad = (n: number) => String(n).padStart(2, "0");
  holidays.push(
    `${goodFriday.getFullYear()}-${pad(goodFriday.getMonth() + 1)}-${pad(goodFriday.getDate())}`,
  );
  holidays.push(
    `${easterMonday.getFullYear()}-${pad(easterMonday.getMonth() + 1)}-${pad(easterMonday.getDate())}`,
  );
  holidays.sort();
  return holidays;
}

function getBusinessDaysInMonth(year: number, month: number): number {
  const holidays = getCzechHolidays(year);
  let count = 0;
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  for (let day = 1; day <= daysInMonth; day++) {
    const date = new Date(year, month, day);
    const dow = date.getDay();
    if (dow !== 0 && dow !== 6) {
      const dateStr = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
      if (!holidays.includes(dateStr)) {
        count++;
      }
    }
  }
  return count;
}

const renderProjectCell = (record: AttendanceRecord) => {
  if (record.project_logs && record.project_logs.length > 0) {
    return (
      <Box sx={{ display: "flex", flexDirection: "column", gap: 0.25 }}>
        {record.project_logs.map((log, i) => {
          let h: number,
            m: number,
            isActive = false;
          if (log.hours !== null && log.hours !== undefined) {
            h = parseInt(String(log.hours)) || 0;
            m = parseInt(String(log.minutes)) || 0;
          } else {
            isActive = !log.ended_at;
            const end = log.ended_at ? new Date(log.ended_at) : new Date();
            const mins = Math.max(
              0,
              Math.floor(
                (end.getTime() - new Date(log.started_at!).getTime()) / 60000,
              ),
            );
            h = Math.floor(mins / 60);
            m = mins % 60;
          }
          return (
            <StatusChip
              key={log.id || i}
              color={isActive ? "info" : "default"}
              label={`${log.project_name || `#${log.project_id}`} (${h}:${String(m).padStart(2, "0")}h${isActive ? " ▸" : ""})`}
              sx={{ fontSize: "0.7rem" }}
            />
          );
        })}
      </Box>
    );
  }
  if (record.project_name) {
    return (
      <StatusChip
        color="default"
        label={record.project_name}
        sx={{
          fontSize: "0.75rem",
          height: "auto",
          "& .MuiChip-label": { whiteSpace: "normal", py: 0.25 },
        }}
      />
    );
  }
  return "—";
};

export default function AttendanceHistory() {
  const { user, hasPermission } = useAuth();
  const { data: companySettings } = useQuery(companySettingsOptions());
  const companyName = companySettings?.company_name || "";
  const printRef = useRef<HTMLDivElement>(null);
  const [month, setMonth] = useState(() => {
    const now = new Date();
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
  });
  const { data, isPending } = useQuery(
    attendanceHistoryOptions({ month, userId: user?.id }),
  );
  const records = useMemo(() => data ?? [], [data]);

  const computed = useMemo(() => {
    const [yearStr, monthStr] = month.split("-");
    const monthIndex = parseInt(monthStr, 10) - 1;
    const monthName = `${MONTH_NAMES[monthIndex]} ${yearStr}`;

    let totalMinutes = 0;
    let vacationHours = 0;
    let sickHours = 0;
    let unpaidHours = 0;

    for (const record of records) {
      const leaveType = record.leave_type || "work";
      if (leaveType === "work") {
        totalMinutes += calculateWorkMinutes(record);
      } else {
        const hours =
          record.leave_hours != null ? Number(record.leave_hours) : 8;
        if (leaveType === "vacation") vacationHours += hours;
        else if (leaveType === "sick") sickHours += hours;
        else if (leaveType === "unpaid") unpaidHours += hours;
        // "holiday" is no longer a user-selectable leave_type — it is
        // auto-computed from Czech public holidays by the print/KPI code.
        // Old records may still exist; skip so they don't double-count.
      }
    }

    const yr = parseInt(yearStr, 10);
    const mo = parseInt(monthStr, 10) - 1;
    const businessDays = getBusinessDaysInMonth(yr, mo);
    // Fund counts Mon-Fri + holidays (holidays are paid via the fond).
    const holidayDates = holidaysInMonth(yr, mo + 1);
    const holidayCount = holidayDates.length;
    const fund = (businessDays + holidayCount) * 8;
    const worked = Math.round((totalMinutes / 60) * 100) / 100;
    // Covered = worked + vacation + sick (NOT unpaid — unpaid is voluntary).
    const leaveHours = vacationHours + sickHours;
    const covered = Math.round((worked + leaveHours) * 100) / 100;

    // fondUsed = real_worked + vacation + worked_holiday + free_holiday.
    // (the all-in number: everything the user got paid for this month).
    const realWorked = totalMinutes / 60;
    const freeHolidayHours = calculateFreeHolidayHours(
      records as unknown as Parameters<typeof calculateFreeHolidayHours>[0],
      holidayDates,
    );
    const workedHolidayHours = records
      .filter(
        (r) =>
          (r.leave_type || "work") === "work" &&
          holidayDates.includes(normalizeDateStr(r.shift_date)),
      )
      .reduce((sum, r) => sum + calculateWorkMinutesPrint(r) / 60, 0);
    const fondUsed =
      realWorked + vacationHours + workedHolidayHours + freeHolidayHours;
    const delta = fondUsed - fund;
    const missing = Math.max(0, Math.round(-delta * 100) / 100);
    const overtime = Math.max(0, Math.round(delta * 100) / 100);
    const remaining = missing;

    const monthlyFund = {
      fund,
      business_days: businessDays,
      holiday_count: holidayCount,
      worked: Math.round(fondUsed * 100) / 100,
      covered,
      remaining,
      overtime,
    };

    return {
      monthName,
      totalMinutes,
      vacationHours,
      sickHours,
      unpaidHours,
      monthlyFund,
      fondUsed,
      freeHolidayHours,
      workedHolidayHours,
      delta,
    };
  }, [records, month]);

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

  const handlePrint = () => {
    if (!printRef.current) return;
    const content = printRef.current.innerHTML;
    const printWindow = window.open("", "_blank");
    if (!printWindow) return;
    printWindow.document.write(`
      <!DOCTYPE html>
      <html lang="cs">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Docházka - ${computed.monthName}</title>
        <style>
          * { margin: 0; padding: 0; box-sizing: border-box; }
          body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            font-size: 11px;
            line-height: 1.4;
            color: #000;
            background: #fff;
            padding: 15mm;
          }
          .print-wrapper-table { width: 100%; border-collapse: collapse; border: none; }
          .print-wrapper-table > thead > tr > td,
          .print-wrapper-table > tbody > tr > td { padding: 0; border: none; background: none; }
          .print-header {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 2px solid #333;
          }
          .print-header-left { display: flex; align-items: center; gap: 12px; }
          .print-logo { height: 40px; width: auto; }
          .print-header-text { text-align: left; }
          .print-header-right { text-align: right; }
          .print-header h1 { font-size: 18px; font-weight: 700; margin-bottom: 3px; }
          .print-header .company { font-size: 11px; color: #666; }
          .print-header .period { font-size: 13px; font-weight: 600; color: #333; margin-bottom: 2px; }
          .print-header .filters { font-size: 10px; color: #666; }
          .print-header .generated { font-size: 9px; color: #888; margin-top: 5px; }
          .user-section { margin-bottom: 25px; page-break-inside: avoid; }
          .user-header {
            background: #f5f5f5;
            border: 1px solid #ddd;
            padding: 10px 15px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
          }
          .user-header h3 { font-size: 13px; font-weight: 600; }
          .user-header .total { font-size: 12px; font-weight: 600; }
          .leave-summary {
            margin-top: 10px;
            padding: 8px 15px;
            background: #f9f9f9;
            border: 1px solid #ddd;
            font-size: 10px;
          }
          .user-section table { width: 100%; border-collapse: collapse; margin-bottom: 15px; }
          .user-section th, .user-section td { border: 1px solid #333; padding: 6px 8px; text-align: left; }
          .user-section th { background: #333; color: #fff; font-weight: 600; font-size: 10px; text-transform: uppercase; }
          .user-section td { font-size: 10px; }
          .user-section tr:nth-child(even) { background: #f9f9f9; }
          .text-center { text-align: center; }
          .text-right { text-align: right; }
          .user-section tfoot td { background: #eee; font-weight: 600; }
          .leave-badge {
            display: inline-block;
            padding: 2px 6px;
            border-radius: 3px;
            font-size: 9px;
            font-weight: 500;
          }
          .badge-vacation { background: #dbeafe; color: #1d4ed8; }
          .badge-sick { background: #fee2e2; color: #dc2626; }
          .badge-unpaid { background: #f3f4f6; color: #6b7280; }
          .badge-overtime { background: #fef3c7; color: #d97706; }
          @media print {
            body { padding: 0; margin: 0; }
            @page { size: A4 portrait; margin: 10mm; }
            .user-section { page-break-inside: avoid; }
          }
        </style>
      </head>
      <body>
        ${content}
      </body>
      </html>
    `);
    printWindow.document.close();
    printWindow.onload = () => {
      printWindow.print();
    };
  };

  const fund = computed.monthlyFund;
  const progressValue =
    fund.fund > 0 ? Math.min(100, (fund.worked / fund.fund) * 100) : 0;
  const progressColor =
    computed.delta > 0
      ? "warning"
      : computed.delta >= 0
        ? "success"
        : "primary";
  const deltaColor =
    computed.delta > 0
      ? "warning.main"
      : computed.delta < 0
        ? "error.main"
        : "success.main";

  const columns: DataColumn<AttendanceRecord>[] = [
    {
      key: "date",
      header: "Datum",
      width: "10%",
      mono: true,
      render: (record) => formatDate(record.shift_date),
    },
    {
      key: "type",
      header: "Typ",
      width: "11%",
      render: (record) => {
        const leaveType = record.leave_type || "work";
        return (
          <StatusChip
            color={leaveTypeChipColor(leaveType)}
            label={getLeaveTypeName(leaveType)}
          />
        );
      },
    },
    {
      key: "arrival",
      header: "Příchod",
      width: "10%",
      mono: true,
      render: (record) => {
        const isLeave = (record.leave_type || "work") !== "work";
        return isLeave ? "—" : formatDatetime(record.arrival_time);
      },
    },
    {
      key: "break",
      header: "Pauza",
      width: "11%",
      mono: true,
      render: (record) => {
        const isLeave = (record.leave_type || "work") !== "work";
        return isLeave ? "—" : formatBreakRange(record);
      },
    },
    {
      key: "departure",
      header: "Odchod",
      width: "10%",
      mono: true,
      render: (record) => {
        const isLeave = (record.leave_type || "work") !== "work";
        return isLeave ? "—" : formatDatetime(record.departure_time);
      },
    },
    {
      key: "hours",
      header: "Hodiny",
      width: "9%",
      mono: true,
      render: (record) => {
        const leaveType = record.leave_type || "work";
        const isLeave = leaveType !== "work";
        const workMinutes = isLeave
          ? (Number(record.leave_hours) || 8) * 60
          : calculateWorkMinutes(record);
        return workMinutes > 0 ? formatMinutes(workMinutes, true) : "—";
      },
    },
    {
      key: "projects",
      header: "Projekty",
      width: "18%",
      render: (record) => renderProjectCell(record),
    },
    {
      key: "notes",
      header: "Poznámka",
      width: "11%",
      render: (record) => record.notes || "",
    },
  ];

  return (
    <PageEnter>
      <PageHeader
        title="Historie docházky"
        subtitle={computed.monthName}
        actions={
          records.length > 0 ? (
            <Button
              variant="outlined"
              color="inherit"
              startIcon={PrintIcon}
              onClick={handlePrint}
              title="Tisk docházky"
            >
              Tisk
            </Button>
          ) : undefined
        }
      />

      {/* Filters */}
      <FilterBar>
        <Box sx={{ flex: "0 0 180px" }}>
          <MonthField value={month} onChange={(val) => setMonth(val)} />
        </Box>
      </FilterBar>

      {/* Monthly Fund Card */}
      <Card sx={{ mt: 3 }}>
        {isPending ? (
          <LoadingState />
        ) : (
          <Box
            sx={{
              display: "flex",
              alignItems: "center",
              gap: 2,
              flexWrap: "wrap",
            }}
          >
            <Box
              sx={[
                {
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  width: 44,
                  height: 44,
                  borderRadius: 2,
                  flexShrink: 0,
                },
                iconBadgeSx("info"),
              ]}
            >
              <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>
            </Box>
            <Box sx={{ flex: 1, minWidth: "200px" }}>
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "baseline",
                  mb: 0.75,
                }}
              >
                <Typography sx={{ fontWeight: 600, fontSize: "1rem" }}>
                  Fond: {fund.worked}h / {fund.fund}h
                </Typography>
                <Typography
                  variant="body2"
                  color="text.secondary"
                  sx={{ fontSize: "0.8125rem" }}
                >
                  {fund.business_days} prac. dnů
                  {fund.holiday_count > 0 && ` + ${fund.holiday_count} svátky`}
                </Typography>
              </Box>
              <ProgressBar value={progressValue} color={progressColor} />
              <Box
                sx={{
                  display: "flex",
                  flexWrap: "wrap",
                  gap: 0.5,
                  mt: 1,
                  minHeight: "1.5rem",
                  alignItems: "center",
                  justifyContent: "space-between",
                }}
              >
                <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
                  {computed.totalMinutes > 0 && (
                    <StatusChip
                      color="info"
                      label={`Práce: ${formatHoursDecimal(computed.totalMinutes)}h`}
                      title="Odpracováno (reálně)"
                    />
                  )}
                  {computed.vacationHours > 0 && (
                    <StatusChip
                      color="success"
                      label={`Dov: ${computed.vacationHours}h`}
                    />
                  )}
                  {computed.sickHours > 0 && (
                    <StatusChip
                      color="error"
                      label={`Nem: ${computed.sickHours}h`}
                    />
                  )}
                  {computed.freeHolidayHours > 0 && (
                    <StatusChip
                      color="warning"
                      label={`Sv: ${Math.round(computed.freeHolidayHours)}h`}
                    />
                  )}
                  {computed.unpaidHours > 0 && (
                    <StatusChip
                      color="default"
                      label={`Nep: ${computed.unpaidHours}h`}
                    />
                  )}
                </Box>
                <Typography
                  variant="caption"
                  sx={{ fontWeight: 600, color: deltaColor }}
                >
                  {computed.delta > 0
                    ? `Přesčas: +${formatHoursDecimal(computed.delta * 60)}h`
                    : computed.delta < 0
                      ? `Zbývá: ${formatHoursDecimal(-computed.delta * 60)}h`
                      : "Fond splněn"}
                </Typography>
              </Box>
            </Box>
          </Box>
        )}
      </Card>

      {/* Records Table */}
      <Card sx={{ mt: 3 }}>
        {isPending ? (
          <LoadingState />
        ) : (
          <DataTable<AttendanceRecord>
            columns={columns}
            rows={records}
            rowKey={(record) => record.id}
            empty={<EmptyState title="Za tento měsíc nejsou žádné záznamy." />}
          />
        )}
      </Card>

      {/* Hidden Print Content */}
      {records.length > 0 && (
        <div ref={printRef} style={{ display: "none" }}>
          <table className="print-wrapper-table">
            <thead>
              <tr>
                <td>
                  <div className="print-header">
                    <div className="print-header-left">
                      <img
                        src="/api/admin/company-settings/logo?variant=light"
                        alt=""
                        className="print-logo"
                      />
                      <div className="print-header-text">
                        <h1>EVIDENCE DOCHÁZKY</h1>
                        <div className="company">{companyName}</div>
                      </div>
                    </div>
                    <div className="print-header-right">
                      <div className="period">{computed.monthName}</div>
                      <div className="filters">
                        Zaměstnanec: {user?.fullName || ""}
                      </div>
                      <div className="generated">
                        Vygenerováno: {new Date().toLocaleString("cs-CZ")}
                      </div>
                    </div>
                  </div>
                </td>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>
                  <div className="user-section">
                    <div className="user-header">
                      <h3>{user?.fullName || ""}</h3>
                      <span className="total">
                        Odpracováno:{" "}
                        {formatMinutes(computed.totalMinutes, true)}
                      </span>
                    </div>

                    {(computed.vacationHours > 0 || computed.sickHours > 0) && (
                      <div className="leave-summary">
                        {computed.vacationHours > 0 && (
                          <>
                            <span className="leave-badge badge-vacation">
                              Dovolená: {computed.vacationHours}h
                            </span>{" "}
                          </>
                        )}
                        {computed.sickHours > 0 && (
                          <>
                            <span className="leave-badge badge-sick">
                              Nemoc: {computed.sickHours}h
                            </span>{" "}
                          </>
                        )}
                      </div>
                    )}

                    <table>
                      <thead>
                        <tr>
                          <th style={{ width: "70px" }}>Datum</th>
                          <th style={{ width: "70px" }}>Typ</th>
                          <th className="text-center" style={{ width: "70px" }}>
                            Příchod
                          </th>
                          <th className="text-center" style={{ width: "90px" }}>
                            Pauza
                          </th>
                          <th className="text-center" style={{ width: "70px" }}>
                            Odchod
                          </th>
                          <th className="text-center" style={{ width: "80px" }}>
                            Hodiny
                          </th>
                          <th>Projekty</th>
                          <th>Poznámka</th>
                        </tr>
                      </thead>
                      <tbody>
                        {[...records]
                          .sort((a, b) =>
                            a.shift_date.localeCompare(b.shift_date),
                          )
                          .map((record) => {
                            const leaveType = record.leave_type || "work";
                            const isLeave = leaveType !== "work";
                            const workMinutes =
                              calculateWorkMinutesPrint(record);
                            const hours = Math.floor(workMinutes / 60);
                            const mins = workMinutes % 60;

                            return (
                              <tr key={record.id}>
                                <td>{formatDate(record.shift_date)}</td>
                                <td>
                                  <span
                                    className={`leave-badge ${getLeaveTypeBadgeClass(leaveType)}`}
                                  >
                                    {getLeaveTypeName(leaveType)}
                                  </span>
                                </td>
                                <td className="text-center">
                                  {isLeave
                                    ? "—"
                                    : formatTimeOrDatetimePrint(
                                        record.arrival_time,
                                        record.shift_date,
                                      )}
                                </td>
                                <td className="text-center">
                                  {isLeave ||
                                  !record.break_start ||
                                  !record.break_end
                                    ? "—"
                                    : `${formatTimeOrDatetimePrint(record.break_start, record.shift_date)} - ${formatTimeOrDatetimePrint(record.break_end, record.shift_date)}`}
                                </td>
                                <td className="text-center">
                                  {isLeave
                                    ? "—"
                                    : formatTimeOrDatetimePrint(
                                        record.departure_time,
                                        record.shift_date,
                                      )}
                                </td>
                                <td className="text-center">
                                  {workMinutes > 0
                                    ? `${hours}:${String(mins).padStart(2, "0")}`
                                    : "—"}
                                </td>
                                <td style={{ fontSize: "8px" }}>
                                  {record.project_logs &&
                                  record.project_logs.length > 0
                                    ? record.project_logs.map((log, i) => {
                                        let h: number, m: number;
                                        if (
                                          log.hours !== null &&
                                          log.hours !== undefined
                                        ) {
                                          h = parseInt(String(log.hours)) || 0;
                                          m =
                                            parseInt(String(log.minutes)) || 0;
                                        } else if (
                                          log.started_at &&
                                          log.ended_at
                                        ) {
                                          const mins2 = Math.max(
                                            0,
                                            Math.floor(
                                              (new Date(
                                                log.ended_at,
                                              ).getTime() -
                                                new Date(
                                                  log.started_at,
                                                ).getTime()) /
                                                60000,
                                            ),
                                          );
                                          h = Math.floor(mins2 / 60);
                                          m = mins2 % 60;
                                        } else {
                                          h = 0;
                                          m = 0;
                                        }
                                        return (
                                          <div key={log.id || i}>
                                            {log.project_name ||
                                              `#${log.project_id}`}{" "}
                                            ({h}:{String(m).padStart(2, "0")}h)
                                          </div>
                                        );
                                      })
                                    : record.project_name || "—"}
                                </td>
                                <td>{record.notes || ""}</td>
                              </tr>
                            );
                          })}
                      </tbody>
                      <tfoot>
                        <tr>
                          <td colSpan={6} className="text-right">
                            Odpracováno:
                          </td>
                          <td className="text-center">
                            {formatMinutes(computed.totalMinutes, true)}
                          </td>
                          <td colSpan={2}></td>
                        </tr>
                      </tfoot>
                    </table>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      )}
    </PageEnter>
  );
}

/** Map an attendance leave_type to a StatusChip semantic color (mirrors the
 *  legacy getLeaveTypeBadgeClass colors): work→info, vacation→info(blue),
 *  sick→error(red), unpaid→default(gray). */
function leaveTypeChipColor(
  type: string,
): "default" | "success" | "error" | "warning" | "info" {
  switch (type) {
    case "vacation":
      return "info";
    case "sick":
      return "error";
    case "unpaid":
      return "default";
    default:
      return "info";
  }
}
