import { query, internalQuery } from "./_generated/server";
import { v } from "convex/values";
import * as Users from "./model/users";
import * as CartsModel from "./model/carts";
import { validateAndEnrichCart } from "./model/checkout";
import type { CartValidationResult } from "./model/checkout";

const EMPTY_RESULT_INVALID: CartValidationResult = {
  valid: false,
  items: [],
  issues: [],
  subtotal: 0,
};

const EMPTY_RESULT_VALID: CartValidationResult = {
  valid: true,
  items: [],
  issues: [],
  subtotal: 0,
};

export const validateCart = query({
  args: { sessionId: v.optional(v.string()) },
  handler: async (ctx, args) => {
    const user = await Users.getCurrentUser(ctx);
    const userId = user?._id ?? null;

    if (!userId && !args.sessionId) {
      return EMPTY_RESULT_INVALID;
    }

    const cart = await CartsModel.getCart(ctx, userId ?? undefined, args.sessionId);
    if (!cart || cart.items.length === 0) {
      return EMPTY_RESULT_VALID;
    }

    return await validateAndEnrichCart(ctx, cart.items);
  },
});

export const getShippingAddresses = query({
  args: {},
  handler: async (ctx) => {
    const user = await Users.getCurrentUserOrThrow(ctx);
    const addresses = await ctx.db
      .query("addresses")
      .withIndex("by_user_and_type", (q) =>
        q.eq("userId", user._id).eq("type", "shipping"),
      )
      .collect();
    addresses.sort((a, b) => {
      if (a.isDefault !== b.isDefault) return a.isDefault ? -1 : 1;
      return b._creationTime - a._creationTime;
    });
    return addresses;
  },
});

// ─── Internal Queries (consumed by actions in checkoutActions.ts) ────────────

export const getAddressById = internalQuery({
  args: { addressId: v.id("addresses") },
  handler: async (ctx, args) => {
    const address = await ctx.db.get(args.addressId);
    if (!address) throw new Error("Address not found");
    return address;
  },
});

export const validateCartInternal = internalQuery({
  args: {
    userId: v.optional(v.id("users")),
    sessionId: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const cart = await CartsModel.getCart(
      ctx,
      args.userId ?? undefined,
      args.sessionId,
    );
    if (!cart || cart.items.length === 0) return null;
    return await validateAndEnrichCart(ctx, cart.items);
  },
});

export const getCurrentUserId = internalQuery({
  args: {},
  handler: async (ctx) => {
    const user = await Users.getCurrentUserOrThrow(ctx);
    return user._id;
  },
});
