import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import BulkAttendanceModal from "../components/BulkAttendanceModal";
import ShiftFormModal from "../components/ShiftFormModal";
import AttendanceShiftTable from "../components/AttendanceShiftTable";
import useModalLock from "../hooks/useModalLock";
import useAttendanceAdmin from "../hooks/useAttendanceAdmin";
import { formatMinutes, formatHoursDecimal } from "../utils/attendanceHelpers";
import {
  Button,
  Card,
  ConfirmDialog,
  FilterBar,
  LoadingState,
  MonthField,
  PageEnter,
  Select,
  StatCard,
  StatusChip,
  ProgressBar,
  type ProgressColor,
  type StatCardColor,
} from "../ui";

interface UserTotalData {
  name: string;
  minutes: number;
  working: boolean;
  vacation_hours: number;
  sick_hours: number;
  unpaid_hours: number;
  fund: number | null;
  worked_hours: number;
  // Raw worked hours incl. sub-day remainders (set by computeUserTotals in
  // useAttendanceAdmin); used for the Fond "used" calculation below.
  worked_hours_raw?: number;
  covered: number;
  missing: number;
  overtime: number;
  // mzda-style summary fields (set by computeUserTotals in useAttendanceAdmin)
  odpracovano?: number;
  vcetne_svatku?: number;
  prescas?: number;
  svatek?: number;
  worked_holiday_hours?: number;
}

/** Fond "used" total mirrors the Fond footer line below:
 *  real_worked + vacation + worked_holiday + free_holiday. */
function getFondUsed(data: UserTotalData): number {
  const realWorked = data.worked_hours_raw ?? data.worked_hours;
  return (
    realWorked +
    (data.vacation_hours ?? 0) +
    (data.worked_holiday_hours ?? 0) +
    (data.svatek ?? 0)
  );
}

/** Maps the Fond delta (used − fund) to a ProgressBar color token, mirroring
 *  the legacy getFundBarBackground conditional: over fund → warning, exactly
 *  at fund → success, under fund → primary (was the accent gradient). */
