import { z } from 'zod';
import { baseListQuerySchema } from '@/lib/api/list-query';

export const TENANCY_STATUSES = ['pending', 'active', 'ended', 'cancelled'] as const;
export const TENURE_TYPES = ['permanent', 'fixed_term', 'seasonal'] as const;

export const createPendingSchema = z.object({
  berthId: z.string().min(1),
  clientId: z.string().min(1),
  yachtId: z.string().min(1),
  interestId: z.string().optional(),
  startDate: z.coerce.date(),
  tenureType: z.enum(TENURE_TYPES).optional().default('permanent'),
  notes: z.string().optional(),
});

export const activateSchema = z.object({
  contractFileId: z.string().optional(),
  effectiveDate: z.coerce.date().optional(),
});

export const endTenancySchema = z.object({
  endDate: z.coerce.date(),
  notes: z.string().optional(),
});

export const cancelSchema = z.object({
  reason: z.string().optional(),
});

/** PATCH body for the "edit metadata" idiom — touches notes / dates /
 *  tenure type without crossing a status boundary. Status transitions
 *  flow through activate / endTenancy / cancel; this is non-transition
 *  metadata only. */
export const updateTenancySchema = z
  .object({
    startDate: z.coerce.date().optional(),
    endDate: z.coerce.date().nullable().optional(),
    tenureType: z.enum(TENURE_TYPES).optional(),
    notes: z.string().nullable().optional(),
  })
  .refine((d) => Object.keys(d).length > 0, { message: 'At least one field must be provided' });
export type UpdateTenancyInput = z.infer<typeof updateTenancySchema>;

/** Renewal input. For permanent-class tenancies the existing row is
 *  mutated in place; for fixed_term / seasonal the existing row is
 *  ended at `previousEndDate` and a fresh row is minted with
 *  previousTenancyId pointing back. */
export const renewTenancySchema = z.object({
  /** New start date for the renewal window (or the mutated row when permanent). */
  newStartDate: z.coerce.date(),
  /** New end date — required for fixed_term / seasonal; optional when permanent. */
  newEndDate: z.coerce.date().optional(),
  /** Optional notes appended to the successor / mutated row. */
  notes: z.string().optional(),
});
export type RenewTenancyInput = z.infer<typeof renewTenancySchema>;

/** Transfer input — hand a berth's active tenancy to a new client/yacht
 *  pair. The current row is ended, a fresh active row is minted with
 *  transferredFromTenancyId pointing at the predecessor. */
export const transferTenancySchema = z.object({
  newClientId: z.string().min(1),
  newYachtId: z.string().min(1),
  transferDate: z.coerce.date(),
  notes: z.string().optional(),
});
export type TransferTenancyInput = z.infer<typeof transferTenancySchema>;

export const listTenanciesSchema = baseListQuerySchema.extend({
  status: z.enum(TENANCY_STATUSES).optional(),
  berthId: z.string().optional(),
  clientId: z.string().optional(),
  yachtId: z.string().optional(),
});

export type CreatePendingInput = z.infer<typeof createPendingSchema>;
export type ActivateInput = z.infer<typeof activateSchema>;
export type EndTenancyInput = z.infer<typeof endTenancySchema>;
export type CancelInput = z.infer<typeof cancelSchema>;
export type ListTenanciesInput = z.infer<typeof listTenanciesSchema>;
