import { LucideIcon } from 'lucide-react';

/** Реэкспорт из единого источника прав (constants/roleAccess.ts) */
export type { UserRole } from './constants/roleAccess';

export interface User {
  id: string;
  userId?: string | number;
  name: string;
  givenName?: string | null;
  familyName?: string | null;
  email?: string;
  emailVerified?: boolean;
  phone?: string | null;
  role: UserRole;
  avatar: string | null;
  birthDate?: string | null;
  position?: string | null;
  /** Назначенные участки (несколько у мастера). */
  assignedDistrictIds?: string[] | null;
  assignedDistrictId?: string | null;
  messengerLogins?: { messenger: 'Max' | 'Telegram'; login: string }[];
  language?: string;
  theme?: string;
  notificationEmail?: boolean;
  notificationPush?: boolean;
  lastLogin?: string | null;
  createdAt?: string | null;
  updatedAt?: string | null;
  allowedSections?: string[];
  permissions?: string[] | null;
  scope?: 'all' | 'own_district';
}

export interface UserPreferences {
  language: string;
  theme: string;
  notificationEmail: boolean;
  notificationPush: boolean;
}

export interface NavItem {
  id: string;
  label: string;
  icon: LucideIcon;
}

export interface District {
  id: string;
  name: string;
  managerName: string;
  inventory?: BuildingInventoryItem[]; // Склад участка
}

/** Справочник должностей (панель управления) */
export interface Position {
  id: string;
  name: string;
  isManagerial: boolean;
  sortOrder?: number;
  createdAt?: string;
  updatedAt?: string;
}

export interface Employee {
  id: string;
  name: string; // ФИО
  position: string; // Должность
  phone: string; // Номер телефона
  status: 'active' | 'vacation' | 'inactive';
  salary: number;
  /** Назначенные участки (многие ко многим). Приоритет над assignedDistrictId. */
  assignedDistrictIds?: string[];
  /** Один участок — для обратной совместимости; первый из assignedDistrictIds или старое поле. */
  assignedDistrictId?: string | null; // Участок
  managerId?: string; // ID руководителя сотрудника
  birthDate?: string; // Дата рождения (ISO date string)
  messengerLogins?: { // Логины мессенджеров
    messenger: 'Max' | 'Telegram';
    login: string;
  }[];
  photoUrl?: string; // Фото сотрудника
  registrationDate?: string; // Дата регистрации (ISO date string)
  hrData?: { // Данные для HR и Бухгалтерии
    passportData?: {
      series: string;
      number: string;
      issuedBy: string;
      issuedDate: string;
      registrationAddress: string;
    };
    laborBook?: {
      number: string;
      series?: string;
      entries?: Array<{
        date: string;
        organization: string;
        position: string;
      }>;
    };
    certificates?: Array<{ // Заказ справок
      type: string; // Тип справки (2-НДФЛ, справка с места работы и т.д.)
      requestedDate: string;
      issuedDate?: string;
      status: 'requested' | 'issued' | 'ready';
    }>;
    otherDocuments?: Array<{
      name: string;
      type: string;
      date: string;
      fileUrl?: string;
    }>;
    accountingData?: { // Бухгалтерская информация
      inn?: string; // ИНН
      snils?: string; // СНИЛС
      bankName?: string; // Название банка
      bankAccount?: string; // Расчетный счет
      correspondentAccount?: string; // Корреспондентский счет
      bik?: string; // БИК
      taxId?: string; // КПП
    };
    contracts?: Array<{ // Характеристики договора
      id?: number;
      contractType: string; // Тип договора (трудовой, ГПХ, срочный и т.д.)
      contractNumber?: string; // Номер договора
      startDate: string; // Дата начала
      endDate?: string; // Дата окончания (для бессрочного - undefined)
      probationPeriodDays?: number; // Испытательный срок в днях
      workSchedule?: string; // График работы
      workMode?: string; // Режим работы (офис, удаленно, гибрид)
      contractTerms?: string; // Дополнительные условия
    }>;
    vacations?: EmployeeVacation[]; // Отпуска
    sickLeaves?: EmployeeSickLeave[]; // Больничные
    terminations?: EmployeeTermination[]; // Увольнения
    absences?: EmployeeAbsence[]; // Отгулы и прогулы
  };
}

// Отпуск сотрудника
export interface EmployeeVacation {
  id: number;
  employeeId: string;
  startDate: string; // ISO date string
  endDate: string; // ISO date string
  daysCount: number;
  vacationType: 'annual' | 'unpaid' | 'study' | 'maternity' | 'other'; // Тип отпуска
  status: 'planned' | 'approved' | 'active' | 'completed' | 'canceled';
  requiresApproval?: boolean; // Требуется ли согласование
  approvedBy?: string;
  approvedAt?: string; // ISO datetime string
  approvedSignature?: string; // Подпись руководителя
  rejectedBy?: string;
  rejectedAt?: string; // ISO datetime string
  rejectionReason?: string; // Причина отклонения
  notes?: string;
  createdAt: string; // ISO datetime string
  updatedAt: string; // ISO datetime string
}

// Больничный сотрудника
export interface EmployeeSickLeave {
  id: number;
  employeeId: string;
  startDate: string; // ISO date string
  endDate?: string; // ISO date string (может быть NULL, если больничный еще не закрыт)
  expectedReturnDate?: string; // Предварительная дата выхода (ISO date)
  daysCount?: number;
  sickLeaveNumber?: string; // Номер больничного листа (обязателен при выходе с больничного)
  diagnosis?: string; // Диагноз
  medicalInstitution?: string; // Медицинское учреждение
  status: 'active' | 'closed' | 'canceled';
  requiresApproval?: boolean; // Требуется ли согласование
  approvedBy?: string;
  approvedAt?: string; // ISO datetime string
  approvedSignature?: string; // Подпись руководителя
  closedAt?: string; // ISO datetime string
  notes?: string;
  fileUrl?: string; // Ссылка на отсканированный больничный лист
  createdAt: string; // ISO datetime string
  updatedAt: string; // ISO datetime string
}

// Отгул или прогул сотрудника
export interface EmployeeAbsence {
  id: number;
  employeeId: string;
  absenceType: 'day_off' | 'absence' | 'late' | 'early_leave'; // Тип: отгул, прогул, опоздание, ранний уход
  startDate: string; // ISO date string
  endDate?: string; // ISO date string (может быть NULL для однодневных отгулов)
  startTime?: string; // Время начала (HH:mm) для опозданий и ранних уходов
  endTime?: string; // Время окончания (HH:mm) для опозданий и ранних уходов
  daysCount: number; // Количество дней (может быть дробным для части дня)
  reason?: string; // Причина отсутствия
  requiresApproval: boolean; // Требуется ли согласование
  status: 'pending' | 'approved' | 'rejected' | 'canceled'; // Статус согласования
  approvedBy?: string; // Кто утвердил (руководитель)
  approvedAt?: string; // ISO datetime string
  approvedSignature?: string; // Подпись руководителя (текст или путь к файлу)
  rejectedBy?: string; // Кто отклонил
  rejectedAt?: string; // ISO datetime string
  rejectionReason?: string; // Причина отклонения
  notes?: string; // Примечания
  createdAt: string; // ISO datetime string
  updatedAt: string; // ISO datetime string
}

// Увольнение сотрудника
// Обучение сотрудников (инструктажи и курсы)
export type TrainingType = 'instruction' | 'course' | 'certification' | 'exam' | 'other';
export type TrainingCategory = 'safety' | 'fire_safety' | 'electrical' | 'first_aid' | 'professional' | 'compliance' | 'other';
export type TrainingStatus = 'not_started' | 'in_progress' | 'completed' | 'failed' | 'expired' | 'cancelled';

