import { prisma, WatchlistType } from '@shieldai/db';
import { createHash } from 'crypto';

export function normalizeAddressValue(address: string): string {
  return address.trim().toLowerCase().replace(/\s+/g, ' ');
}

export function hashAddressValue(value: string): string {
  return createHash('sha256').update(value).digest('hex');
}

const TIER_LIMITS: Record<string, number> = {
  BASIC: 3,
  PLUS: 5,
  PREMIUM: 50,
};

export class PropertyWatchlistService {
  async addItem(
    subscriptionId: string,
    address: string,
    parcelId?: string,
    ownerName?: string,
  ) {
    const normalized = normalizeAddressValue(address);
    const itemHash = hashAddressValue(normalized);

    const currentCount = await prisma.propertyWatchlistItem.count({
      where: { subscriptionId, isActive: true },
    });

    const subscription = await prisma.subscription.findUnique({
      where: { id: subscriptionId },
      select: { tier: true },
    });

    if (!subscription) {
      throw new Error(`Subscription not found: ${subscriptionId}`);
    }

    const tier = subscription.tier.toUpperCase();
    const maxItems = TIER_LIMITS[tier] ?? 3;

    if (currentCount >= maxItems) {
      throw new Error(
        `Property watchlist limit reached (${maxItems} items). Your ${tier} plan allows up to ${maxItems} properties.`,
      );
    }

    const existing = await prisma.propertyWatchlistItem.findFirst({
      where: { subscriptionId, address: normalized, isActive: true },
    });

    if (existing) {
      if (!existing.isActive) {
        return prisma.propertyWatchlistItem.update({
          where: { id: existing.id },
          data: { isActive: true },
        });
      }
      return existing;
    }

    return prisma.propertyWatchlistItem.create({
      data: {
        subscriptionId,
        address: normalized,
        parcelId: parcelId ?? null,
        ownerName: ownerName ?? null,
        streetAddress: normalized,
        isActive: true,
      },
    });
  }

  async getItems(subscriptionId: string) {
    return prisma.propertyWatchlistItem.findMany({
      where: { subscriptionId, isActive: true },
      orderBy: { createdAt: 'desc' },
    });
  }

  async removeItem(id: string, subscriptionId: string) {
    const item = await prisma.propertyWatchlistItem.findFirst({
      where: { id, subscriptionId, isActive: true },
    });

    if (!item) {
      throw new Error(`Watchlist item not found: ${id}`);
    }

    return prisma.propertyWatchlistItem.update({
      where: { id },
      data: { isActive: false },
    });
  }

  async getActiveItemsForScan(subscriptionId: string) {
    return prisma.propertyWatchlistItem.findMany({
      where: { subscriptionId, isActive: true },
      include: {
        snapshots: {
          orderBy: { capturedAt: 'desc' },
          take: 1,
        },
      },
    });
  }

  async getItemCount(subscriptionId: string) {
    return prisma.propertyWatchlistItem.count({
      where: { subscriptionId, isActive: true },
    });
  }

  async getMaxItemsForTier(subscriptionId: string): Promise<number> {
    const subscription = await prisma.subscription.findUnique({
      where: { id: subscriptionId },
      select: { tier: true },
    });

    if (!subscription) {
      return 3;
    }

    const tier = subscription.tier.toUpperCase();
    return TIER_LIMITS[tier] ?? 3;
  }
}

export const propertyWatchlistService = new PropertyWatchlistService();
