import type { Visibility } from "@/core/module-registry/types";
import type { CompanyId } from "@/core/auth/types";

/** Document direction */
export type RegistryDirection = "intrat" | "iesit";

/** Maps direction to the numbering type code (used internally, not in number format) */
export const DIRECTION_TYPE_CODE: Record<RegistryDirection, string> = {
  intrat: "IN",
  iesit: "OUT",
};

/** Single-letter company prefixes for registry numbering.
 *  Format: B-2026-00001 (no direction code in the number). */
export const REGISTRY_COMPANY_PREFIX: Record<CompanyId, string> = {
  beletage: "B",
  "urban-switch": "U",
  "studii-de-teren": "S",
  group: "G",
};

/** Old 3-letter prefixes — for backward compat when scanning existing entries */
export const OLD_COMPANY_PREFIX: Record<string, string> = {
  B: "BTG",
  U: "USW",
  S: "SDT",
  G: "GRP",
};

/** Registration type — normal, late, or claimed from reserved slot */
export type RegistrationType = "normal" | "late" | "reserved-claimed";

/** Default document types — user can add custom types that sync with Tag Manager */
export const DEFAULT_DOCUMENT_TYPES = [
  "contract",
  "oferta",
  "factura",
  "scrisoare",
  "aviz",
  "nota-de-comanda",
  "raport",
  "cerere",
  "proces-verbal",
  "convocare-sedinta",
  "convocare-ctatu",
  "notificare",
  "comunicare",
  "apel-telefonic",
  "videoconferinta",
  "altele",
] as const;

/** Document type — string-based for dynamic types from Tag Manager */
export type DocumentType = (typeof DEFAULT_DOCUMENT_TYPES)[number] | string;

/** Labels for default document types */
export const DEFAULT_DOC_TYPE_LABELS: Record<string, string> = {
  contract: "Contract",
  oferta: "Oferta",
  factura: "Factura",
  scrisoare: "Scrisoare / Adresa",
  aviz: "Aviz / Act administrativ",
  "nota-de-comanda": "Nota de comanda",
  raport: "Raport / Studiu",
  cerere: "Cerere",
  "proces-verbal": "Proces verbal",
  "convocare-sedinta": "Convocare sedinta",
  "convocare-ctatu": "Convocare CTATU",
  notificare: "Notificare",
  comunicare: "Comunicare",
  "apel-telefonic": "Apel telefonic",
  videoconferinta: "Videoconferinta",
  altele: "Altele",
};

/** Status — open/closed/reserved */
export type RegistryStatus = "deschis" | "inchis" | "reserved";

/** Closure resolution — why the entry was closed */
export type ClosureResolution =
  | "finalizat"
  | "aprobat-tacit"
  | "respins"
  | "retras"
  | "altele";

/** Structured closure information — recorded every time an entry is closed */
export interface ClosureInfo {
  /** Resolution type */
  resolution: ClosureResolution;
  /** Why the entry was closed */
  reason: string;
  /** Who closed it (name / SSO identity when available) */
  closedBy: string;
  /** ISO timestamp of closure */
  closedAt: string;
  /** If the entry continues in another entry, its ID */
  linkedEntryId?: string;
  /** Linked entry number for display (e.g. "B-0042/2026") */
  linkedEntryNumber?: string;
  /** Whether the entry had unresolved legal deadlines when closed */
  hadActiveDeadlines: boolean;
  /** Optional document justifying the closure */
  attachment?: RegistryAttachment;
}

/** File attachment — either uploaded (base64) or network path reference */
export interface RegistryAttachment {
  id: string;
  name: string;
  /** base64-encoded content, empty string (stripped), or "__network__" for network paths */
  data: string;
  type: string;
  size: number;
  addedAt: string;
  /** UNC or drive-letter path to a file on network storage (NAS) */
  networkPath?: string;
}

// ── Deadline tracking types ──

export type DeadlineDayType = "calendar" | "working";

export type DeadlineResolution =
  | "pending"
  | "completed"
  | "aprobat-tacit"
  | "respins"
  | "anulat"
  | "intrerupt";

export type DeadlineCategory =
  | "certificat"
  | "avize"
  | "completari"
  | "urbanism"
  | "autorizare"
  | "litigii";

