import { v4 as uuidv4 } from 'uuid';
import * as Device from 'expo-device';
import { Platform } from 'react-native';
import { pb } from './pocketbase';
import { kv } from '../lib/kv';
import { Household, HouseholdMember } from '../types';

const NOTIF_KEY = 'houseorg_notifications_enabled';
const HOUSEHOLD_ID_KEY = 'household_id';
const DEVICE_ID_KEY = 'device_id';

function mapHousehold(record: { id: string; name: string; invite_token: string; created: string }): Household {
  return {
    id: record.id,
    name: record.name,
    inviteToken: record.invite_token,
    createdAt: new Date(record.created),
  };
}

export async function getOrCreateDeviceId(): Promise<string> {
  let deviceId = await kv.getItem(DEVICE_ID_KEY);
  if (!deviceId) {
    deviceId = uuidv4();
    await kv.setItem(DEVICE_ID_KEY, deviceId);
  }
  return deviceId;
}

export async function getStoredHouseholdId(): Promise<string | null> {
  return kv.getItem(HOUSEHOLD_ID_KEY);
}

export async function createHousehold(name: string): Promise<Household> {
  const record = await pb.collection('households').create({
    name,
    invite_token: uuidv4(),
  });
  const household = mapHousehold(record as any);
  await kv.setItem(HOUSEHOLD_ID_KEY, household.id);
  return household;
}

export async function joinHousehold(householdId: string, inviteToken: string): Promise<boolean> {
  try {
    const record = await pb.collection('households').getOne(householdId);
    if ((record as any).invite_token !== inviteToken) return false;
    await kv.setItem(HOUSEHOLD_ID_KEY, householdId);
    return true;
  } catch {
    return false;
  }
}

export async function registerMember(
  householdId: string,
  fcmToken: string | null,
  displayName?: string
): Promise<void> {
  const deviceId = await getOrCreateDeviceId();
  const deviceName = displayName?.trim() || Device.deviceName || 'Unbekanntes Gerät';
  const storedNotif = await kv.getItem(NOTIF_KEY);
  const notificationsEnabled = storedNotif !== 'false';

  const member: Omit<HouseholdMember, 'joinedAt'> & { household: string; device_id: string; device_name: string; fcm_token: string | null; notifications_enabled: boolean } = {
    household: householdId,
    device_id: deviceId,
    device_name: deviceName,
    deviceId,
    deviceName,
    fcmToken: notificationsEnabled ? fcmToken : null,
    fcm_token: notificationsEnabled ? fcmToken : null,
    notificationsEnabled,
    notifications_enabled: notificationsEnabled,
  };

  const existing = await pb.collection('members').getFullList({
    filter: `device_id = "${deviceId}" && household = "${householdId}"`,
  });

  if (existing.length > 0) {
    await pb.collection('members').update(existing[0].id, member);
  } else {
    await pb.collection('members').create(member);
  }
}

export async function getHousehold(id: string): Promise<Household | null> {
  try {
    const record = await pb.collection('households').getOne(id);
    return mapHousehold(record as any);
  } catch (e: any) {
    if (e?.status === 404) return null;
    throw e;
  }
}

export async function regenerateInviteToken(householdId: string): Promise<string> {
  const newToken = uuidv4();
  await pb.collection('households').update(householdId, { invite_token: newToken });
  return newToken;
}

export function buildInviteLink(householdId: string, token: string): string {
  const base = process.env.EXPO_PUBLIC_POCKETBASE_URL ?? '';
  if (Platform.OS === 'web' && base) {
    const origin = base.replace(':8090', '').replace(/\/$/, '');
    return `${origin}/join?householdId=${householdId}&token=${token}`;
  }
  return `houseorg://join?householdId=${householdId}&token=${token}`;
}
