import { supabase } from '@/lib/supabase'
import type { Process } from '@/domain/types'

function toRow(process: Process, userId: string) {
  return {
    id: process.id,
    name: process.name,
    client: process.clientName,
    bpmn_xml: process.bpmnXml,
    currency: process.currency,
    overhead_percentage: process.overheadPercentage,
    annual_frequency: process.annualFrequency,
    analysis_horizon_years: process.analysisHorizonYears,
    automation_investment: process.automationInvestment,
    group_id: process.groupId,
    tags: process.tags,
    // owner_id se preserva del valor existente en el proceso; solo se inicializa con userId en creates
    owner_id: process.ownerId || userId,
    created_by: userId,
    updated_by: userId,
    updated_at: new Date().toISOString(),
  }
}

function fromRow(row: Record<string, unknown>): Process {
  return {
    id: row.id as string,
    name: row.name as string,
    clientName: (row.client as string) ?? '',
    bpmnXml: (row.bpmn_xml as string) ?? '',
    currency: (row.currency as string) ?? 'USD',
    overheadPercentage: Number(row.overhead_percentage ?? 0),
    annualFrequency: Number(row.annual_frequency ?? 1000),
    analysisHorizonYears: Number(row.analysis_horizon_years ?? 3),
    automationInvestment: Number(row.automation_investment ?? 0),
    groupId: (row.group_id as string | null) ?? null,
    tags: Array.isArray(row.tags) ? (row.tags as string[]) : [],
    createdAt: new Date(row.created_at as string).getTime(),
    updatedAt: new Date(row.updated_at as string).getTime(),
    ownerId: (row.owner_id as string) ?? '',
    updatedBy: (row.updated_by as string) ?? '',
  }
}

// Solo para display — no es parte del dominio puro. La resolución UUID → nombre
// es responsabilidad del repositorio, no del dominio (que solo conoce ownerId/updatedBy).
export interface ProcessWithUserNames extends Process {
  ownerName: string
  ownerAvatarUrl?: string
  updaterName: string
}

interface UserRef {
  name: string | null
  avatar_url?: string | null
}

function fromRowWithUsers(row: Record<string, unknown>): ProcessWithUserNames {
  const owner = row.owner as UserRef | null
  const updater = row.updater as UserRef | null
  return {
    ...fromRow(row),
    ownerName: owner?.name ?? 'Desconocido',
    ownerAvatarUrl: owner?.avatar_url ?? undefined,
    updaterName: updater?.name ?? 'Desconocido',
  }
}

export const supabaseProcessRepo = {
  async save(process: Process, userId: string): Promise<void> {
    const { error } = await supabase.from('processes').upsert(toRow(process, userId))
    if (error) throw error
  },

  async getById(id: string): Promise<Process | undefined> {
    const { data, error } = await supabase
      .from('processes')
      .select('*')
      .eq('id', id)
      .single()
    if (error) return undefined
    return fromRow(data)
  },

  // JOIN con users para resolver owner/updater en una sola query (evita N+1).
  // Si las FK owner_id/updated_by no están declaradas como relaciones en PostgREST,
  // este select falla — en ese caso usar el fallback de dos queries + mapeo en memoria.
  async getAll(): Promise<ProcessWithUserNames[]> {
    const { data, error } = await supabase
      .from('processes')
      .select('*, owner:users!owner_id(name, avatar_url), updater:users!updated_by(name)')
      .order('updated_at', { ascending: false })
    if (error) throw error
    return (data ?? []).map((row) => fromRowWithUsers(row as Record<string, unknown>))
  },

  async delete(id: string): Promise<void> {
    // CASCADE en Supabase elimina: activities, gateways, activity_resource_assignments, simulations
    const { error } = await supabase.from('processes').delete().eq('id', id)
    if (error) throw error
  },

  // No-op en Sprint 4: la implementación real (insertar en process_access) llega cuando existan guests.
  // El método existe para que la UI de "Compartir con equipo" funcione sin escritura a DB.
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  async setShared(_processId: string, _shared: boolean): Promise<void> {
    return
  },
}