export interface TrainingProgram {
  id: string;
  title: string;
  description?: string;
  type: TrainingType;
  category: TrainingCategory;
  durationHours?: number;
  validityMonths?: number; // Срок действия в месяцах (null = бессрочно)
  isRequired: boolean;
  requiredForPositions?: string[]; // Должности, для которых обязательно
  instructorName?: string;
  materialsUrl?: string;
  createdAt?: string;
  updatedAt?: string;
}

export interface EmployeeTraining {
  id: number;
  employeeId: string;
  programId: string;
  status: TrainingStatus;
  startDate?: string;
  completionDate?: string;
  expiryDate?: string; // Дата окончания срока действия
  score?: number;
  passed?: boolean;
  certificateNumber?: string;
  certificateUrl?: string;
  notes?: string;
  instructorName?: string;
  location?: string;
  createdAt?: string;
  updatedAt?: string;
  // Дополнительные поля при получении с JOIN
  programTitle?: string;
  programType?: TrainingType;
  programCategory?: TrainingCategory;
  programDurationHours?: number;
  programValidityMonths?: number;
  employeeName?: string;
  employeePosition?: string;
}

export interface EmployeeTermination {
  id: number;
  employeeId: string;
  terminationDate: string; // ISO date string
  reason: string; // Причина увольнения
  initiatedBy: string; // Кто инициировал увольнение
  initiatedAt: string; // ISO datetime string
  status: 'initiated' | 'in_progress' | 'completed' | 'canceled';
  // Договор на увольнение
  terminationContractNumber?: string;
  terminationContractDate?: string; // ISO date string
  terminationContractFileUrl?: string;
  // Расчеты
  finalSettlementAmount?: number;
  unusedVacationDays?: number;
  compensationAmount?: number; // Компенсация за неиспользованный отпуск
  severancePay?: number; // Выходное пособие
  otherPayments?: number; // Прочие выплаты
  deductions?: number; // Удержания
  settlementDocumentNumber?: string;
  settlementDocumentDate?: string; // ISO date string
  settlementDocumentFileUrl?: string;
  // Дополнительная информация
  notes?: string;
  completedAt?: string; // ISO datetime string
  createdAt: string; // ISO datetime string
  updatedAt: string; // ISO datetime string
}

export interface CandidateEvent {
  id: string;
  candidateId: string;
  eventType: 'call' | 'interview_1' | 'interview_2' | 'interview_3' | 'test_task' | 'offer' | 'offer_accepted' | 'offer_rejected' | 'probation_start' | 'hired' | 'rejected' | 'other';
  eventDate: string; // ISO date string
  notes?: string;
  result?: 'success' | 'failed' | 'pending' | 'cancelled';
  interviewer?: string;
  location?: string;
  durationMinutes?: number;
  createdAt?: string;
  updatedAt?: string;
}

export interface Candidate {
  id: string;
  name: string;
  position: string;
  vacancyId?: string; // Связь с вакансией
  stage: 'new' | 'interview' | 'probation' | 'hired' | 'rejected';
  phone: string;
  email?: string;
  resumeUrl?: string;
  coverLetter?: string;
  interviewDate?: string;
  interviewNotes?: string;
  offerSalary?: number;
  offerDate?: string;
  hiredDate?: string;
  rejectedReason?: string;
  events?: CandidateEvent[]; // События кандидата
  createdAt?: string;
  updatedAt?: string;
}

export interface Vacancy {
  id: string;
  position: string;
  department: string;
  status: 'urgent' | 'active' | 'paused' | 'closed';
  salary?: string;
  applicantsCount: number;
  postedDate: string;
  description: string;
  requirements?: string; // Требования к кандидату
  conditions?: string; // Условия работы
  responsibilities?: string; // Обязанности
  closingDate?: string; // Дата закрытия вакансии
  createdAt?: string;
  updatedAt?: string;
}

export interface SMMChannel {
  id: number;
  name: string;
  type: 'tg' | 'vk' | 'wa' | 'other';
  url?: string;
  sortOrder?: number;
  createdAt?: string;
  lastSnapshot?: SMMSubscriberSnapshot | null;
  subscribersCount?: number | null;
}

export interface SMMSubscriberSnapshot {
  id: number;
  channelId: number;
  subscribersCount: number;
  recordedAt: string;
  note?: string;
  createdAt?: string;
}

export interface SMMChannelsSummary {
  total: number;
  byChannel: Array<{ id: number; name: string; type: string; subscribersCount: number }>;
}

export interface AttractionAction {
  id: number;
  title: string;
  description?: string;
  channelId?: number | null;
  actionType: 'mailing' | 'event' | 'post' | 'other';
  actionDate: string;
  newSubscribersAttributed?: number | null;
  eventId?: number | null;
  createdAt?: string;
  createdBy?: string;
  channelName?: string;
  channelType?: string;
}

export interface PostTopic {
  id: number;
  title: string;
  description?: string;
  scheduledDate: string; // дата планируемой публикации
  month: string; // YYYY-MM для фильтрации
  status: 'draft' | 'pending_approval' | 'approved' | 'rejected';
  createdAt?: string;
  createdBy?: string;
  approvedAt?: string;
  approvedBy?: string;
  rejectionReason?: string;
}

export interface ScheduledPost {
  id: number;
  title: string;
  content: string;
  channelIds: number[];
  scheduledAt: string;
  status: 'draft' | 'pending_approval' | 'approved' | 'rejected' | 'edited' | 'published';
  topicId?: number | null;
  imageUrl?: string | null;
  createdAt?: string;
  createdBy?: string;
  approvedAt?: string;
  approvedBy?: string;
  rejectionReason?: string;
  editedContent?: string;
  publishedAt?: string;
}

export interface PREventPhoto {
  id: number;
  event_id?: number;
  photoUrl: string;
  caption?: string;
  locationType?: 'building' | 'office';
  locationBuildingId?: string;
  createdAt?: string;
}

export interface PREvent {
  id: string | number;
  title: string;
  date: string;
  type: 'resident' | 'internal';
  category: 'holiday' | 'eco' | 'sport' | 'training' | 'meeting';
  status: 'planned' | 'in_progress' | 'completed' | 'canceled';
  location: string;
  attendeesCount: number;
  budget?: number;
  shortPlan?: string;
  announcement?: string;
  locationType?: 'building' | 'office';
  locationBuildingId?: string;
  /** Для жителей: участок или дома отдельно */
  locationPlaceType?: 'district' | 'buildings';
  locationDistrictId?: string;
  locationBuildingIds?: string[];
  assignedEmployeeIds?: string[];
  photos?: PREventPhoto[];
  invoices?: Array<{ id: number; invoiceNumber: string; status: string; totalAmount?: number }>;
  createdAt?: string;
  updatedAt?: string;
  createdBy?: string;
}

/** Живая статистика по отчёту — актуальные данные из БД на момент запроса */
export interface ResidentReportLiveStats {
  applicationsTotal: number;
  npsScore: number;
  fundsCollected: number;
}

export interface ResidentReport {
  id: string | number;
  buildingId: string;
  address?: string;
  month: string;
  periodStart?: string;
  periodEnd?: string;
  status: 'draft' | 'published';
  publishedAt?: string;
  content?: ResidentReportContent;
  /** Живая статистика (заявки, NPS, собрано) — подставляется с бэкенда при запросе списка */
  liveStats?: ResidentReportLiveStats;
  createdAt?: string;
  updatedAt?: string;
  // Старые поля для обратной совместимости
  stats?: {
    appsDone: number;
    budgetSpent: number;
    cleaningQuality: number;
  };
}