function getFundBarColor(data: UserTotalData): ProgressColor {
  const delta = getFondUsed(data) - (data.fund ?? 0);
  if (delta > 0) return "warning";
  if (delta >= 0) return "success";
  return "primary";
}

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 AddIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <line x1="12" y1="5" x2="12" y2="19" />
    <line x1="5" y1="12" x2="19" y2="12" />
  </svg>
);

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

  const {
    loading,
    month,
    setMonth,
    filterUserId,
    setFilterUserId,
    data,
    hasData,
    showBulkModal,
    setShowBulkModal,
    bulkSubmitting,
    bulkForm,
    setBulkForm,
    showCreateModal,
    setShowCreateModal,
    createForm,
    setCreateForm,
    showEditModal,
    setShowEditModal,
    editingRecord,
    editForm,
    setEditForm,
    deleteConfirm,
    setDeleteConfirm,
    projectList,
    createProjectLogs,
    setCreateProjectLogs,
    editProjectLogs,
    setEditProjectLogs,
    openCreateModal,
    handleCreateShiftDateChange,
    handleCreateSubmit,
    openBulkModal,
    toggleBulkUser,
    toggleAllBulkUsers,
    handleBulkSubmit,
    openEditModal,
    handleEditSubmit,
    handleDelete,
    handlePrint,
  } = useAttendanceAdmin({ alert });

  useModalLock(showBulkModal);
  useModalLock(showEditModal);
  useModalLock(showCreateModal);

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

  // Show spinner only on initial load (no data yet), not on filter changes
  const isInitialLoad =
    loading &&
    data.records.length === 0 &&
    Object.keys(data.user_totals).length === 0;

  if (isInitialLoad) {
    return <LoadingState />;
  }

  const hasTotals = Object.keys(data.user_totals).length > 0;

  return (
    <PageEnter>
      <Box
        sx={{
          display: "flex",
          alignItems: "flex-start",
          justifyContent: "space-between",
          flexWrap: "wrap",
          gap: 2,
          mb: 3,
        }}
      >
        <Typography variant="h4">Správa docházky</Typography>
        <Box sx={{ display: "flex", gap: 1.5, flexWrap: "wrap" }}>
          {hasData && (
            <Button
              variant="outlined"
              color="inherit"
              startIcon={PrintIcon}
              onClick={handlePrint}
              title="Tisk docházky"
            >
              Tisk
            </Button>
          )}
          <Button variant="outlined" color="inherit" onClick={openBulkModal}>
            Vyplnit měsíc
          </Button>
          <Button startIcon={AddIcon} onClick={openCreateModal}>
            Přidat záznam
          </Button>
        </Box>
      </Box>

      {/* Filters */}
      <FilterBar>
        <Box sx={{ flex: "0 0 180px" }}>
          <MonthField value={month} onChange={(val) => setMonth(val)} />
        </Box>
        <Box sx={{ flex: "0 0 220px" }}>
          <Select
            value={filterUserId}
            onChange={setFilterUserId}
            options={[
              { value: "", label: "Všichni zaměstnanci" },
              ...data.users.map((user) => ({
                value: String(user.id),
                label: user.name,
              })),
            ]}
          />
        </Box>
      </FilterBar>

      {/* User Totals (KPI cards) */}
      {hasTotals && (
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: {
              xs: "1fr",
              sm: "repeat(2, 1fr)",
              lg: "repeat(3, 1fr)",
            },
            gap: 2,
            mb: 3,
          }}
        >
          {Object.entries(data.user_totals).map(([uid, userData]) => {
            const ut = userData as UserTotalData;
            const balance = data.leave_balances[uid];
            const statColor: StatCardColor = ut.working ? "success" : "default";
            return (
              <StatCard
                key={uid}
                label={ut.name}
                value={
                  <Box
                    component="span"
                    sx={{
                      display: "inline-flex",
                      alignItems: "center",
                      gap: 1,
                    }}
                  >
                    {formatMinutes(ut.minutes)}
                    <StatusChip
                      color={ut.working ? "success" : "default"}
                      label={ut.working ? "✓" : "✗"}
                    />
                  </Box>
                }
                color={statColor}
                footer={
                  <Box>
                    {/* Leave-type badges */}
                    <Box
                      sx={{
                        display: "flex",
                        flexWrap: "wrap",
                        gap: 0.5,
                        mb: 1,
                        minHeight: "1.75rem",
                        alignItems: "center",
                      }}
                    >
                      {ut.vacation_hours > 0 && (
                        <StatusChip
                          color="info"
                          label={`Dov: ${ut.vacation_hours}h`}
                        />
                      )}
                      {ut.sick_hours > 0 && (
                        <StatusChip
                          color="error"
                          label={`Nem: ${ut.sick_hours}h`}
                        />
                      )}
                      {ut.svatek !== undefined && ut.svatek > 0 && (
                        <StatusChip
                          color="warning"
                          label={`Sv: ${Math.round(ut.svatek)}h`}
                        />
                      )}
                      {ut.unpaid_hours > 0 && (
                        <StatusChip
                          color="default"
                          label={`Nep: ${ut.unpaid_hours}h`}
                        />
                      )}
                    </Box>

                    {/* Fond usage */}
                    {ut.fund !== null &&
                      (() => {
                        // Fond "used" = real_worked + vacation +
                        // worked_holiday + free_holiday (everything the user
                        // actually got paid for this month).
                        const fondUsed = getFondUsed(ut);
                        const fundVal = ut.fund ?? 0;
                        const delta = fondUsed - fundVal;
                        const pct = Math.min(
                          100,
                          (fondUsed / (ut.fund || 1)) * 100,
                        );
                        return (
                          <Box>
                            <Box
                              sx={{
                                display: "flex",
                                justifyContent: "space-between",
                                alignItems: "center",
                                mb: 0.5,
                              }}
                            >
                              <Typography
                                variant="caption"
                                color="text.secondary"
                              >
                                Fond: {formatHoursDecimal(fondUsed * 60)}h /{" "}
                                {formatHoursDecimal(fundVal * 60)}h
                              </Typography>
                              {delta > 0 && (
                                <Typography
                                  variant="caption"
                                  sx={{
                                    fontWeight: 600,
                                    color: "warning.main",
                                  }}
                                >
                                  +{formatHoursDecimal(delta * 60)}h
                                </Typography>
                              )}
                              {delta < 0 && (
                                <Typography
                                  variant="caption"
                                  sx={{
                                    fontWeight: 600,
                                    color: "error.main",
                                  }}
                                >
                                  -{formatHoursDecimal(Math.abs(delta) * 60)}h
                                </Typography>
                              )}
                            </Box>
                            <ProgressBar
                              value={pct}
                              color={getFundBarColor(ut)}
                              height={4}
                            />
                          </Box>
                        );
                      })()}

                    {/* Remaining vacation */}
                    <Box sx={{ mt: 1.5 }}>
                      {balance ? (
                        <Typography variant="caption" color="text.secondary">
                          Zbývá dovolené:{" "}
                          {balance.vacation_remaining.toFixed(1)}h /{" "}
                          {balance.vacation_total}h
                        </Typography>
                      ) : (
                        <Typography
                          variant="caption"
                          sx={{ visibility: "hidden" }}
                        >
                          —
                        </Typography>
                      )}
                    </Box>
                  </Box>
                }
              />
            );
          })}
        </Box>
      )}

      {/* Records Table */}
      <Card>
        <AttendanceShiftTable
          records={data.records}
          onEdit={openEditModal}
          onDelete={(record) => setDeleteConfirm({ show: true, record })}
        />
      </Card>

      {/* Modals */}
      <BulkAttendanceModal
        isOpen={showBulkModal}
        onClose={() => setShowBulkModal(false)}
        form={bulkForm}
        setForm={setBulkForm}
        users={data.users}
        onSubmit={handleBulkSubmit}
        submitting={bulkSubmitting}
        toggleUser={toggleBulkUser}
        toggleAllUsers={toggleAllBulkUsers}
      />

      <ShiftFormModal
        mode="create"
        isOpen={showCreateModal}
        onClose={() => setShowCreateModal(false)}
        onSubmit={handleCreateSubmit}
        form={createForm}
        setForm={setCreateForm}
        projectLogs={createProjectLogs}
        setProjectLogs={setCreateProjectLogs}
        projectList={projectList}
        users={data.users}
        onShiftDateChange={handleCreateShiftDateChange}
        editingRecord={null}
      />

      <ShiftFormModal
        mode="edit"
        isOpen={showEditModal && !!editingRecord}
        onClose={() => setShowEditModal(false)}
        onSubmit={handleEditSubmit}
        form={editForm}
        setForm={setEditForm}
        projectLogs={editProjectLogs}
        setProjectLogs={setEditProjectLogs}
        projectList={projectList}
        users={data.users}
        onShiftDateChange={handleCreateShiftDateChange}
        editingRecord={
          editingRecord
            ? {
                user_name: editingRecord.user_name ?? "",
                shift_date: editingRecord.shift_date,
              }
            : null
        }
      />

      <ConfirmDialog
        isOpen={deleteConfirm.show}
        onClose={() => setDeleteConfirm({ show: false, record: null })}
        onConfirm={handleDelete}
        title="Smazat záznam"
        message="Opravdu chcete smazat tento záznam docházky?"
        confirmText="Smazat"
        confirmVariant="danger"
      />
    </PageEnter>
  );
}
