import {
  auditLog,
  bookings,
  documents,
  documentsForTrip,
  flights,
  flightsForTrip,
  guests,
  guestsOnTrip,
  hotelsForTrip,
  itineraryForTrip,
  payments,
  paymentsForTrip,
  transportForTrip,
  tripHotels,
  trips,
} from "@/data/mock";
import type { Trip } from "@/data/types";

/** The operational "today" for this dataset. */
export const TODAY = new Date("2026-08-27T00:00:00Z");

export const todayLabel = TODAY.toLocaleDateString("en-GB", {
  weekday: "long",
  day: "numeric",
  month: "long",
  year: "numeric",
});

export function daysUntil(iso: string) {
  if (!iso) return 0;
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return 0;
  return Math.round((d.getTime() - TODAY.getTime()) / 86400000);
}

// ───────────────────────────────────────────────── Trip readiness

export interface Readiness {
  guestsConfirmed: number;
  guestsTotal: number;
  docsVerified: number;
  docsTotal: number;
  paidAmount: number;
  totalAmount: number;
  outstanding: number;
  itineraryDays: number;
  itineraryPlanned: number;
  itineraryComplete: boolean;
  hotelsConfirmed: number;
  hotelsTotal: number;
  flightsConfirmed: number;
  flightsTotal: number;
  transportConfirmed: number;
  transportTotal: number;
  score: number;
}

const readinessCache = new Map<string, Readiness>();

export function tripReadiness(trip: Trip): Readiness {
  const cached = readinessCache.get(trip.id);
  if (cached) return cached;

  const roster = guestsOnTrip(trip.id);
  const guestsTotal = Math.max(1, roster.length || trip.guests);
  const tripBookings = bookings.filter((b) => b.trip === trip.id);
  const guestsConfirmed = tripBookings.filter((b) => b.status === "Confirmed").length || guestsTotal;

  const docs = documentsForTrip(trip.id);
  const docsTotal = docs.length;
  const docsVerified = docs.filter((d) => d.status === "Verified").length;

  const pay = paymentsForTrip(trip.id);
  const totalAmount = pay.reduce((s, p) => s + p.netPayable, 0);
  const paidAmount = pay.reduce((s, p) => s + p.paid, 0);
  const outstanding = pay.reduce((s, p) => s + p.due, 0);

  const itineraryPlanned = itineraryForTrip(trip.id).length;
  const itineraryDays = Math.min(trip.days, 10);
  const itineraryComplete = itineraryPlanned >= itineraryDays && itineraryPlanned > 0;

  const th = hotelsForTrip(trip.id);
  const fl = flightsForTrip(trip.id);
  const tr = transportForTrip(trip.id);

  const pct = (a: number, b: number, fallback = 0) => (b > 0 ? a / b : fallback);

  const score = Math.round(
    (pct(guestsConfirmed, guestsTotal, 1) * 15 +
      pct(docsVerified, docsTotal) * 25 +
      pct(paidAmount, totalAmount) * 30 +
      (itineraryComplete ? 15 : itineraryPlanned > 0 ? 8 : 0) +
      pct(th.filter((h) => h.status === "Confirmed").length, th.length) * 8 +
      pct(fl.filter((f) => f.status !== "Cancelled").length, fl.length) * 4 +
      pct(tr.filter((t) => t.status !== "Cancelled").length, tr.length) * 3) *
      1,
  );

  const value: Readiness = {
    guestsConfirmed,
    guestsTotal,
    docsVerified,
    docsTotal,
    paidAmount,
    totalAmount,
    outstanding,
    itineraryDays,
    itineraryPlanned,
    itineraryComplete,
    hotelsConfirmed: th.filter((h) => h.status === "Confirmed").length,
    hotelsTotal: th.length,
    flightsConfirmed: fl.filter((f) => f.status === "Scheduled" || f.status === "Departed").length,
    flightsTotal: fl.length,
    transportConfirmed: tr.filter((t) => t.status !== "Cancelled").length,
    transportTotal: tr.length,
    score: Math.min(100, Math.max(0, score)),
  };
  readinessCache.set(trip.id, value);
  return value;
}

// ───────────────────────────────────────────────── Trip cohorts

export const upcomingTrips = trips
  .filter((t) => daysUntil(t.departure) >= 0 && t.status !== "Cancelled" && t.status !== "Draft")
  .sort((a, b) => a.departure.localeCompare(b.departure));

export const activeTrips = trips.filter(
  (t) => t.status === "Active" || (daysUntil(t.departure) <= 0 && daysUntil(t.returnDate) >= 0 && t.status !== "Cancelled"),
);

export const departuresToday = trips.filter((t) => daysUntil(t.departure) === 0);