export interface ResidentReportContent {
  // Информация о доме
  buildingInfo?: {
    address: string;
    apartmentsCount?: number;
    floors?: number;
  };
  // Заявки за период
  applications?: {
    total: number;
    completed: number;
    inProgress: number;
    new: number;
    list?: Array<{
      id: number;
      number: string;
      description: string;
      status: string;
      createdAt: string;
    }>;
  };
  // Статистика по дому
  statistics?: {
    nps?: number;
    collectionRate?: number;
    totalDebt?: number;
    debtorsCount?: number;
  };
  // Работа с должниками
  debtors?: Array<{
    name: string;
    apartment: string;
    debt: number;
  }>;
  // Финансы предприятия
  finances?: {
    income: number;
    expenses: number;
    balance: number;
    incomeByItems?: Record<string, number>;
    expensesByItems?: Record<string, number>;
  };
  // Фото отчеты
  workPhotos?: WorkPhoto[];
  // AI сгенерированный текст
  generatedText?: string;
  // Структура отчета собственника (из оборотно-сальдовой ведомости)
  parameters?: {
    periodStart: string;
    periodEnd: string;
    building: string;
    residentialArea?: number;
    nonResidentialArea?: number;
    parkingArea?: number;
    totalArea?: number;
  };
  tariffs?: {
    tariff: number;
    reserveFund: number;
  };
  services?: Array<{
    name: string;
    debt: number;
    accrued: number;
    paid: number;
    percentOfPlan: number;
    order: number;
  }>;
  balance?: {
    fromAccrued: number;
    fromReceived: number;
    reserveFundFromAccrued: number;
    reserveFundFromReceived: number;
  };
  expenseItems?: Array<{
    number: string;
    name: string;
    perMonth: number;
    total: number;
    perSquareMeter: number;
    children?: Array<{
      number: string;
      name: string;
      perMonth: number;
      total: number;
      perSquareMeter: number;
      children?: Array<{
        number: string;
        name: string;
        perMonth: number;
        total: number;
        perSquareMeter: number;
      }>;
    }>;
  }>;
  totals?: {
    totalExpenses: number;
    vat: number;
    recalculation: number;
    totalWithRecalculation: number;
    totalWithRecalculationWithVAT: number;
    debtReturn: number;
    totalTariff: number;
    otherIncome: number;
  };
  financialResults?: {
    maintenanceFromAccrued: number;
    maintenanceFromReceived: number;
    reserveFundFromAccrued: number;
    reserveFundFromReceived: number;
  };
}

// ========= PR и NPS: ФОТО ОТЧЕТЫ =========
export interface WorkPhoto {
  id: number;
  buildingId: string;
  residentReportId?: number;
  taskId?: string; // Привязка к задаче (фото отчёт до/после)
  workName: string;
  workDate: string;
  description?: string;
  photoBeforeUrl?: string;
  photoAfterUrl?: string;
  createdAt: string;
  updatedAt: string;
  // Дополнительные поля для отображения
  address?: string;
}

// ========= PR и NPS: NPS ОПРОСЫ =========
export type NPSSurveyStatus = 'draft' | 'active' | 'closed';

export interface NPSSurvey {
  id: number;
  buildingId: string;
  title: string;
  description?: string;
  status: NPSSurveyStatus;
  accessKey: string;
  publishedAt?: string;
  expiresAt?: string;
  createdBy: string;
  createdAt: string;
  updatedAt: string;
  // Дополнительные поля для отображения
  address?: string;
  responsesCount?: number;
  avgScore?: number;
}

export interface NPSResponse {
  id: number;
  surveyId: number;
  buildingId: string;
  score: number; // 0-10
  comment?: string;
  respondentName?: string;
  apartment?: string;
  phone?: string;
  email?: string;
  createdAt: string;
}

export interface NPSSurveyStats {
  totalResponses: number;
  avgScore: number;
  promoters: number; // 9-10
  passives: number; // 7-8
  detractors: number; // 0-6
  nps: number; // (promoters% - detractors%)
  promoterPercent: number;
  detractorPercent: number;
}

// ========= PR и NPS: НАСТРОЙКИ ПАРСИНГА =========
export type ParsingSource = 'yandex_maps' | '2gis';

export interface ParsingSettings {
  id: number;
  source: ParsingSource;
  enabled: boolean;
  urlTemplate?: string;
  apiKey?: string;
  parsingIntervalHours: number;
  lastParsedAt?: string;
  settings?: Record<string, any>;
  buildingId?: string; // ID дома, к которому привязаны отзывы (извлекается из settings.building_id)
  createdAt: string;
  updatedAt: string;
}

export type Department = 'production' | 'pr' | 'finance' | 'development' | 'legal' | 'hr';

export type CompanyNewsStatus = 'draft' | 'pending' | 'published';

export interface CompanyNews {
  id: number;
  title: string;
  body: string | null;
  status: CompanyNewsStatus;
  createdAt: string;
  updatedAt: string;
  publishedAt: string | null;
  createdBy: number | null;
  createdByName?: string | null;
  notifyDepartments?: Department[];
  notifyEmployeeIds?: string[];
}

export interface StrategicGoal {
  id: string;
  department: Department;
  title: string;
  description: string;
  currentValue: number;
  targetValue: number;
  unit: string;
  deadline: string;
}

export interface ResidentFeedback {
  id: string;
  buildingId: string;
  address: string;
  date: string;
  text: string;
  source: string;
  rating: number;
}

export interface AnalyzedFeedback extends ResidentFeedback {
  category: string;
  sentiment: 'Positive' | 'Negative' | 'Neutral';
}

// ========= PR и NPS: ОТЗЫВЫ =========
export type ReviewSource = 'yandex_maps' | '2gis' | 'internal' | 'other';
export type ReviewStatus = 'new' | 'processed' | 'archived';

export interface Review {
  id: number;
  buildingId: string;
  source: ReviewSource;
  sourceUrl?: string;
  authorName?: string;
  text: string;
  rating: number; // 1-10
  date: string;
  status: ReviewStatus;
  processedAt?: string;
  processedBy?: string;
  createdAt: string;
  updatedAt: string;
  // Дополнительные поля для отображения
  address?: string;
}

// ========= PR и NPS: ИНЦИДЕНТЫ =========
export type IncidentType = 'property_damage' | 'debtor_complaint' | 'service_quality' | 'other';
export type IncidentStatus = 'new' | 'in_progress' | 'resolved' | 'closed';
export type IncidentPriority = 'low' | 'medium' | 'high' | 'urgent';

export interface Incident {
  id: number;
  reviewId?: number;
  buildingId: string;
  type: IncidentType;
  title: string;
  description: string;
  status: IncidentStatus;
  priority: IncidentPriority;
  assignedTo?: string;
  createdBy: string;
  createdAt: string;
  resolvedAt?: string;
  resolutionNotes?: string;
  updatedAt: string;
  // Дополнительные поля для отображения
  address?: string;
  review?: Review;
}

export interface AIAnalysisResult {
  analyzedFeedback: AnalyzedFeedback[];
  summary: {
    positive: string[];
    negative: string[];
  };
}

export type DomaApplicationStatus = 'new' | 'in_progress' | 'deferred' | 'done' | 'canceled';

export interface DomaApplication {
  id: number;
  number: string;
  status: DomaApplicationStatus;
  description: string;
  address: string;
  apartment: string;
  clientName: string;
  createdAt: string;
  deadlineAt: string;
  performer?: { name: string };
  isOverdue?: boolean;
  domaId?: string;
  source?: 'doma' | 'manual';
  sourceChannel?: string;
  contactPhone?: string;
  contactName?: string;
  placeIncident?: string;
  workType?: string;
  problemDetail?: string;
  executorName?: string;
  responsibleName?: string;
  observersText?: string;
  updatedAt?: string;
  buildingId?: string;
}

