import { NextResponse } from "next/server";
import {
  getStorefrontCheckoutState,
  submitStorefrontCheckoutOrder,
  updateStorefrontCheckout,
} from "@/lib/storefront-checkout";
import {
  applyCartSessionCookies,
  getCartSessionFromRequestCookies,
} from "@/lib/storefront-cart";
import type { StorefrontCheckoutAddress } from "@/types/storefront";

function isCheckoutAddress(value: unknown): value is StorefrontCheckoutAddress {
  if (!value || typeof value !== "object") {
    return false;
  }

  const address = value as StorefrontCheckoutAddress;

  return (
    typeof address.firstName === "string" &&
    typeof address.lastName === "string" &&
    typeof address.address1 === "string" &&
    typeof address.address2 === "string" &&
    typeof address.city === "string" &&
    typeof address.postcode === "string" &&
    typeof address.country === "string" &&
    typeof address.email === "string" &&
    typeof address.phone === "string"
  );
}

export async function GET() {
  try {
    const session = await getCartSessionFromRequestCookies();
    const result = await getStorefrontCheckoutState(session);
    const response = NextResponse.json(result.checkout);

    applyCartSessionCookies(response, result.session);

    return response;
  } catch (error) {
    return NextResponse.json(
      {
        message:
          error instanceof Error ? error.message : "Checkout request failed.",
      },
      { status: 500 },
    );
  }
}

export async function PUT(request: Request) {
  try {
    const body = (await request.json()) as {
      billingAddress?: StorefrontCheckoutAddress;
      shippingAddress?: StorefrontCheckoutAddress;
      paymentMethod?: string;
      customerNote?: string;
      shippingSelection?: {
        packageId: number;
        rateId: string;
      };
    };

    if (
      !isCheckoutAddress(body.billingAddress) ||
      !isCheckoutAddress(body.shippingAddress) ||
      typeof body.paymentMethod !== "string"
    ) {
      return NextResponse.json(
        { message: "Neispravni checkout podaci." },
        { status: 400 },
      );
    }

    const session = await getCartSessionFromRequestCookies();
    const result = await updateStorefrontCheckout(session, {
      billingAddress: body.billingAddress,
      shippingAddress: body.shippingAddress,
      paymentMethod: body.paymentMethod,
      customerNote:
        typeof body.customerNote === "string" ? body.customerNote : undefined,
      shippingSelection: body.shippingSelection,
    });
    const response = NextResponse.json(result.checkout);

    applyCartSessionCookies(response, result.session);

    return response;
  } catch (error) {
    return NextResponse.json(
      {
        message:
          error instanceof Error
            ? error.message
            : "Ažuriranje checkouta nije uspjelo.",
      },
      { status: 500 },
    );
  }
}

export async function POST(request: Request) {
  try {
    const body = (await request.json()) as {
      billingAddress?: StorefrontCheckoutAddress;
      shippingAddress?: StorefrontCheckoutAddress;
      paymentMethod?: string;
      customerNote?: string;
      shippingSelection?: {
        packageId: number;
        rateId: string;
      };
    };

    if (
      !isCheckoutAddress(body.billingAddress) ||
      !isCheckoutAddress(body.shippingAddress) ||
      typeof body.paymentMethod !== "string"
    ) {
      return NextResponse.json(
        { message: "Neispravni checkout podaci." },
        { status: 400 },
      );
    }

    const session = await getCartSessionFromRequestCookies();
    const result = await submitStorefrontCheckoutOrder(session, {
      billingAddress: body.billingAddress,
      shippingAddress: body.shippingAddress,
      paymentMethod: body.paymentMethod,
      customerNote:
        typeof body.customerNote === "string" ? body.customerNote : undefined,
      shippingSelection: body.shippingSelection,
    });
    const response = NextResponse.json(result.result);

    applyCartSessionCookies(response, result.session);

    return response;
  } catch (error) {
    return NextResponse.json(
      {
        message:
          error instanceof Error
            ? error.message
            : "Slanje narudžbe nije uspjelo.",
      },
      { status: 500 },
    );
  }
}