export interface DeadlineTypeDef {
  id: string;
  label: string;
  description: string;
  days: number;
  dayType: DeadlineDayType;
  startDateLabel: string;
  requiresCustomStartDate: boolean;
  startDateHint?: string;
  tacitApprovalApplicable: boolean;
  tacitApprovalExcludable?: boolean;
  chainNextTypeId?: string;
  chainNextActionLabel?: string;
  legalReference?: string;
  category: DeadlineCategory;
  isBackwardDeadline?: boolean;
  /** If true, this deadline is auto-created by the system (not user-selectable) */
  autoTrack?: boolean;
  /** Which directions this category/type applies to (undefined = both) */
  directionFilter?: RegistryDirection[];
  /** If true, this deadline is purely background — never shown in dashboard */
  backgroundOnly?: boolean;
}

/** Audit log entry for deadline changes */
export interface DeadlineAuditEntry {
  action: "created" | "resolved" | "modified" | "recipient-registered" | "paused" | "resumed";
  timestamp: string;
  /** User who performed the action (SSO name when available) */
  actor?: string;
  detail: string;
}

export interface TrackedDeadline {
  id: string;
  typeId: string;
  startDate: string;
  dueDate: string;
  resolution: DeadlineResolution;
  resolvedDate?: string;
  resolutionNote?: string;
  chainParentId?: string;
  /** Mini audit log — tracks who created/modified/resolved this deadline */
  auditLog?: DeadlineAuditEntry[];
  createdAt: string;

  // ── Pause/resume for clarification requests ──
  /** ISO date when deadline was paused (solicitare clarificari linked) */
  pausedAt?: string;
  /** Total calendar days the deadline has been paused across all pause periods */
  totalPausedDays?: number;
}

// ── AC (Autorizație de Construire) validity tracking ──

/** Execution duration options (months) */
export type ACExecutionDuration = 6 | 12 | 24 | 36;

/** Phase of the AC lifecycle */
export type ACPhase =
  | "validity" // 12-month validity period from issuance
  | "execution" // Execution period after works announcement
  | "extended" // Extended by 24 months
  | "abandoned" // Declared not starting
  | "expired"; // Period expired without action

/** Required document checklist for starting works */
export interface ACRequiredDocs {
  /** Notare în Cartea Funciară */
  cfNotation: boolean;
  cfNotationDate?: string;
  /** Publicare într-un ziar */
  newspaperPublication: boolean;
  newspaperPublicationDate?: string;
  /** Afișare panou de șantier */
  sitePanel: boolean;
  sitePanelDate?: string;
}

/** Reminder state */
export interface ACReminder {
  /** ISO date of last snooze */
  lastSnoozed?: string;
  /** Number of months snoozed so far */
  snoozeCount: number;
  /** Whether the user dismissed monthly reminders */
  dismissed: boolean;
}

export type ACValidityPeriod = 12 | 24;

/** Full AC validity tracking state */
export interface ACValidityTracking {
  /** Whether AC tracking is enabled for this entry */
  enabled: boolean;
  /** Date the AC was issued (YYYY-MM-DD) */
  issuanceDate: string;
  /** Current phase */
  phase: ACPhase;
  /** Validity period in months (default 12, can be 24 for special cases) */
  validityMonths?: ACValidityPeriod;
  /** Execution duration selected (months) */
  executionDuration: ACExecutionDuration;
  /** Date works were announced to City Hall & ISC */
  worksAnnouncedDate?: string;
  /** Date works actually started */
  worksStartDate?: string;
  /** Required documents checklist */
  requiredDocs: ACRequiredDocs;
  /** Reminder state */
  reminder: ACReminder;
  /** Extension (prelungire) request date */
  extensionRequestDate?: string;
  /** Extension granted (inscribed on original AC) */
  extensionGranted: boolean;
  /** Extension granted date */
  extensionGrantedDate?: string;
  /** Declared abandonment — user chose not to start */
  abandonedDeclaration: boolean;
  abandonedDate?: string;
  abandonedReason?: string;
  /** Audit notes */
  notes: string[];
}

// ── External status monitoring types ──

/** Semantic status of a document at an external authority */
export type ExternalDocStatus =
  | "in-operare"
  | "trimis"
  | "solutionat"
  | "respins"
  | "necunoscut";

/** Labels for external doc statuses (Romanian UI) */
export const EXTERNAL_STATUS_LABELS: Record<ExternalDocStatus, string> = {
  "in-operare": "In operare",
  trimis: "Trimis",
  solutionat: "Solutionat",
  respins: "Respins",
  necunoscut: "Necunoscut",
};

/** A single row from the authority's status tracking table */
export interface ExternalStatusRow {
  dataVenire: string;
  oraVenire: string;
  sursa: string;
  dataTrimitere: string;
  oraTrimitere: string;
  destinatie: string;
  modRezolvare: string;
  comentarii: string;
}

