import { z } from "zod";
import {
  intIdFromForm,
  isoDateString,
  nullableDateTimeString,
  nullableIntIdFromForm,
  numberFromForm,
  numberInRange,
  timeString,
} from "./common";

export const AttendanceNotesSchema = z.object({
  notes: z.string().nullish(),
});

export const AttendanceUpdateAddressSchema = z.object({
  address: z.string().max(500).nullish(),
  punch_action: z.string().optional().default("arrival"),
});

export const AttendanceSwitchProjectSchema = z.object({
  project_id: nullableIntIdFromForm.nullish(),
});

export const AttendanceBalancesSchema = z.object({
  user_id: intIdFromForm,
  year: numberFromForm.optional(),
  action_type: z.enum(["edit", "reset"]),
  vacation_total: numberFromForm.optional(),
  vacation_used: numberFromForm.optional(),
  sick_used: numberFromForm.optional(),
});

export const AttendanceBulkSchema = z.object({
  month: z.string().regex(/^\d{4}-\d{2}$/, "Měsíc je povinný (formát YYYY-MM)"),
  user_ids: z
    .array(intIdFromForm)
    .min(1, "Vyberte alespoň jednoho zaměstnance"),
  arrival_time: timeString.optional().default("08:00"),
  departure_time: timeString.optional().default("16:30"),
  break_start_time: timeString.optional().default("12:00"),
  break_end_time: timeString.optional().default("12:30"),
});

export const AttendanceLeaveSchema = z.object({
  user_id: intIdFromForm.optional(),
  date_from: z.string().min(1, "Datum je povinné"),
  date_to: z.string().optional(),
  leave_type: z
    .enum(["vacation", "sick", "unpaid"])
    .optional()
    .default("vacation"),
  leave_hours: numberFromForm.optional(),
  notes: z.string().nullish(),
});

const ProjectLogSchema = z.object({
  project_id: intIdFromForm,
  hours: z.coerce.number().min(0).default(0),
  minutes: numberInRange(0, 59).default(0),
});

export const AttendancePunchSchema = z.object({
  punch_action: z.string(),
  latitude: numberFromForm.nullish(),
  longitude: numberFromForm.nullish(),
  accuracy: numberFromForm.nullish(),
  address: z.string().max(500).nullish(),
});

// arrival/departure/break fields travel as COMBINED local datetimes
// ("YYYY-MM-DDTHH:MM:00", built by the admin forms' combineDatetime from a
// date + time input) — the service parses them with `new Date(...)`. They are
// NOT bare HH:MM times.
export const CreateAttendanceSchema = z.object({
  user_id: intIdFromForm.optional(),
  // Must be a bare "YYYY-MM-DD" (parses to UTC midnight) — the service's
  // duplicate-validation window and the stored @db.Date both depend on it.
  // isoDateString leniently strips a trailing time component.
  shift_date: isoDateString,
  arrival_time: nullableDateTimeString.optional(),
  arrival_lat: numberFromForm.nullish(),
  arrival_lng: numberFromForm.nullish(),
  arrival_accuracy: numberFromForm.nullish(),
  arrival_address: z.string().nullish(),
  departure_time: nullableDateTimeString.optional(),
  departure_lat: numberFromForm.nullish(),
  departure_lng: numberFromForm.nullish(),
  departure_accuracy: numberFromForm.nullish(),
  departure_address: z.string().nullish(),
  break_start: nullableDateTimeString.optional(),
  break_end: nullableDateTimeString.optional(),
  notes: z.string().nullish(),
  project_id: nullableIntIdFromForm.nullish(),
  leave_type: z
    .enum(["work", "vacation", "sick", "unpaid"])
    .optional()
    .default("work"),
  leave_hours: numberFromForm.nullish(),
  project_logs: z.array(ProjectLogSchema).optional(),
});

export const UpdateAttendanceSchema = z.object({
  arrival_time: nullableDateTimeString.optional(),
  departure_time: nullableDateTimeString.optional(),
  break_start: nullableDateTimeString.optional(),
  break_end: nullableDateTimeString.optional(),
  notes: z.string().nullish(),
  project_id: nullableIntIdFromForm.optional(),
  leave_type: z.enum(["work", "vacation", "sick", "unpaid"]).optional(),
  leave_hours: numberFromForm.nullish(),
  project_logs: z.array(ProjectLogSchema).optional(),
});

export type AttendanceNotesInput = z.infer<typeof AttendanceNotesSchema>;
export type AttendanceUpdateAddressInput = z.infer<
  typeof AttendanceUpdateAddressSchema
>;
export type AttendanceSwitchProjectInput = z.infer<
  typeof AttendanceSwitchProjectSchema
>;
export type AttendanceBalancesInput = z.infer<typeof AttendanceBalancesSchema>;
export type AttendanceBulkInput = z.infer<typeof AttendanceBulkSchema>;
export type AttendanceLeaveInput = z.infer<typeof AttendanceLeaveSchema>;
export type AttendancePunchInput = z.infer<typeof AttendancePunchSchema>;
export type CreateAttendanceInput = z.infer<typeof CreateAttendanceSchema>;
export type UpdateAttendanceInput = z.infer<typeof UpdateAttendanceSchema>;
