import { randomUUID } from 'crypto';
import type { CreateDocumentBody, DocumentRecord, DocumentType, UpdateDocumentBody } from './documents.types';
import { DocumentsRepository } from '../data/documents.repository';
import pool from '../../../core/config/database';

export class DocumentsService {
  private readonly repo = new DocumentsRepository(pool);

  async createDocument(userId: string, body: CreateDocumentBody): Promise<DocumentRecord> {
    await this.assertVehicleOwnership(userId, body.vehicleId);
    const id = randomUUID();
    return this.repo.insert({
      id,
      userId,
      vehicleId: body.vehicleId,
      documentType: body.documentType as DocumentType,
      title: body.title,
      notes: body.notes ?? null,
      details: body.details ?? null,
      issuedDate: body.issuedDate ?? null,
      expirationDate: body.expirationDate ?? null,
      emailNotifications: body.emailNotifications ?? false,
      scanForMaintenance: body.scanForMaintenance ?? false,
    });
  }

  async getDocument(userId: string, id: string): Promise<DocumentRecord | null> {
    return this.repo.findById(id, userId);
  }

  async listDocuments(userId: string, filters?: { vehicleId?: string; type?: DocumentType; expiresBefore?: string }) {
    return this.repo.listByUser(userId, filters);
  }

  async updateDocument(userId: string, id: string, patch: UpdateDocumentBody) {
    const existing = await this.repo.findById(id, userId);
    if (!existing) return null;
    if (patch && typeof patch === 'object') {
      return this.repo.updateMetadata(id, userId, patch as any);
    }
    return existing;
  }

  async deleteDocument(userId: string, id: string): Promise<void> {
    await this.repo.softDelete(id, userId);
  }

  private async assertVehicleOwnership(userId: string, vehicleId: string) {
    const res = await pool.query('SELECT id FROM vehicles WHERE id = $1 AND user_id = $2', [vehicleId, userId]);
    if (!res.rows[0]) {
      const err: any = new Error('Vehicle not found or not owned by user');
      err.statusCode = 403;
      throw err;
    }
  }
}

