// src/server/features/reference_books/lib/contractors.mapper.ts
// Mapper functions for transforming database rows to DTOs

import type { ContractorEntryWithMetadata, ContractorPendingEntry } from '../contractors.schema';
import type { contractorsPending, contractors } from '../db/contractors.table';
import type { employees } from '@features/personnel/db/employees.table';

type ResponsibleManager = {
  name: string;
  phone: string | null;
  email: string | null;
};

function parseResponsibleManagers(
  raw: unknown,
  legacyManagerName: string | null,
  legacyManagerPhone: string | null,
  legacyManagerEmail: string | null,
): ResponsibleManager[] {
  if (Array.isArray(raw)) {
    return raw
      .filter((item) => item && typeof item === 'object')
      .map((item) => {
        const candidate = item as Record<string, unknown>;
        return {
          name: typeof candidate.name === 'string' ? candidate.name.trim() : '',
          phone: typeof candidate.phone === 'string' ? candidate.phone.trim() || null : null,
          email: typeof candidate.email === 'string' ? candidate.email.trim() || null : null,
        };
      })
      .filter((item) => item.name.length > 0);
  }

  if (legacyManagerName && legacyManagerName.trim()) {
    return [{
      name: legacyManagerName.trim(),
      phone: legacyManagerPhone?.trim() || null,
      email: legacyManagerEmail?.trim() || null,
    }];
  }

  return [];
}

/**
 * Map database row to ContractorEntryWithMetadata
 */
export function mapToContractorEntry(row: typeof contractors.$inferSelect): ContractorEntryWithMetadata {
  const responsibleManagers = parseResponsibleManagers(
    row.responsibleManagers,
    row.managerName,
    row.managerPhone,
    row.managerEmail,
  );

  return {
    id: row.id,
    name: row.name,
    category: row.category,
    contractNumber: row.contractNumber,
    phone: row.phone,
    email: row.email,
    webLink: row.webLink,
    responsibleManagers,
    managerName: row.managerName,
    managerPhone: row.managerPhone,
    managerEmail: row.managerEmail,
    comment: row.comment,
    isApproved: row.isApproved,
    status: row.isApproved ? 'approved' : 'pending',
    targetId: null,
    createdBy: null,
    creatorName: null,
    reviewedBy: null,
    reviewedAt: null,
    rejectionReason: null,
    createdAt: row.createdAt.toISOString(),
    updatedAt: row.updatedAt.toISOString(),
    archivedAt: row.archivedAt?.toISOString() || null,
  };
}

/**
 * Map database row to ContractorPendingEntry
 */
export function mapToContractorPendingEntry(row: typeof contractorsPending.$inferSelect & { creatorName?: string | null }): ContractorPendingEntry {
  const responsibleManagers = parseResponsibleManagers(
    row.responsibleManagers,
    row.managerName,
    row.managerPhone,
    row.managerEmail,
  );

  return {
    id: row.id,
    name: row.name,
    category: row.category,
    contractNumber: row.contractNumber,
    phone: row.phone,
    email: row.email,
    webLink: row.webLink,
    responsibleManagers,
    managerName: row.managerName,
    managerPhone: row.managerPhone,
    managerEmail: row.managerEmail,
    comment: row.comment,
    status: row.status as 'pending' | 'approved' | 'rejected' | 'to_delete',
    targetId: row.targetId,
    createdBy: row.createdBy,
    creatorName: row.creatorName || null,
    reviewedBy: row.reviewedBy,
    reviewedAt: row.reviewedAt?.toISOString() || null,
    rejectionReason: row.rejectionReason,
    createdAt: row.createdAt.toISOString(),
    updatedAt: row.updatedAt.toISOString(),
  };
}

/**
 * Map pending entry with metadata (includes creatorName from join)
 */
export function mapPendingToContractorEntryWithMetadata(row: typeof contractorsPending.$inferSelect & { creatorName?: string | null }): ContractorEntryWithMetadata {
  const responsibleManagers = parseResponsibleManagers(
    row.responsibleManagers,
    row.managerName,
    row.managerPhone,
    row.managerEmail,
  );

  return {
    id: row.id,
    name: row.name,
    category: row.category,
    contractNumber: row.contractNumber,
    phone: row.phone,
    email: row.email,
    webLink: row.webLink,
    responsibleManagers,
    managerName: row.managerName,
    managerPhone: row.managerPhone,
    managerEmail: row.managerEmail,
    comment: row.comment,
    isApproved: false, // Pending entries are not approved
    status: row.status as 'pending' | 'approved' | 'rejected' | 'to_delete',
    targetId: row.targetId,
    createdBy: row.createdBy,
    creatorName: row.creatorName || null,
    reviewedBy: row.reviewedBy,
    reviewedAt: row.reviewedAt?.toISOString() || null,
    rejectionReason: row.rejectionReason,
    createdAt: row.createdAt.toISOString(),
    updatedAt: row.updatedAt.toISOString(),
    archivedAt: null, // Pending entries don't have archivedAt
  };
}