/** Комментарий к заявке (внутренний или с жителем) */
export interface ApplicationComment {
  id: number;
  applicationId: number;
  authorName: string;
  type: 'internal' | 'resident';
  text: string;
  createdAt: string;
}

/** Запись истории изменений заявки */
export interface ApplicationHistoryEntry {
  id: number;
  applicationId: number;
  changedBy: string;
  changedAt: string;
  fieldName: string;
  oldValue?: string | null;
  newValue?: string | null;
}

/** Payload для создания заявки вручную (карточка диспетчерской) */
export interface CreateApplicationPayload {
  address: string;
  description: string;
  apartment?: string;
  sourceChannel?: string;
  isFromResident?: boolean;
  contactPhone?: string;
  contactName?: string;
  placeIncident?: string;
  workType?: string;
  problemDetail?: string;
  isEmergency?: boolean;
  isPaid?: boolean;
  isWarranty?: boolean;
  deadlineAt?: string;
  executorName?: string;
  responsibleName?: string;
  observersText?: string;
  showInApp?: boolean;
  buildingId?: string;
}

/** Запись журнала отключений */
export type OutageWorkType = 'absent' | 'planned' | 'emergency';

export interface Outage {
  id: number;
  buildingId: string;
  startAt: string;
  endAt?: string | null;
  type?: string | null;
  description?: string | null;
  active: boolean;
  createdAt: string;
  updatedAt: string;
  buildingAddress?: string;
  authorName?: string | null;
  category?: string | null;
  problemDetail?: string | null;
  workType?: OutageWorkType | string | null;
  residentMessage?: string | null;
  generateNews?: boolean;
}

export interface CreateOutagePayload {
  buildingId?: string;
  buildingIds?: string[];
  startAt: string;
  endAt?: string;
  type?: string;
  description: string;
  active?: boolean;
  authorName?: string;
  category?: string;
  problemDetail?: string;
  workType?: OutageWorkType | string;
  residentMessage?: string;
  generateNews?: boolean;
}

export interface OfficeRequest {
  id: number | string; // number из БД, string для моков
  requesterName: string;
  category: string;
  itemName: string;
  quantity?: number;
  issuedQuantity?: number; // Количество выданного сотруднику
  unit?: string;
  date?: string; // Дата создания (created_at)
  status: 'new' | 'approved' | 'ordered' | 'received' | 'canceled' | 'archived' | 'collected';
  amount: number;
  priority: 'low' | 'medium' | 'high' | 'urgent';
  approvedBy?: string;
  approvedAt?: string;
  orderedAt?: string;
  receivedAt?: string;
  notes?: string;
  createdAt?: string;
  updatedAt?: string;
}

export interface OfficeInventoryItem {
  id: number | string; // number из БД, string для моков
  name: string;
  category?: string;
  quantity: number;
  unit: string;
  minThreshold: number;
  lastRestock?: string | null; // DATE из БД
  lastRestockBy?: string;
  location?: string;
  notes?: string;
  createdAt?: string;
  updatedAt?: string;
}

export interface OfficeDocument {
  id: number | string; // number из БД, string для моков
  regNumber: string;
  title: string;
  correspondent: string;
  date: string;
  status: 'registered' | 'processed' | 'sent' | 'archived';
  // FIX: added type property to fix TS errors in OfficeSummary.tsx and DocumentFlow.tsx
  type: 'incoming' | 'outgoing'; // document_type в БД
  letterType?: 'email' | 'paper'; // Тип письма: Email или бумага
  assignedTo?: string;
  trackingNumber?: string;
  fileUrl?: string; // URL загруженного файла (скан или текстовый файл)
  notes?: string;
  createdBy: string; // Кто создал/зарегистрировал
  createdAt?: string;
  updatedAt?: string;
}

export interface OfficeAsset {
  id: string;
  name: string;
  type: 'laptop' | 'appliance' | 'furniture' | 'other';
  assignedTo?: string;
  purchaseDate: string;
  condition: 'good' | 'poor' | 'fair';
  serialNumber: string;
  nextMaintenanceDate?: string;
}

export type ContractStatus = 'draft' | 'finance_approval' | 'counterparty_approval' | 'signing' | 'active' | 'archived';

export interface LegalContract {
  id: string;
  number: string;
  type: string;
  counterparty: string;
  counterpartyInn?: string;
  amount: number;
  status: ContractStatus;
  startDate: string;
  endDate: string;
  autoProlongation: boolean;
  manager: string;
  hasDisagreements: boolean;
  contractFileUrl?: string;
  notes?: string;
  createdAt?: string;
  updatedAt?: string;
}

/** Этап ФССП в цепочке взыскания */
export type FsspStage = 'writ_submitted' | 'ip_initiated' | 'bank_requests' | 'money_on_deposit' | 'transferred_to_uk';

export interface LegalCourtCase {
  id: string;
  caseNumber: string;
  type: 'arbitration' | 'civil' | 'debt_recovery';
  role: 'plaintiff' | 'defendant';
  subject: string;
  debtorName?: string;
  address?: string;
  amount: number; // Присужденная сумма
  recoveredAmount?: number; // Реально пришло в УК
  amountAtBailiffs?: number; // Деньги на счетах ФССП
  status: 'pre_trial' | 'litigation' | 'decision_received' | 'enforcement' | 'closed';
  fsspStatus?: string;
  bailiffName?: string;
  fsspLastActionDate?: string;
  nextHearingDate?: string;
  judge?: string;
  /** Номер исполнительного производства */
  enforcementNumber?: string;
  /** Дата возбуждения ИП */
  enforcementStartDate?: string;
  /** Этап ФССП: ИЛ предъявлен → ИП возбуждено → запросы в банки → деньги на депозите → в УК */
  fsspStage?: FsspStage | null;
  /** Сумма пени по делу */
  penaltyAmount?: number;
  /** Дата начала просрочки оплаты */
  overdueSince?: string;
  /** Название суда */
  courtName?: string;
  /** Примечания */
  notes?: string;
  /** Ссылка на материалы дела */
  caseFileUrl?: string;
}

export interface LegalPoA {
  id: string;
  number: string;
  issuedTo: string;
  issueDate: string;
  expiryDate: string;
  status: 'active' | 'expired' | 'revoked';
  authority: string;
}

export interface LegalCounterparty {
  id: string;
  name: string;
  inn: string;
  status: 'active' | 'inactive';
  riskLevel: 'low' | 'medium' | 'high';
  checkedDate: string;
  notes?: string;
}

export type DevPipelineStatus =
  | 'incoming'           // Входящие
  | 'analysis'           // Анализ
  | 'agenda_approval'    // Согласование повестки
  | 'in_person'          // Очная часть
  | 'absentee'           // Заочная часть
  | 'protocol_formation' // Формирование протокола
  | 'protocol_to_gzhi'   // Отправка протокола в ГЖИ
  | 'gzhi_order'        // Приказ ГЖИ
  | 'success'           // Успех
  | 'failure';          // Провал

export interface DevPipelineItem {
  id: string;
  address: string;
  type: 'old' | 'new';
  floors: number;
  area: number;
  apartments: number;
  status: DevPipelineStatus;
  probability: number;
  expectedRevenue: number;
  manager: string;
  buildingId?: string | null;
  notes?: string | null;
}

export interface DevOSSSession {
  id: string;
  buildingId: string;
  address: string;
  startDate: string;
  endDate: string;
  quorumCurrent: number;
  quorumTotal: number;
  status: 'active' | 'planned' | 'completed';
  type: 'annual' | 'extraordinary';
  description?: string | null;
  agendaItems?: string[];
}

/** Статус аудита */
export type DevAuditStatus = 'new' | 'in_progress' | 'completed';

