import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { kappa } from '@/services/kappa-api'
import { tauriDb, type AlphaUserRecord, type CellRecord } from '@/services/tauri-db'
import { syncUserDetails } from '@/services/user-sync'
import { getLookups, getUsers, type UserRecord } from '@/services/users-db'
import type { KappaEmployee } from '@/types/kappa'

export interface AlphaUser {
  id: number
  email: string
  first_name: string
  last_name: string
  full_name: string
  is_active: boolean
  cell?: string
  cell_id?: number
  role?: string
  seniority?: string
  projects: string[]
  projects_count: number
  employee_ref?: KappaEmployee
}

export const useUsersStore = defineStore('users', () => {
  const users = ref<AlphaUser[]>([])
  const employees = ref<KappaEmployee[]>([])
  const cells = ref<CellRecord[]>([])
  const loading = ref(false)
  const error = ref<string | null>(null)
  const totalPages = ref(1)
  const currentPage = ref(1)
  const syncing = ref(false)
  const syncProgress = ref(0)
  const syncTotal = ref(0)
  const roles = ref<{ id: number; name: string }[]>([])

  const activeUsers = computed(() => users.value.filter(u => u.is_active))
  const devsByProject = computed(() => {
    const map = new Map<string, AlphaUser[]>()
    for (const u of users.value) {
      for (const p of u.projects) {
        if (!map.has(p)) map.set(p, [])
        map.get(p)!.push(u)
      }
    }
    return map
  })

  async function fetchAll() {
    error.value = null

    // 1. Cache hit: mostrar desde Dexie inmediatamente, saltar skeleton
    const dbUsers = await getUsers().catch(() => [] as UserRecord[])
    const roleItems = await getLookups('role').catch(() => [] as { id: number; name: string }[])

    if (dbUsers.length > 0) {
      users.value = dbUsers.map(u => ({
        id: u.id,
        email: u.email,
        first_name: u.firstName,
        last_name: u.lastName,
        full_name: u.fullName,
        is_active: u.isActive,
        role: roleItems.find(r => r.id === u.roleId)?.name || undefined,
        cell: undefined,
        seniority: u.seniority || undefined,
        projects: [],
        projects_count: 0,
        cell_id: undefined,
        employee_ref: undefined,
      }))
      loading.value = false
    } else {
      loading.value = true
    }

    // 2. Background refresh desde API
    try {
      const [rawUsers, page1, localUsers, localCells] = await Promise.all([
        kappa.getUsers(),
        kappa.getEmployees(1),
        tauriDb.getUsers().catch(() => [] as AlphaUserRecord[]),
        tauriDb.getCells().catch(() => [] as CellRecord[]),
      ])

      employees.value = page1.results
      cells.value = localCells

      totalPages.value = Math.ceil(page1.count / 25)
      if (totalPages.value > 1) {
        const restPages = []
        for (let p = 2; p <= totalPages.value; p++) {
          restPages.push(kappa.getEmployees(p))
        }
        const rest = await Promise.all(restPages)
        for (const r of rest) {
          employees.value.push(...r.results)
        }
      }

      const localMap = new Map(localUsers.map(u => [u.id, u]))
      users.value = buildUsers(rawUsers, employees.value, localMap)

      // 3. Restaurar roles desde Dexie
      for (const u of users.value) {
        const record = dbUsers.find(d => d.id === u.id)
        if (record?.roleId) {
          const role = roleItems.find(r => r.id === record.roleId)
          if (role) u.role = role.name
        }
      }

      syncUsersToTurso(users.value)
    } catch (e: any) {
      if (!dbUsers.length) error.value = e.message
    } finally {
      loading.value = false
    }
  }

  function buildUsers(raw: unknown[], emps: KappaEmployee[], localMap: Map<number, AlphaUserRecord>): AlphaUser[] {
    const cellMap = new Map(cells.value.map(c => [c.id, c.name]))

    return raw.map((u: any) => {
      const userEmps = emps.filter(e => e.user === u.id)
      const local = localMap.get(u.id)
      const cellName = local?.cell_id ? cellMap.get(local.cell_id) : undefined

      return {
        id: u.id,
        email: u.email || '',
        first_name: u.first_name || '',
        last_name: u.last_name || '',
        full_name: u.full_name || `${u.first_name || ''} ${u.last_name || ''}`.trim() || u.email,
        is_active: u.is_active !== undefined ? u.is_active : true,
        cell: cellName,
        cell_id: local?.cell_id ?? undefined,
        role: local?.role ?? undefined,
        seniority: local?.seniority ?? undefined,
        projects: userEmps
          .filter(e => e.initiative_name)
          .map(e => e.initiative_name!),
        projects_count: userEmps.filter(e => e.initiative).length,
        employee_ref: userEmps[0] || undefined,
      }
    })
  }

  async function syncUsersToTurso(userList: AlphaUser[]) {
    for (const u of userList) {
      await tauriDb.saveUser({
        id: u.id,
        email: u.email,
        first_name: u.first_name,
        last_name: u.last_name,
        role: u.role ?? null,
        seniority: u.seniority ?? null,
        cell_id: u.cell_id ?? null,
        is_active: u.is_active,
        created_at: null,
      }).catch(() => {})
    }
  }

  async function syncDetails() {
    const userIds = users.value.map(u => u.id)
    if (userIds.length === 0) return
    syncing.value = true
    syncProgress.value = 0
    syncTotal.value = userIds.length
    try {
      await syncUserDetails(userIds, (done, total) => { syncProgress.value = done; syncTotal.value = total })
      const roleItems = await getLookups('role')
      roles.value = roleItems.map(r => ({ id: r.id, name: r.name }))
      const dbUsers = await getUsers()
      // Mapear roleId → role name a AlphaUser
      for (const u of users.value) {
        const record = dbUsers.find(d => d.id === u.id)
        if (record?.roleId) {
          const role = roles.value.find(r => r.id === record.roleId)
          if (role) u.role = role.name
        }
      }
      console.log(`[Users] Sync complete: ${dbUsers.length} users in DB, ${roles.value.length} roles`)
    } catch (e) {
      console.error('[Users] Sync error:', e)
    } finally {
      syncing.value = false
    }
  }

  async function updateUserFields(id: number, role: string | null, seniority: string | null, cellId: number | null) {
    await tauriDb.updateUserFields(id, role, seniority, cellId)
    const idx = users.value.findIndex(u => u.id === id)
    if (idx !== -1) {
      const cellName = cellId ? cells.value.find(c => c.id === cellId)?.name : undefined
      users.value[idx] = {
        ...users.value[idx],
        role: role ?? undefined,
        seniority: seniority ?? undefined,
        cell: cellName,
        cell_id: cellId ?? undefined,
      }
    }
  }

  function updateLocal(id: number, data: Partial<AlphaUser>) {
    const idx = users.value.findIndex(u => u.id === id)
    if (idx !== -1) {
      users.value[idx] = { ...users.value[idx], ...data }
    }
  }

  async function createCell(name: string, description?: string): Promise<CellRecord> {
    const cell: CellRecord = {
      id: 0,
      name,
      description: description ?? null,
      created_at: null,
    }
    const id = await tauriDb.saveCell(cell)
    const created = { ...cell, id }
    cells.value.push(created)
    return created
  }

  return {
    users,
    employees,
    cells,
    loading,
    error,
    syncing,
    syncProgress,
    syncTotal,
    roles,
    totalPages,
    currentPage,
    activeUsers,
    devsByProject,
    fetchAll,
    syncDetails,
    updateLocal,
    updateUserFields,
    createCell,
  }
})
