import { useRef } from "react";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import {
  Modal,
  Button,
  Select,
  TextField,
  DateField,
  TimeField,
  Field,
  Alert,
} from "../ui";
import {
  calcFormWorkMinutes,
  calcProjectMinutesTotal,
  formatDate,
} from "../utils/attendanceHelpers";

// ---------- Shared types ----------

export interface ShiftFormData {
  user_id: string;
  shift_date: string;
  leave_type: string;
  leave_hours: number;
  arrival_date: string;
  arrival_time: string;
  break_start_date: string;
  break_start_time: string;
  break_end_date: string;
  break_end_time: string;
  departure_date: string;
  departure_time: string;
  notes: string;
}

export interface ProjectLog {
  _key?: string;
  id?: number;
  project_id: string | number;
  hours: string | number;
  minutes: string | number;
}

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

export interface User {
  id: number | string;
  name: string;
}

export interface EditingRecord {
  user_name: string;
  shift_date: string;
}

// ---------- Sub-component props ----------

interface ProjectTimeStatusProps {
  form: ShiftFormData;
  projectLogs: ProjectLog[];
}

interface ProjectLogRowProps {
  log: ProjectLog;
  index: number;
  projectList: Project[];
  onUpdate: (index: number, field: string, value: string) => void;
  onRemove: (index: number) => void;
}

export interface ShiftFormModalProps {
  mode: "create" | "edit";
  isOpen: boolean;
  onClose: () => void;
  onSubmit: () => void;
  form: ShiftFormData;
  setForm: (form: ShiftFormData) => void;
  projectLogs: ProjectLog[];
  setProjectLogs: (logs: ProjectLog[]) => void;
  projectList: Project[];
  users: User[];
  onShiftDateChange: (value: string) => void;
  editingRecord: EditingRecord | null;
}

const RemoveIcon = (
  <svg
    width="16"
    height="16"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <path d="M18 6L6 18M6 6l12 12" />
  </svg>
);

// ---------- ProjectTimeStatus ----------

function ProjectTimeStatus({ form, projectLogs }: ProjectTimeStatusProps) {
  const totalWork = calcFormWorkMinutes(form);
  const totalProject = calcProjectMinutesTotal(
    projectLogs.map((l) => ({
      ...l,
      project_id:
        l.project_id !== "" && l.project_id != null
          ? Number(l.project_id)
          : undefined,
    })),
  );
  const remaining = totalWork - totalProject;
  const hasLogs = projectLogs.some((l) => l.project_id);

  if (!hasLogs || totalWork <= 0) return null;

  const isMatch = remaining === 0;
  return (
    <Box sx={{ mb: 1 }}>
      <Alert severity={isMatch ? "success" : "error"}>
        Odpracováno: {Math.floor(totalWork / 60)}h {totalWork % 60}m |
        Přiřazeno: {Math.floor(totalProject / 60)}h {totalProject % 60}m |
        Zbývá: {Math.floor(Math.abs(remaining) / 60)}h{" "}
        {Math.abs(remaining) % 60}m {remaining < 0 ? "(překročeno)" : ""}
      </Alert>
    </Box>
  );
}

// ---------- ProjectLogRow ----------

function ProjectLogRow({
  log,
  index,
  projectList,
  onUpdate,
  onRemove,
}: ProjectLogRowProps) {
  return (
    <Box
      sx={{
        display: "flex",
        alignItems: "center",
        gap: 1,
        mb: 1,
      }}
    >
      <Box sx={{ flex: 3, minWidth: 0 }}>
        <Select
          value={String(log.project_id)}
          onChange={(val) => onUpdate(index, "project_id", val)}
          options={[
            { value: "", label: "— Projekt —" },
            ...projectList.map((p) => ({
              value: String(p.id),
              label: `${p.project_number} – ${p.name}`,
            })),
          ]}
        />
      </Box>
      <Box sx={{ width: 70, flexShrink: 0 }}>
        <TextField
          type="number"
          value={log.hours}
          onChange={(e) => onUpdate(index, "hours", e.target.value)}
          placeholder="h"
          slotProps={{
            htmlInput: { min: 0, max: 24, style: { textAlign: "center" } },
          }}
        />
      </Box>
      <Typography variant="body2" color="text.secondary">
        h
      </Typography>
      <Box sx={{ width: 70, flexShrink: 0 }}>
        <TextField
          type="number"
          value={log.minutes}
          onChange={(e) => onUpdate(index, "minutes", e.target.value)}
          placeholder="m"
          slotProps={{
            htmlInput: { min: 0, max: 59, style: { textAlign: "center" } },
          }}
        />
      </Box>
      <Typography variant="body2" color="text.secondary">
        m
      </Typography>
      <IconButton
        size="small"
        onClick={() => onRemove(index)}
        aria-label="Odebrat"
        title="Odebrat"
        sx={{ flexShrink: 0 }}
      >
        {RemoveIcon}
      </IconButton>
    </Box>
  );
}

// ---------- ShiftFormModal ----------