/** Оценка подпункта: 1–5 (1 — худшее, 5 — лучшее). Итог по пункту — среднее арифметическое. */
export type InspectionSubItemRating = number; // 1 | 2 | 3 | 4 | 5

/** Подпункт осмотра (label берётся из справочника по key) */
export interface InspectionSubItem {
  key: string;
  label?: string;
  /** Оценка 1–5; не участвует в среднем при noAccess/notPresent */
  rating: number | null;
  description: string | null;
  noAccess: boolean;
  notPresent: boolean;
}

/** Данные по одному пункту осмотра (категория). overall — среднее по подпунктам (вычисляемое или сохранённое). */
export interface InspectionCategoryData {
  subItems: InspectionSubItem[];
  /** Среднее арифметическое оценок подпунктов (1–5), вычисляется из subItems */
  overall?: number | null;
}

/** Ключи пунктов осмотра: кровля, фасад, подъезды, инфраструктура, придомовой участок */
export type InspectionCategoryKey = 'roof' | 'facade' | 'entrances' | 'infrastructure' | 'yard';

/** Данные осмотра по всем пунктам */
export type InspectionData = Partial<Record<InspectionCategoryKey, InspectionCategoryData>>;

export interface DevAuditData {
  id: string;
  buildingId: string;
  address: string;
  status: DevAuditStatus;
  wearPercent: number;
  roofCondition: 'good' | 'poor' | 'fair';
  basementCondition: 'good' | 'poor' | 'fair';
  calculatedTariff: number;
  projectedMargin: number;
  complexityIndex: number | null;
  inspectionData: InspectionData | null;
  auditDate?: string;
  auditorName?: string | null;
  notes?: string | null;
}

export interface DevMarketingActivity {
  id: string;
  buildingId: string;
  address: string;
  activistsCount: number;
  meetingsHeld: number;
  adsDistributed: number;
  competitor: string;
  status: 'voting' | 'my_house' | 'competitor_house';
}

export interface MeterReading {
  date: string;
  value: number;
  consumption: number;
  source: 'app' | 'manual' | 'iot';
}

export interface AccountMeter {
  id: string;
  type: 'ХВС' | 'ГВС' | 'Э/Э' | 'Газ' | 'Other';
  make: string;
  number: string;
  name?: string; // Название прибора (для кастомных)
  manufacturer?: string; // Производитель
  installDate?: string; // Дата установки
  lastVerification: string;
  nextVerification: string;
  currentReading?: number; // Текущее показание
  unit?: string; // Единица измерения (м³, кВт⋅ч и т.д.)
  readings: MeterReading[];
  documents?: string[]; // Файлы документов (паспорт, акты поверки и т.д.)
  notes?: string; // Примечания
}

export interface ResidentProfile {
  sentiment: 'negative' | 'toxic' | 'positive' | 'loyal' | 'neutral';
  birthday?: string; // ISO date string (YYYY-MM-DD)
  notes?: string;
  preferredContactMethod?: 'phone' | 'email' | 'chat' | 'in_person';
  email?: string;
  lastInteractionDate?: string; // ISO date string
  specialNeeds?: string[];
  paymentHistory?: {
    onTime: number;
    late: number;
    averageDelayDays: number;
  };
}

export interface RegisteredPerson {
  id: string;
  fullName: string;
  phone?: string;
  email?: string;
  residentProfile?: ResidentProfile; // Портрет клиента для каждого прописанного
}

export interface PersonalAccount {
  id: string;
  accountNumber: string;
  apartmentNumber: string;
  type: 'apartment' | 'parking' | 'storage' | 'office';
  floor: number;
  entranceNumber?: number; // Номер подъезда (если известен)
  owners: { 
    fullName: string, 
    phone: string;
    residentProfile?: ResidentProfile; // Портрет клиента для собственника
  }[];
  registered: RegisteredPerson[]; // Прописанные с их данными и портретами
  areaTotal: number;
  areaLiving: number;
  areaNonLiving: number;
  meters: AccountMeter[];
  isMeterInstallationFeasible: boolean;
  surveyActNumber?: string;
  surveyActDate?: string;
  premiseNotes?: string; // Примечания по помещению (ремонты, особенности, проблемы и т.д.)
}

export interface Debtor {
  apartment: string;
  amount: number;
  months: number;
  status: 'new' | 'pending' | 'legal';
}

// ========= ЮРИДИЧЕСКИЙ ОТДЕЛ: ДОСУДЕБНАЯ РАБОТА =========

export interface LegalDebtor {
  id: number;
  buildingId: string;
  apartment: string;
  debtorName?: string;
  phone?: string;
  email?: string;
  address: string;
  debtAmount: number;
  debtMonths: number;
  status: 'new' | 'in_progress' | 'promised_payment' | 'transferred_to_court' | 'resolved';
  transferredFromFinance: boolean;
  createdAt: string;
  updatedAt: string;
}

export interface PreTrialWork {
  id: number;
  debtorId: number;
  assignedTo?: string;
  status: 'new' | 'in_progress' | 'promised_payment' | 'transferred_to_court' | 'resolved';
  promisedPaymentDate?: string;
  promisedPaymentAmount?: number;
  transferredToCourt: boolean;
  courtCaseId?: string;
  notes?: string;
  createdAt: string;
  updatedAt: string;
  debtor?: LegalDebtor;
  actions?: PreTrialAction[];
  promisedPayments?: PromisedPayment[];
}

export interface PreTrialAction {
  id: number;
  workId: number;
  actionType: 'call' | 'letter' | 'visit';
  actionDate: string;
  performedBy: string;
  result?: string;
  notes?: string;
  attachments?: string[];
  createdAt: string;
}

export interface PromisedPayment {
  id: number;
  workId: number;
  promisedDate: string;
  promisedAmount: number;
  actualPaymentDate?: string;
  actualPaymentAmount?: number;
  isPaid: boolean;
  reminderSent: boolean;
  reminderDate?: string;
  notes?: string;
  createdAt: string;
  updatedAt: string;
}

export type InvoiceStatus = 'draft' | 'pending_approval' | 'approved' | 'scheduled' | 'paid' | 'rejected' | 'overdue' | 'clarification';

export interface Invoice {
  id: string;
  buildingId: string;
  address: string;
  contractorName: string;
  serviceName: string;
  amount: number;
  date: string; 
  paymentDeadline?: string;
  scheduledDate?: string;
  status: InvoiceStatus;
  priority: 'low' | 'medium' | 'high';
  closingDocsReceived: boolean;
  paymentRef?: string;
}

// Типы для новой системы счетов на оплату
export type PaymentInvoiceStatus = 
  | 'draft' 
  | 'pending_manager_approval' 
  | 'pending_finance_manager_approval' 
  | 'approved' 
  | 'scheduled' 
  | 'paid' 
  | 'postponed'
  | 'cancelled'
  | 'rejected'
  | 'completed';

export type PaymentInvoicePurposeType = 'building' | 'district' | 'legal' | 'office' | 'hr' | 'other' | 'event';
export type PaymentInvoiceFormat = 'prepayment' | 'postpayment' | 'advance';
export type DistributionMethod = 'equal' | 'by_area' | 'manual';
export type PaymentInvoiceItemType = 'service' | 'materials';

export interface ApprovalHistoryEntry {
  userId: string;
  userRole: string;
  action: 'approve' | 'reject' | 'revision';
  comment?: string;
  date: string;
}

// Элемент услуги в счете
export interface ServiceItem {
  name: string; // Название услуги
  amount: number; // Сумма за услугу
}

// Элемент ТМЦ в счете
export interface MaterialItem {
  name: string; // Наименование ТМЦ
  quantity: number; // Количество
  unit: string; // Единица измерения (шт, кг, м и т.д.)
  pricePerUnit: number; // Цена за единицу
  amount: number; // Сумма (quantity * pricePerUnit)
}