/** A recorded change in external status */
export interface ExternalStatusChange {
  timestamp: string;
  row: ExternalStatusRow;
  semanticStatus: ExternalDocStatus;
  notified: boolean;
}

/** Full tracking state for an entry's external status monitoring */
export interface ExternalStatusTracking {
  /** Authority config ID (e.g., "primaria-cluj") */
  authorityId: string;
  /** Petitioner name used for authority lookup */
  petitionerName: string;
  /** Registration number at the authority */
  regNumber: string;
  /** Registration date at the authority (dd.mm.yyyy for POST) */
  regDate: string;
  /** ISO timestamp of last check */
  lastCheckAt: string | null;
  /** Last known status row */
  lastStatusRow: ExternalStatusRow | null;
  /** Hash of last status row for change detection */
  statusHash: string;
  /** Derived semantic status */
  semanticStatus: ExternalDocStatus;
  /** History of detected status changes (max 50) */
  history: ExternalStatusChange[];
  /** Whether monitoring is active */
  active: boolean;
  /** Last error message (null if OK) */
  lastError: string | null;
}

export interface RegistryEntry {
  id: string;
  /** Company-specific number: B-0001/2026, US-0001/2026, SDT-0001/2026 */
  number: string;
  /** Data documentului (poate fi în trecut pentru backdating) */
  date: string;
  /** Data înregistrării efective în sistem (auto = azi) */
  registrationDate?: string;
  direction: RegistryDirection;
  documentType: DocumentType;
  subject: string;
  /** Expeditor — free text or linked contact ID */
  sender: string;
  senderContactId?: string;
  /** Destinatar — free text or linked contact ID */
  recipient: string;
  recipientContactId?: string;
  /** Număr înregistrare la destinatar (for outgoing docs — triggers legal deadline) */
  recipientRegNumber?: string;
  /** Data înregistrare la destinatar (YYYY-MM-DD) — legal deadlines start from this date */
  recipientRegDate?: string;
  company: CompanyId;
  status: RegistryStatus;
  /** Structured closure metadata (populated when status = 'inchis') */
  closureInfo?: ClosureInfo;
  /** Deadline date (YYYY-MM-DD) */
  deadline?: string;
  /** Assignee — person responsible (ERP-ready field) */
  assignee?: string;
  assigneeContactId?: string;
  /** Thread parent — ID of the entry this is a reply to */
  threadParentId?: string;
  /** Linked entry IDs (for closing/archiving related entries) */
  linkedEntryIds: string[];
  /** File attachments */
  attachments: RegistryAttachment[];
  /** Tracked legal deadlines */
  trackedDeadlines?: TrackedDeadline[];
  /** Document expiry date — for CU/AC validity tracking (YYYY-MM-DD) */
  expiryDate?: string;
  /** Days before expiry to trigger alert (default 30) */
  expiryAlertDays?: number;
  /** URL for external status checking (web scraping prep) */
  externalStatusUrl?: string;
  /** External tracking ID (e.g., portal reference number) */
  externalTrackingId?: string;
  /** External authority status monitoring */
  externalStatusTracking?: ExternalStatusTracking;
  /** AC (Autorizație de Construire) validity tracking */
  acValidity?: ACValidityTracking;
  tags: string[];
  notes: string;
  visibility: Visibility;
  createdAt: string;
  updatedAt: string;

  // ── New fields for numbering/reserved/audit ──

  /** Whether this is a reserved slot (auto-generated placeholder) */
  isReserved?: boolean;
  /** Registration type — normal, late, or reserved-claimed */
  registrationType?: RegistrationType;
  /** Who created this entry (SSO user ID) */
  createdBy?: string;
  /** Who created this entry (display name) */
  createdByName?: string;
  /** Original reserved slot ID if this entry claimed a reserved slot */
  claimedReservedSlotId?: string;
  /** Old-format number if entry was migrated */
  legacyNumber?: string;
}

// ── Audit types ──

export type RegistryAuditAction =
  | "created"
  | "updated"
  | "reserved_created"
  | "reserved_claimed"
  | "late_registration"
  | "closed"
  | "reopened"
  | "deleted";

export interface RegistryAuditEvent {
  id: string;
  entryId: string;
  entryNumber: string;
  action: RegistryAuditAction;
  actor: string;
  actorName?: string;
  company: string;
  detail?: Record<string, unknown>;
  createdAt: string;
}