export const draftTrips = trips.filter((t) => t.status === "Draft");

export const completedTrips = trips.filter((t) => t.status === "Completed");

export function tripNeedsAttention(t: Trip) {
  if (t.status === "Cancelled" || t.status === "Completed") return false;
  const r = tripReadiness(t);
  const d = daysUntil(t.departure);
  if (d < 0) return false;
  return (
    r.score < 75 ||
    (r.outstanding > 0 && d <= 30) ||
    (!r.itineraryComplete && d <= 45) ||
    r.hotelsConfirmed < r.hotelsTotal ||
    (r.docsTotal > 0 && r.docsVerified < r.docsTotal && d <= 30)
  );
}

export const attentionTrips = upcomingTrips.filter(tripNeedsAttention);

export const departingThisWeek = upcomingTrips.filter((t) => daysUntil(t.departure) <= 7);
export const departingThisMonth = upcomingTrips.filter((t) => daysUntil(t.departure) <= 31);

// ───────────────────────────────────────────────── Money & documents

export const outstandingTotal = payments.reduce((s, p) => s + p.due, 0);
export const collectedTotal = payments.reduce((s, p) => s + p.paid, 0);
export const billedTotal = payments.reduce((s, p) => s + p.netPayable, 0);

export const overduePayments = payments.filter((p) => p.due > 0 && daysUntil(p.dueDate) < 0);

export const pendingDocs = documents.filter((d) => d.status === "Pending" || d.status === "Uploaded");
export const expiringDocs = documents.filter((d) => d.status === "Expiring Soon");
export const expiredDocs = documents.filter((d) => d.status === "Expired" || d.status === "Rejected");
export const docsNeedingAttention = [...pendingDocs, ...expiringDocs, ...expiredDocs];

/** Documents ranked by how soon the traveller departs. */
export const urgentDocs = documents
  .filter((d) => d.status !== "Verified")
  .filter((d) => daysUntil(d.departure) >= 0 && daysUntil(d.departure) <= 21)
  .sort((a, b) => a.departure.localeCompare(b.departure));

export const incompleteProfiles = guests.filter((g) => g.profileCompletion < 70 && (g.upcomingTrip || g.activeTrip));

export const travellersOnUpcoming = upcomingTrips.reduce((s, t) => s + t.guests, 0);

export const unconfirmedHotels = tripHotels.filter((h) => h.status === "Awaiting confirmation");
export const disruptedFlights = flights.filter((f) => f.status === "Delayed" || f.status === "Cancelled");

// ───────────────────────────────────────────────── Dashboard feeds

export interface AttentionItem {
  count: number;
  label: string;
  description: string;
  cta: string;
  to: string;
  tone: "danger" | "warning" | "info";
}

export const attentionItems: AttentionItem[] = [
  {
    count: overduePayments.length,
    label: "Payments overdue",
    description: "Balances past their due date on confirmed bookings.",
    cta: "Chase collections",
    to: "/payments",
    tone: "danger",
  },
  {
    count: pendingDocs.length,
    label: "Documents awaiting verification",
    description: "Passports, visas and insurance uploaded but unchecked.",
    cta: "Open verification queue",
    to: "/documents",
    tone: "warning",
  },
  {
    count: attentionTrips.filter((t) => !tripReadiness(t).itineraryComplete).length,
    label: "Itineraries incomplete",
    description: "Upcoming journeys without a full day-by-day plan.",
    cta: "Plan itineraries",
    to: "/itineraries",
    tone: "warning",
  },
  {
    count: unconfirmedHotels.length + disruptedFlights.length,
    label: "Supplier confirmations pending",
    description: "Hotel confirmations outstanding and flights showing changes.",
    cta: "Review bookings",
    to: "/hotels",
    tone: "warning",
  },
  {
    count: incompleteProfiles.length,
    label: "Guest profiles incomplete",
    description: "Travelling guests with profile completion under 70%.",
    cta: "Complete profiles",
    to: "/guests",
    tone: "info",
  },
];

export interface OpsEvent {
  time: string;
  title: string;
  tripId: string;
  tripName: string;
  travellers: number;
  owner: string;
  detail: string;
  status: string;
}

