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

async function getCurrentUserId(): Promise<string> {
  const { data: { session } } = await supabase.auth.getSession()
  if (!session?.user) throw new Error('Usuario no autenticado')
  return session.user.id
}

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: 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(),
  }
}

export const supabaseProcessRepo = {
  async save(process: Process): Promise<void> {
    const userId = await getCurrentUserId()
    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)
  },

  async getAll(): Promise<Process[]> {
    const { data, error } = await supabase
      .from('processes')
      .select('*')
      .order('updated_at', { ascending: false })
    if (error) throw error
    return (data ?? []).map(fromRow)
  },

  async delete(id: string): Promise<void> {
    const { error } = await supabase.from('processes').delete().eq('id', id)
    if (error) throw error

    // TODO Sprint 4 Etapa 3-4: eliminar limpieza Dexie cuando actividades migren a Supabase
    await db.transaction('rw', [db.activities, db.gateways, db.resources, db.simulations], async () => {
      await db.activities.where('processId').equals(id).delete()
      await db.gateways.where('processId').equals(id).delete()
      await db.resources.where('processId').equals(id).delete()
      await db.simulations.where('processId').equals(id).delete()
    })
  },
}
