import { and, eq, sql } from 'drizzle-orm';
import { z } from 'zod';

import { db } from '@/lib/db';
import { companies } from '@/lib/db/schema/companies';
import { createCompany, updateCompany } from '@/lib/services/companies.service';

import type { ImportAdapter } from '../types';

export const companiesAdapter: ImportAdapter = {
  key: 'companies',
  label: 'Companies',
  order: 1,
  dependsOn: [],
  targetFields: [
    {
      key: 'name',
      label: 'Name',
      required: true,
      aliases: ['company', 'companyname'],
      zod: z.string().min(1),
    },
    { key: 'legalName', label: 'Legal name', required: false, zod: z.string() },
    {
      key: 'taxId',
      label: 'Tax ID',
      required: false,
      aliases: ['vat', 'vatnumber'],
      zod: z.string(),
    },
    { key: 'registrationNumber', label: 'Registration number', required: false, zod: z.string() },
    {
      key: 'billingEmail',
      label: 'Billing email',
      required: false,
      aliases: ['email'],
      zod: z.string().email(),
    },
    {
      key: 'status',
      label: 'Status',
      required: false,
      zod: z.enum(['active', 'dissolved']),
    },
    { key: 'notes', label: 'Notes', required: false, zod: z.string() },
  ],
  matchKey: (row) => (row.name ? row.name.trim().toLowerCase() : null),
  findExisting: async (portId, key) => {
    const row = await db.query.companies.findFirst({
      where: and(eq(companies.portId, portId), sql`lower(${companies.name}) = ${key}`),
      columns: { id: true },
    });
    return row ?? null;
  },
  insert: async (row, _resolved, ctx) => {
    const c = await createCompany(
      ctx.portId,
      {
        name: row.name!,
        legalName: row.legalName,
        taxId: row.taxId,
        registrationNumber: row.registrationNumber,
        billingEmail: row.billingEmail,
        status: (row.status as 'active' | 'dissolved' | undefined) ?? 'active',
        notes: row.notes,
        tagIds: [],
      },
      ctx.meta,
    );
    return { id: c.id };
  },
  update: async (id, row, _resolved, ctx) => {
    await updateCompany(
      id,
      ctx.portId,
      {
        legalName: row.legalName,
        taxId: row.taxId,
        registrationNumber: row.registrationNumber,
        billingEmail: row.billingEmail,
        status: row.status as 'active' | 'dissolved' | undefined,
        notes: row.notes,
      },
      ctx.meta,
    );
  },
};