export interface PaymentInvoice {
  id: number;
  invoiceNumber: string;
  createdBy: string;
  createdAt: string;
  updatedAt: string;
  purposeType: PaymentInvoicePurposeType;
  purposeBuildingIds: string[];
  purposeDistrictIds: string[];
  purposeDescription?: string;
  purposeEventId?: number | null; // ID мероприятия (pr_events), если purposeType = 'event'
  /** Пункт плана работ (Участки → Дом → План работ). Связь план/факт. */
  planItemId?: string | null;
  planItemBuildingId?: string | null;
  paymentFormat: PaymentInvoiceFormat;
  itemType: PaymentInvoiceItemType; // Услуга или ТМЦ
  contractorName: string;
  contractorInn?: string;
  serviceDescription: string; // Описание услуги или ТМЦ (для обратной совместимости)
  serviceItems?: ServiceItem[]; // Список услуг (если itemType = 'service')
  materialItems?: MaterialItem[]; // Список ТМЦ (если itemType = 'materials')
  totalAmount: number;
  distributionMethod?: DistributionMethod;
  distributionData: Record<string, any>;
  status: PaymentInvoiceStatus;
  currentApproverRole?: string;
  approvalHistory: ApprovalHistoryEntry[];
  rejectionReason?: string;
  scheduledDate?: string;
  paymentDate?: string;
  /** Номер платежного поручения / платежки */
  paymentRef?: string | null;
  /** Оплата наличными */
  isCash?: boolean;
  /** Дата переноса (при отложении) */
  postponedDate?: string | null;
  /** Причина отмены */
  cancelReason?: string | null;
  isCompleted: boolean;
  closingDocsReceived: boolean;
  closingDocsFiles?: any[];
  notes?: string;
  fileUrls: string[];
}

// Платежный календарь: типы записей
export type PaymentType = 'invoice' | 'manual' | 'cash';
export type PaymentDirection = 'outgoing' | 'incoming';
export type PaymentProbability = 'confirmed' | 'high' | 'medium' | 'low';

export interface PaymentCalendarEntry {
  id: number;
  direction: PaymentDirection;
  type: PaymentType;
  paymentInvoiceId?: number | null;
  category: string;
  description: string;
  amount: number;
  scheduledDate: string;
  paymentDate?: string | null;
  probability: PaymentProbability;
  currency: string;
  isCash: boolean;
  contractorName: string;
  notes?: string | null;
  createdAt: string;
  updatedAt: string;
  createdBy?: string;
}

/** Статья доходов/расходов (справочник) */
export interface PaymentCategory {
  id: number;
  name: string;
  code?: string | null;
  direction: 'income' | 'expense';
  parentId?: number | null;
  isActive: boolean;
  sortOrder?: number;
}

/** Банковский счёт или кошелёк (наличка) для календаря оплат */
export interface FinanceAccount {
  id: number;
  type: 'bank' | 'cash';
  name: string;
  balance: number;
  currency: string;
  sortOrder?: number;
}

export interface ApproverUserRole {
  id: number;
  userId: string;
  role: 'manager' | 'finance_manager' | 'financier' | 'finance_director' | 'director' | 'top_management';
  createdAt: string;
}

export interface BuildingFinancials {
  balance: number;
  debt: number;
  collectionRate: number;
  topDebtors: Debtor[];
  invoices: Invoice[];
}

export interface PassportMeter {
  id?: string; // Уникальный ID прибора
  resource: 'Heat' | 'Water' | 'Electricity' | 'Gas' | 'Other';
  hasMeter: boolean;
  name?: string; // Название прибора (для кастомных)
  model?: string;
  number?: string;
  manufacturer?: string; // Производитель
  installDate?: string; // Дата установки
  lastVerification?: string; // Дата последней поверки
  nextVerification?: string; // Дата следующей поверки
  currentReading?: number; // Текущее показание
  unit?: string; // Единица измерения (Гкал, м³, кВт⋅ч и т.д.)
  readings?: MeterReading[]; // История показаний
  documents?: string[]; // Файлы документов (паспорт, акты поверки и т.д.)
  notes?: string; // Примечания
}

export interface PassportServiceContract {
  id: string;
  serviceType: string;
  providerName: string;
  contractNumber: string;
  contractDate: string;
  expiryDate?: string;
}

export interface EntranceSection {
  id: string;
  title: string;
  elements: {
    id: string;
    name: string;
    generalStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL';
    electroStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL';
    weldingStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL';
  }[];
}

export interface PlanItem {
  id: string;
  year: number;
  month: string;
  workName: string;
  status: 'current' | 'future' | 'completed' | 'carried_over';
  progress: number;
  estimatedCost: number;
  actualCost?: number;
  originalYear?: number;
  postponeReason?: string;
  carryOverReason?: string;
  sourceInspectionId?: string;
  sourceElementId?: string;
  sourceSectionTitle?: string;
  /** Силами УК (без бюджета подрядчика) */
  byManagement?: boolean;
  /** ID счетов на оплату, привязанных к этой работе (план/факт) */
  linkedInvoiceIds?: number[];
}

export interface BuildingInventoryItem {
  id: string;
  name: string;
  category: 'tool' | 'material' | 'door' | 'consumable';
  quantity: number;
  unit: string;
  lastCheck: string;
  source?: 'district' | 'invoice'; // Откуда взята позиция: со склада участка или из счета
  unitPrice?: number; // Цена за единицу товара (стоимость / количество)
  totalAmount?: number; // Общая стоимость товара (которую должны получить/заплатили)
}

// Акт списания товаров со склада
export interface WriteOffAct {
  id: string;
  date: string; // Дата списания (ISO date string)
  items: WriteOffItem[]; // Список списанных позиций
  totalAmount: number; // Общая сумма списания
  performer: string; // Кто выполнил списание
  reason?: string; // Причина списания (общая для всех позиций)
}

// Позиция в акте списания
export interface WriteOffItem {
  itemId: string; // ID позиции в инвентаре
  name: string; // Наименование товара
  quantity: number; // Количество списанных единиц
  unit: string; // Единица измерения
  unitPrice: number; // Цена за единицу на момент списания
  amount: number; // Сумма списания (quantity * unitPrice)
  reason?: string; // Причина списания для этой позиции
}

export interface InspectionItem {
  id: string;
  category: 'structural' | 'engineering';
  label: string;
  status: 'ok' | 'repair_needed' | 'not_checked';
  description?: string;
  wearPercent?: number;
  photos?: string[];
}

// Элемент МКД для детального осмотра (как в БИСРИК)
export interface InspectionMKDElement {
  id: string;
  name: string; // Название элемента (например, "Напольное покрытие", "Освещение")
  generalStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL'; // Общий строй
  electroStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL'; // Электроснабжение
  weldingStatus: 'NOT_SELECTED' | 'OK' | 'WARNING' | 'CRITICAL'; // Слесарные, сварочные работы
  repairType?: string; // Вид требуемого ремонта
  mainPhoto?: string; // Гл. фото
  additionalPhotos?: string[]; // Доп. фото
}

// Секция осмотра (подъезд, этаж, лифт и т.д.)
export interface InspectionSection {
  id: string;
  type: 'entrance' | 'floor' | 'lift' | 'common'; // Тип секции
  number?: number; // Номер подъезда/этажа/лифта
  title: string; // Название секции
  elements: InspectionMKDElement[]; // Элементы МКД в этой секции
  isCollapsed?: boolean; // Свернута ли секция
}

// Общая секция (кровля, подвал, фасад и т.д.)
export interface InspectionCommonSection {
  id: string;
  title: string; // "Кровля", "Подвал", "Фундамент" и т.д.
  elements: InspectionMKDElement[];
  isCollapsed?: boolean;
}