export default function ShiftFormModal({
  mode,
  isOpen,
  onClose,
  onSubmit,
  form,
  setForm,
  projectLogs,
  setProjectLogs,
  projectList,
  users,
  onShiftDateChange,
  editingRecord,
}: ShiftFormModalProps) {
  const isCreate = mode === "create";
  const isWorkType = form.leave_type === "work";

  // Per-instance counter for stable React keys on newly-added project rows.
  // (Was a module-level mutable `let`, which is shared across every modal
  // instance and fragile under StrictMode / concurrent instances.)
  const logKeyCounter = useRef(0);

  const updateField = (field: keyof ShiftFormData, value: string | number) => {
    setForm({ ...form, [field]: value });
  };

  const updateProjectLog = (index: number, field: string, value: string) => {
    const updated = [...projectLogs];
    updated[index] = { ...updated[index], [field]: value };
    setProjectLogs(updated);
  };

  const removeProjectLog = (index: number) => {
    setProjectLogs(projectLogs.filter((_, j) => j !== index));
  };

  const addProjectLog = () => {
    setProjectLogs([
      ...projectLogs,
      {
        _key: `log-${++logKeyCounter.current}`,
        project_id: "",
        hours: "",
        minutes: "",
      },
    ]);
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={isCreate ? "Přidat záznam docházky" : "Upravit docházku"}
      subtitle={
        !isCreate && editingRecord
          ? `${editingRecord.user_name} — ${formatDate(editingRecord.shift_date)}`
          : undefined
      }
      maxWidth="lg"
      onSubmit={onSubmit}
      submitText="Uložit"
      cancelText="Zrušit"
    >
      {isCreate ? (
        <Box
          sx={{
            display: "grid",
            gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
            gap: 2,
          }}
        >
          <Field label="Zaměstnanec" required>
            <Select
              value={form.user_id}
              onChange={(val) => updateField("user_id", val)}
              options={[
                { value: "", label: "Vyberte zaměstnance" },
                ...users.map((user) => ({
                  value: String(user.id),
                  label: user.name,
                })),
              ]}
            />
          </Field>
          <Field label="Datum směny" required>
            <DateField
              value={form.shift_date}
              onChange={(val) => onShiftDateChange(val)}
            />
          </Field>
        </Box>
      ) : (
        <Field label="Datum směny">
          <DateField
            value={form.shift_date}
            onChange={(val) => updateField("shift_date", val)}
          />
        </Field>
      )}

      <Field label="Typ záznamu">
        <Select
          value={form.leave_type}
          onChange={(val) => updateField("leave_type", val)}
          options={[
            { value: "work", label: "Práce" },
            { value: "vacation", label: "Dovolená" },
            { value: "sick", label: "Nemoc" },
            { value: "unpaid", label: "Neplacené volno" },
          ]}
        />
      </Field>

      {!isWorkType && (
        <Field
          label="Počet hodin"
          hint={isCreate ? "8 hodin = celý den" : undefined}
        >
          <TextField
            type="number"
            inputMode="decimal"
            value={form.leave_hours}
            onChange={(e) =>
              // Empty input -> parseFloat returns NaN, which serializes to an
              // invalid value; fall back to 0 like the Number(...)||0 pattern.
              updateField("leave_hours", Number(e.target.value) || 0)
            }
            slotProps={{ htmlInput: { min: 0.5, max: 24, step: 0.5 } }}
          />
        </Field>
      )}

      {isWorkType && (
        <>
          {/* Arrival */}
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
              gap: 2,
            }}
          >
            <Field label="Příchod - datum">
              <DateField
                value={form.arrival_date}
                onChange={(val) => updateField("arrival_date", val)}
              />
            </Field>
            <Field label="Příchod - čas">
              <TimeField
                value={form.arrival_time}
                onChange={(val) => updateField("arrival_time", val)}
              />
            </Field>
          </Box>

          {/* Break start */}
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
              gap: 2,
            }}
          >
            <Field label="Začátek pauzy - datum">
              <DateField
                value={form.break_start_date}
                onChange={(val) => updateField("break_start_date", val)}
              />
            </Field>
            <Field label="Začátek pauzy - čas">
              <TimeField
                value={form.break_start_time}
                onChange={(val) => updateField("break_start_time", val)}
              />
            </Field>
          </Box>

          {/* Break end */}
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
              gap: 2,
            }}
          >
            <Field label="Konec pauzy - datum">
              <DateField
                value={form.break_end_date}
                onChange={(val) => updateField("break_end_date", val)}
              />
            </Field>
            <Field label="Konec pauzy - čas">
              <TimeField
                value={form.break_end_time}
                onChange={(val) => updateField("break_end_time", val)}
              />
            </Field>
          </Box>

          {/* Departure */}
          <Box
            sx={{
              display: "grid",
              gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
              gap: 2,
            }}
          >
            <Field label="Odchod - datum">
              <DateField
                value={form.departure_date}
                onChange={(val) => updateField("departure_date", val)}
              />
            </Field>
            <Field label="Odchod - čas">
              <TimeField
                value={form.departure_time}
                onChange={(val) => updateField("departure_time", val)}
              />
            </Field>
          </Box>
        </>
      )}

      {isWorkType && projectList.length > 0 && (
        <Field label="Projekty">
          <ProjectTimeStatus form={form} projectLogs={projectLogs} />
          {projectLogs.map((log, i) => (
            <ProjectLogRow
              // Stable key: client-added rows carry `_key`; server-loaded rows
              // carry a DB `id`. Fall back to the index only when neither is
              // present (shouldn't happen, but avoids a key collision).
              key={log._key ?? (log.id != null ? `id-${log.id}` : i)}
              log={log}
              index={i}
              projectList={projectList}
              onUpdate={updateProjectLog}
              onRemove={removeProjectLog}
            />
          ))}
          <Button
            variant="outlined"
            color="inherit"
            size="small"
            onClick={addProjectLog}
          >
            + Přidat projekt
          </Button>
        </Field>
      )}

      <Field label="Poznámka">
        <TextField
          multiline
          minRows={3}
          value={form.notes}
          onChange={(e) => updateField("notes", e.target.value)}
        />
      </Field>
    </Modal>
  );
}
