import { Injectable, inject, signal } from '@angular/core';
import { take } from 'rxjs/operators';
import { ADMIN_ORDERS_GATEWAY } from '../../orders/services/admin-orders-gateway.token';
import { AdminOrder } from '../../orders/models/admin-order.model';
import { AdminCustomer } from '../models/admin-customer.model';

@Injectable({ providedIn: 'root' })
export class AdminCustomersFacade {
  private readonly ordersGateway = inject(ADMIN_ORDERS_GATEWAY);

  readonly customers = signal<AdminCustomer[]>([]);
  readonly loading = signal(false);
  readonly error = signal<string | null>(null);
  readonly search = signal('');
  readonly selected = signal<AdminCustomer | null>(null);
  readonly selectedLoading = signal(false);
  readonly selectedError = signal<string | null>(null);

  private buildCustomers(orders: AdminOrder[]): AdminCustomer[] {
    const byEmail = new Map<string, AdminOrder[]>();
    for (const order of orders) {
      const list = byEmail.get(order.customer.email) ?? [];
      list.push(order);
      byEmail.set(order.customer.email, list);
    }

    return [...byEmail.entries()].map(([email, customerOrders]) => {
      const sorted = [...customerOrders].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
      const latest = customerOrders[0];
      return {
        email,
        name: latest.customer.name,
        phone: latest.customer.phone,
        orderCount: customerOrders.length,
        totalSpent: customerOrders.reduce((sum, order) => sum + order.total, 0),
        currency: latest.currency,
        firstOrderAt: sorted[0].createdAt,
        lastOrderAt: sorted[sorted.length - 1].createdAt,
        addresses: [...new Set(customerOrders.map(order => order.shipping.address))],
        orders: [...customerOrders].sort((a, b) => b.createdAt.localeCompare(a.createdAt)),
      };
    });
  }

  loadList(): void {
    this.loading.set(true);
    this.error.set(null);
    this.ordersGateway.loadOrders({ search: '', status: 'all', page: 1, pageSize: 100000 }).pipe(take(1)).subscribe({
      next: result => {
        this.customers.set(this.buildCustomers(result.items));
        this.loading.set(false);
      },
      error: () => {
        this.customers.set([]);
        this.loading.set(false);
        this.error.set('common.errorDescription');
      }
    });
  }

  loadDetail(email: string): void {
    this.selectedLoading.set(true);
    this.selectedError.set(null);
    this.ordersGateway.loadOrders({ search: '', status: 'all', page: 1, pageSize: 100000 }).pipe(take(1)).subscribe({
      next: result => {
        const decoded = decodeURIComponent(email);
        const customers = this.buildCustomers(result.items);
        this.selected.set(customers.find(customer => customer.email === decoded) ?? null);
        this.selectedLoading.set(false);
      },
      error: () => {
        this.selectedLoading.set(false);
        this.selectedError.set('common.errorDescription');
      }
    });
  }

  setSearch(value: string): void {
    this.search.set(value);
  }

  filteredCustomers(): AdminCustomer[] {
    const query = this.search().trim().toLowerCase();
    if (!query) {
      return this.customers();
    }
    return this.customers().filter(customer =>
      `${customer.name} ${customer.email} ${customer.phone}`.toLowerCase().includes(query)
    );
  }
}