export interface InspectionAct {
  id: string;
  number: string;
  date: string;
  inspector: string;
  type: 'scheduled_spring' | 'scheduled_autumn' | 'emergency' | 'acceptance';
  status: 'draft' | 'completed';
  issuesCount: number;
  checklist?: InspectionItem[]; // Старый формат (для обратной совместимости)
  // Новый формат с динамическими секциями
  sections?: InspectionSection[]; // Подъезды, этажи, лифты
  commonSections?: InspectionCommonSection[]; // Общие секции (кровля, подвал и т.д.)
  basis?: string;
  commissionMembers?: string;
  ownerRepresentative?: string;
  geolocation?: { lat: number, lng: number, timestamp: string };
  signatureUrl?: string;
  workCategory?: 'maintenance' | 'capital' | 'emergency';
  isReadyForWinter?: boolean;
}

export interface MeterCheckRound {
  id: string;
  date: string;
  inspector: string;
  status: 'active' | 'completed';
  buildingId: string;
  roundType: 'odpu' | 'apartments' | 'all'; // Тип обхода: только ОДПУ, только квартиры, или все
  // Фильтры для обхода
  selectedEntrances?: number[]; // Выбранные подъезды (если пусто - все)
  selectedFloors?: number[]; // Выбранные этажи (если пусто - все)
  apartments?: {
    apartmentNumber: string;
    entranceNumber?: number; // Номер подъезда
    floor?: number; // Этаж
    status: 'pending' | 'verified' | 'no_access';
    checkedAt?: string;
    readings: {
      meterId: string;
      meterType: string;
      previousValue: number;
      currentValue?: number;
    }[];
  }[];
  odpuMeters?: {
    meterId: string;
    meterIndex: number; // Индекс в массиве meters
    meterType: string;
    meterName: string;
    previousValue: number;
    currentValue?: number;
    status: 'pending' | 'verified' | 'no_access';
    checkedAt?: string;
  }[];
}

// Комментарий к задаче
export interface TaskComment {
  id: string;
  authorId?: string;
  authorName: string;
  text: string;
  createdAt: string; // ISO date string
}

export interface BuildingTask {
  id: string;
  title: string;
  description?: string;
  deadline: string; // ISO date string
  status: 'new' | 'in_progress' | 'done' | 'cancelled';
  priority: 'low' | 'medium' | 'high' | 'urgent';
  assignedTo?: string; // ID или имя ответственного
  assignedToName?: string; // Имя ответственного для отображения
  createdAt: string; // ISO date string
  updatedAt: string; // ISO date string
  createdBy?: string; // ID создателя (постановщик)
  createdByName?: string; // Имя постановщика для отображения
  category?: string; // Категория задачи
  tags?: string[]; // Теги
  estimatedHours?: number; // Оценка времени в часах
  actualHours?: number; // Фактически потраченное время
  buildingId: string; // ID дома (пустая строка — общая задача)
  buildingAddress?: string; // Адрес дома для отображения в сводке
  comments?: TaskComment[]; // Комментарии
  requirePhotoReport?: boolean; // Требуется фото отчёт до/после (по умолчанию true)
  photoReportId?: number; // ID записи work_photos, привязанной к задаче
  /** Соисполнители (ID пользователей) */
  coAssignees?: string[];
  coAssigneesNames?: string[];
  /** Наблюдатели (ID пользователей) */
  observers?: string[];
  observersNames?: string[];
}

