import { adapters, migrationFields, newUuid } from '@/services/serviceConfig';
import { auditService } from '@/services/auditService';
import { MANUFACTURER_SPEC_FIELDS } from '@/services/dimensionDefinitions';

const today = () => new Date().toISOString().slice(0, 10);

export const dimensionService = {
  dimensions: (componentUuid) => adapters.database.filter('ComponentDimension', { component_uuid: componentUuid }),
  specs: (componentUuid) => adapters.database.filter('ComponentSpec', { component_uuid: componentUuid }),
  stations: (componentUuid) => adapters.database.filter('EnvelopeStation', { component_uuid: componentUuid }),
  accessPoints: (componentUuid) => adapters.database.filter('AccessPoint', { component_uuid: componentUuid }),
  keepOutZones: (componentUuid) => adapters.database.filter('KeepOutZone', { component_uuid: componentUuid }),
  movementPositions: (componentUuid) => adapters.database.filter('MovementPosition', { component_uuid: componentUuid }),
  assemblyComponents: (projectUuid) => adapters.database.filter('AssemblyComponent', { project_uuid: projectUuid }),
  componentAssembly: (componentUuid) => adapters.database.filter('AssemblyComponent', { component_uuid: componentUuid }),

  async saveDimension(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const value_mm = portable.entered_unit === 'cm' && portable.original_value != null ? Number(portable.original_value) * 10 : portable.value_mm;
    const existing = (await adapters.database.filter('ComponentDimension', { component_uuid: portable.component_uuid, dimension_key: portable.dimension_key, record_state: 'active' }, '-updated_date', 50))
      .filter(d => d.session_uuid === (portable.session_uuid || null) || !d.session_uuid);
    const payload = { ...portable, value_mm, date_entered: portable.date_entered || today(), updated_by_name: actor };
    let saved;
    if (existing[0]?.id) { saved = await adapters.database.update('ComponentDimension', existing[0].id, payload); }
    else { saved = await adapters.database.create('ComponentDimension', { ...payload, uuid: newUuid('dim'), ...migrationFields(actor) }); }
    await auditService.record('dimension_saved', 'ComponentDimension', saved.uuid, `Saved ${portable.dimension_name}`, actor, payload.warning || '');
    return saved;
  },

  async importSpec(component, specData, actor) {
    const spec = await adapters.database.create('ComponentSpec', {
      ...specData, uuid: newUuid('spec'), component_uuid: component.uuid,
      date_imported: today(), imported_by: actor, is_official_source: specData.is_official_source ?? true,
      ...migrationFields(actor),
    });
    for (const [key, label] of MANUFACTURER_SPEC_FIELDS) {
      const val = specData[key];
      const hasVal = val != null && val !== '' && val !== 'Not Published' && val !== 'Not Applicable';
      await adapters.database.create('ComponentDimension', {
        uuid: newUuid('dim'), component_uuid: component.uuid, dimension_key: key, dimension_name: label,
        category: 'Manufacturer specification', source: 'Manufacturer Verified Specification',
        value_mm: typeof val === 'number' ? val : null, text_value: typeof val === 'string' ? String(val) : null,
        original_value: typeof val === 'number' ? val : null, original_unit: typeof val === 'number' ? 'mm' : 'text',
        entered_unit: typeof val === 'number' ? 'mm' : 'text',
        verification_status: hasVal ? 'Verified manufacturer value' : 'Unknown',
        confidence: 'High', entered_by: actor, verified_by: hasVal ? actor : null,
        date_entered: today(), date_verified: hasVal ? today() : null,
        document_url: specData.source_file_url || '', source_page_number: specData.source_page_number || '',
        session_uuid: '', ...migrationFields(actor),
      });
    }
    await auditService.record('spec_imported', 'ComponentSpec', spec.uuid, `Imported specs for ${component.manufacturer} ${component.model}`, actor);
    return spec;
  },

  async saveStation(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const existing = (await adapters.database.filter('EnvelopeStation', { component_uuid: portable.component_uuid, station_name: portable.station_name, session_uuid: portable.session_uuid || '' }, '-updated_date', 1))[0];
    const payload = { ...portable, date_entered: portable.date_entered || today(), entered_by: actor };
    const saved = existing ? await adapters.database.update('EnvelopeStation', existing.id, payload) : await adapters.database.create('EnvelopeStation', { ...payload, uuid: newUuid('station'), ...migrationFields(actor) });
    await auditService.record('station_saved', 'EnvelopeStation', saved.uuid, `Saved station ${portable.station_name}`, actor);
    return saved;
  },

  async saveAccessPoint(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const saved = await adapters.database.create('AccessPoint', { ...portable, uuid: newUuid('access'), date_entered: today(), entered_by: actor, ...migrationFields(actor) });
    await auditService.record('access_point_saved', 'AccessPoint', saved.uuid, `Saved access point ${portable.name}`, actor);
    return saved;
  },

  async saveKeepOutZone(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const saved = await adapters.database.create('KeepOutZone', { ...portable, uuid: newUuid('keepout'), date_entered: today(), entered_by: actor, ...migrationFields(actor) });
    await auditService.record('keepout_saved', 'KeepOutZone', saved.uuid, `Saved keep-out zone ${portable.name}`, actor);
    return saved;
  },

  async saveMovementPosition(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const existing = (await adapters.database.filter('MovementPosition', { component_uuid: portable.component_uuid, position_name: portable.position_name, session_uuid: portable.session_uuid || '' }, '-updated_date', 1))[0];
    const payload = { ...portable, date_entered: portable.date_entered || today(), entered_by: actor };
    const saved = existing ? await adapters.database.update('MovementPosition', existing.id, payload) : await adapters.database.create('MovementPosition', { ...payload, uuid: newUuid('move'), ...migrationFields(actor) });
    await auditService.record('movement_saved', 'MovementPosition', saved.uuid, `Saved movement ${portable.position_name}`, actor);
    return saved;
  },

  async saveAssemblyComponent(data, actor) {
    const { id, created_date, updated_date, created_by_id, ...portable } = data;
    const saved = await adapters.database.create('AssemblyComponent', { ...portable, uuid: newUuid('assembly'), date_entered: today(), entered_by: actor, ...migrationFields(actor) });
    await auditService.record('assembly_saved', 'AssemblyComponent', saved.uuid, `Saved assembly component ${portable.component_label}`, actor);
    return saved;
  },

  async createSession(workflow, refs, actor) {
    const session = await adapters.database.create('MeasurementSession', {
      uuid: newUuid('session'), project_uuid: refs.project_uuid || '', customer_uuid: refs.customer_uuid || '',
      limb_profile_uuid: refs.limb_profile_uuid || '', component_uuid: refs.component_uuid || '',
      workflow, status: 'Not started', measured_by: actor, measured_date: today(),
      progress_percent: 0, ...migrationFields(actor),
    });
    await auditService.record('session_created', 'MeasurementSession', session.uuid, `Created ${workflow} session`, actor);
    return session;
  },
};