export const todaysOperations: OpsEvent[] = (() => {
  const events: OpsEvent[] = [];
  const departing = departuresToday.slice(0, 2);
  const returning = trips.filter((t) => daysUntil(t.returnDate) === 0).slice(0, 1);
  const running = activeTrips.slice(0, 3);

  departing.forEach((t) => {
    const f = flightsForTrip(t.id).find((x) => x.direction === "Outbound");
    events.push({
      time: "05:30",
      title: "Airport pickup & assistance",
      tripId: t.id,
      tripName: t.tour,
      travellers: t.guests,
      owner: t.tourManager,
      detail: `${t.originCity} — coach transfer to terminal`,
      status: "On schedule",
    });
    events.push({
      time: f?.departure ?? "09:10",
      title: `Departure ${f?.flightNumber ?? ""}`.trim(),
      tripId: t.id,
      tripName: t.tour,
      travellers: t.guests,
      owner: t.tourManager,
      detail: `${f?.departureAirport ?? t.originAirport} → ${f?.arrivalAirport ?? ""} · ${f?.airline ?? ""}`,
      status: f?.status ?? "Scheduled",
    });
  });

  running.forEach((t, i) => {
    const day = itineraryForTrip(t.id).find((d) => daysUntil(d.date) === 0) ?? itineraryForTrip(t.id)[i];
    if (!day) return;
    events.push({
      time: day.startTime,
      title: day.activity,
      tripId: t.id,
      tripName: t.tour,
      travellers: t.guests,
      owner: day.tourManager,
      detail: `${day.city} · meet at ${day.meetingPoint}`,
      status: "In progress",
    });
  });

  returning.forEach((t) => {
    events.push({
      time: "18:40",
      title: "Return arrival & dispersal",
      tripId: t.id,
      tripName: t.tour,
      travellers: t.guests,
      owner: t.tourManager,
      detail: `${t.originAirport} arrivals — onward transfers`,
      status: "Scheduled",
    });
  });

  if (events.length === 0) {
    upcomingTrips.slice(0, 4).forEach((t, i) => {
      events.push({
        time: ["09:00", "11:30", "14:00", "16:30"][i]!,
        title: "Pre-departure readiness call",
        tripId: t.id,
        tripName: t.tour,
        travellers: t.guests,
        owner: t.tourManager,
        detail: `Departs in ${daysUntil(t.departure)} days · ${t.destination}`,
        status: "Scheduled",
      });
    });
  }

  return events.sort((a, b) => a.time.localeCompare(b.time)).slice(0, 7);
})();

export interface OpsAlert {
  kind: "Flight" | "Hotel" | "Document" | "Payment" | "Guest";
  title: string;
  detail: string;
  to: string;
  tone: "danger" | "warning";
}

export const operationalAlerts: OpsAlert[] = (() => {
  const out: OpsAlert[] = [];

  disruptedFlights.slice(0, 2).forEach((f) => {
    out.push({
      kind: "Flight",
      title: `${f.airline} ${f.flightNumber} ${f.status.toLowerCase()}`,
      detail: `${f.departureAirport} → ${f.arrivalAirport} on ${f.date} · trip ${f.trip}`,
      to: `/trips/${f.trip}`,
      tone: "danger",
    });
  });

  unconfirmedHotels.slice(0, 2).forEach((h) => {
    out.push({
      kind: "Hotel",
      title: `${h.hotel} not confirmed`,
      detail: `${h.city}, ${h.country} · ${h.rooms} rooms from ${h.checkIn}`,
      to: `/trips/${h.tripId}`,
      tone: "warning",
    });
  });

  urgentDocs.slice(0, 2).forEach((d) => {
    out.push({
      kind: "Document",
      title: `${d.type} unverified — departs in ${daysUntil(d.departure)} days`,
      detail: `${d.guest} · ${d.tour}`,
      to: "/documents",
      tone: "danger",
    });
  });

  overduePayments.slice(0, 2).forEach((p) => {
    out.push({
      kind: "Payment",
      title: `₹${p.due.toLocaleString("en-IN")} overdue`,
      detail: `${p.guest} · ${p.tour} · due ${p.dueDate}`,
      to: "/payments",
      tone: "danger",
    });
  });

  incompleteProfiles.slice(0, 1).forEach((g) => {
    out.push({
      kind: "Guest",
      title: `${g.name}'s profile is ${g.profileCompletion}% complete`,
      detail: `Travelling soon · ${g.membership} member`,
      to: `/guests/${g.id}`,
      tone: "warning",
    });
  });

  return out.slice(0, 8);
})();

export const recentOperationalActivity = auditLog.slice(0, 8);

export const ROLE_FOCUS = [
  { role: "Operations", focus: "Departures, trip readiness, itineraries, documents, tour managers" },
  { role: "Finance", focus: "Payments, outstanding balances, invoices and transactions" },
  { role: "CRM", focus: "Guests, bookings, profile completion and loyalty" },
  { role: "Content", focus: "Tours, destinations, editorial content and publishing" },
  { role: "Community", focus: "Posts, reviews, moderation and engagement" },
];