export interface Building {
  id: string;
  districtId: string;
  imageUrl: string;
  nps: number;
  passport: {
    address: string;
    apartmentsCount: number;
    general: {
      address: string;
      fiasCode: string;
      constructionYear: number;
      commissionYear: number;
      seriesType: string;
      floors: number;
      undergroundFloors: number;
      totalArea: number;
      livingArea: number;
      nonLivingArea: number;
      commonArea: number;
      cadastralNumberBuild: string;
      cadastralNumberLand: string;
      lastRepairYear?: number;
      // Новые поля
      entrancesCount?: number; // Кол-во подъездов
      hasDifferentFloors?: boolean; // Разноэтажность
      officesCount?: number; // Кол-во офисов
      // Вычисляемые поля (будут считаться из accounts)
      residentialAccountsCount?: number; // Кол-во жилых лицевых счетов
      nonResidentialAccountsCount?: number; // Кол-во нежилых лицевых счетов
      officesAccountsCount?: number; // Кол-во офисов (из лицевых счетов)
      apartmentsCount?: number; // Кол-во квартир (из лицевых счетов)
      nonLivingCommonArea?: number; // Площадь нежилых помещений в составе ОДИ
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
    construction: {
      foundationType: string;
      foundationMaterial: string;
      wallMaterial: string;
      floorMaterial: string;
      roofType: string;
      roofMaterial: string;
      roofArea: number;
      facadeType: string;
      facadeInsulation: boolean;
      windowType: string;
      // Новые поля
      wearPercent?: number; // Процент износа
      hasBasement?: boolean; // Подвал
      hasTechFloor?: boolean; // Тех этаж
      hasAttic?: boolean; // Чердак
      hasBasementFloor?: boolean; // Цоколь
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
    engineering: {
      heatingType: string;
      heatingWiring: string;
      hasITP: boolean;
      waterSupplyMaterial: string;
      waterSupplyType: string;
      sewerMaterial: string;
      electricityEntries: number;
      hasVRU: boolean;
      gasType: string;
      ventilationType: string;
      // Процент износа для каждой системы
      heatingWearPercent?: number;
      waterSupplyWearPercent?: number;
      sewerWearPercent?: number;
      electricityWearPercent?: number;
      gasWearPercent?: number;
      ventilationWearPercent?: number;
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
    odpu: {
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
    meters: PassportMeter[];
    lifts: {
      count: number;
      type: string;
      capacity: number;
      speed: number;
      installYear: number;
      factoryNumber: string;
      // Новые поля
      manufacturer?: string; // Производитель
      lastMaintenanceDate?: string; // Дата последнего обслуживания
      nextMaintenanceDate?: string; // Дата следующего обслуживания
      wearPercent?: number; // Процент износа
      status?: string; // Статус (работает, на ремонте и т.д.)
      documents?: string[]; // Файлы документов
      // Дополнительные поля
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    }[];
    land: {
      area: number;
      hasPlayground: boolean;
      hasSportsGround: boolean;
      hasParking: boolean;
      hasFencing: boolean;
      hasContainerSite: boolean;
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
    management: {
      contractDate: string;
      contractNumber: string;
      servicesList: string[];
      tariffMaintenance: number;
      reserveFund?: number; // Резервный фонд (%)
      serviceContracts: PassportServiceContract[];
      // Дополнительные поля для файлов
      customFields?: { [key: string]: { value: any; type: string; files?: string[] } };
    };
  };
  staff: { id: string, role: string, company: string, name: string }[];
  entrances: {
    id: string;
    number: number;
    floors: number;
    liftsCount: number;
    hasBasement: 'NOT_SELECTED' | 'YES' | 'NO';
    hasTechFloor: 'NOT_SELECTED' | 'YES' | 'NO';
    hasAttic: 'NOT_SELECTED' | 'YES' | 'NO';
    hasParking: 'NOT_SELECTED' | 'YES' | 'NO';
    hasMansard: 'NOT_SELECTED' | 'YES' | 'NO';
    entranceGroupsCount: number;
    sections: EntranceSection[];
    // Технические характеристики подъезда (сохраняются после первого обхода)
    technicalCharacteristics?: {
      hasBasement?: 'NOT_SELECTED' | 'YES' | 'NO';
      hasTechFloor?: 'NOT_SELECTED' | 'YES' | 'NO';
      hasParking?: 'NOT_SELECTED' | 'YES' | 'NO';
      hasAttic?: 'NOT_SELECTED' | 'YES' | 'NO';
      floorsCount?: number; // Количество этажей в подъезде
      liftsCount?: number; // Количество лифтов в подъезде
      hasMansard?: 'NOT_SELECTED' | 'YES' | 'NO';
      entranceGroupsCount?: number; // Количество входных групп
    };
    // Элементы МКД по этажам (сохраняются после первого обхода)
    floorElements?: {
      [floorNumber: number]: InspectionMKDElement[]; // Элементы МКД для каждого этажа
    };
  }[];
  commonSections: EntranceSection[];
  accounts: PersonalAccount[];
  financials: BuildingFinancials;
  requests: { new: number, inProgress: number, overdue: number };
  inspectionHistory: InspectionAct[];
  tasks: BuildingTask[];
  annualPlan: PlanItem[];
  inventory: BuildingInventoryItem[];
  writeOffHistory: WriteOffAct[];
  residents: { id: string, name: string, role: string, apartment: string, mood: string, lastContact: string }[];
  reports: { id: string, month: string, status: string }[];
  isDirty: boolean;
  meterCheckRounds?: MeterCheckRound[];
}

// ========= ФИНАНСОВЫЕ ДАННЫЕ ИЗ 1С =========

export interface FinancialReport {
  id: number;
  filename: string;
  fileType: 'CSV' | 'XLSX';
  reportType?: 'debtors' | 'balance_sheet' | 'balance_sheet_76' | 'other';
  uploadedAt: string;
  uploadedBy?: string;
  status: 'processing' | 'completed' | 'failed' | 'partial';
  totalRows?: number;
  processedRows: number;
  errorRows: number;
  errorLog?: any;
  mappingId?: number;
}

export interface FinancialReportMapping {
  id: number;
  name: string;
  description?: string;
  isDefault: boolean;
  columnMappings: Record<string, string>; // { "source_column": "target_field" }
  createdAt: string;
  updatedAt: string;
}

export interface BuildingFinancialData {
  id: number;
  buildingId: string;
  reportId?: number;
  periodStart: string; // ISO date
  periodEnd: string; // ISO date
  periodType: 'month' | 'quarter' | 'year';
  totalIncome: number;
  incomeByItems: Record<string, number>;
  totalExpenses: number;
  expensesByItems: Record<string, number>;
  balance: number;
  metadata?: any;
  createdAt: string;
  updatedAt: string;
}

export interface ProcessingJob {
  jobId: string;
  status: 'pending' | 'processing' | 'completed' | 'failed';
  progress: number; // 0-100
  currentStep?: string;
  errors: ProcessingError[];
  warnings: string[];
  result?: {
    totalRows: number;
    processedRows: number;
    errorRows: number;
    buildingsFound: number;
  };
}

export interface ProcessingError {
  row: number;
  column?: string;
  message: string;
  suggestion?: string;
  data?: any;
}

// ========= ОФИС: ЗАЯВКИ НА РЕМОНТ ТЕХНИКИ =========

export type OfficeEquipmentType = 'pc' | 'laptop' | 'air_conditioner' | 'printer' | 'other';
export type RepairRequestStatus =
  | 'new'
  | 'search_contractor'      // Поиск подрядчика
  | 'agreed_with_contractor' // Договорились с подрядчиком
  | 'waiting_delivery'       // Ожидание поставки
  | 'taken_for_repair'       // Увезли на ремонт
  | 'self_repair'            // Ремонт самостоятельно
  | 'in_progress'            // В работе
  | 'completed'              // Выполнена
  | 'canceled';              // Отменена

export interface OfficeEquipment {
  id: number;
  name: string;
  type: OfficeEquipmentType;
  brand?: string;
  model?: string;
  serialNumber?: string;
  assignedTo?: string;
  purchaseDate?: string;
  warrantyUntil?: string;
  condition: 'good' | 'fair' | 'poor';
  notes?: string;
  createdAt: string;
  updatedAt: string;
}

export type OfficeEquipmentHistoryType = 'purchase' | 'issue' | 'transfer' | 'repair' | 'write_off';

export interface OfficeEquipmentHistoryItem {
  id: number | string;
  equipment_id: number;
  event_type: OfficeEquipmentHistoryType;
  event_date: string;
  assigned_to?: string;
  assigned_from?: string;
  reason?: string;
  created_at: string;
}

export interface OfficeRepairRequest {
  id: number;
  equipmentId: number;
  equipment?: OfficeEquipment;
  requesterName: string;
  description: string;
  priority: 'low' | 'medium' | 'high' | 'urgent';
  status: RepairRequestStatus;
  assignedTo?: string;
  createdAt: string;
  startedAt?: string;
  completedAt?: string;
  canceledAt?: string;
  cancelReason?: string;
  expectedReturnDate?: string; // Ожидаемая дата возврата из ремонта
  waitingDeliveryDeadline?: string;   // Примерный срок при ожидание поставки
  waitingDeliveryContacts?: string;  // Контакты для уточнения поставки
  takenForRepairDeadline?: string;    // Срок при увезли на ремонт
  takenForRepairContacts?: string;    // Контакты при увезли на ремонт
  agreedContractorPrice?: number;     // Цена при договорились с подрядчиком
  solution?: string;
  attachments?: string[];
  comments?: Array<{
    author: string;
    text: string;
    createdAt: string;
  }>;
  isPaid?: boolean; // Платный ремонт
  cost?: number; // Стоимость ремонта
  costEstimated?: boolean; // Стоимость предварительная (требуется диагностика)
  invoiceId?: number; // ID счета на оплату
  invoiceUrl?: string; // Ссылка на счет
}

// ========= ОФИС: БАЗА ЗНАНИЙ =========

export interface KnowledgeBaseCategory {
  id: number;
  name: string;
  slug: string;
  parentId?: number;
  parent?: KnowledgeBaseCategory;
  description?: string;
  icon?: string;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
  children?: KnowledgeBaseCategory[];
}

export interface KnowledgeBaseArticle {
  id: number;
  title: string;
  slug: string;
  categoryId?: number;
  category?: KnowledgeBaseCategory;
  content: string;
  contentType: 'markdown' | 'html';
  author: string;
  version: number;
  parentVersionId?: number;
  isPublished: boolean;
  tags?: string[];
  attachments?: string[];
  viewCount: number;
  createdAt: string;
  updatedAt: string;
  publishedAt?: string;
}

// ========= ОФИС: СОВЕЩАНИЯ И ПЕРЕГОВОРНЫЕ =========

export interface MeetingRoom {
  id: number;
  name: string;
  capacity: number;
  location?: string;
  equipment?: string[]; // ['projector', 'whiteboard', 'video_conference']
  description?: string;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
}

export type MeetingStatus = 'scheduled' | 'in_progress' | 'completed' | 'canceled';

export interface Meeting {
  id: number;
  title: string;
  description?: string;
  organizer: string;
  startTime: string; // ISO datetime
  endTime: string; // ISO datetime
  roomId?: number;
  room?: MeetingRoom;
  participants: string[];
  agenda?: string;
  notes?: string;
  conclusions?: string; // Заключения совещания
  status: MeetingStatus;
  reminderSent: boolean;
  reminderTime?: string;
  attachments?: string[];
  createdAt: string;
  updatedAt: string;
}

export type MeetingBookingStatus = 'active' | 'completed' | 'canceled';

export interface MeetingBooking {
  id: number;
  roomId: number;
  room?: MeetingRoom;
  meetingId?: number;
  meeting?: Meeting;
  bookedBy: string;
  startTime: string; // ISO datetime
  endTime: string; // ISO datetime
  purpose?: string;
  status: MeetingBookingStatus;
  createdAt: string;
  updatedAt: string;
}