type Env = {
    TURNSTILE_SECRET_KEY?: string;
    RESEND_API_KEY?: string;
    CONTACT_FROM_EMAIL?: string;
    CONTACT_TO_EMAIL?: string;
    ASSETS: Fetcher;
};

const jsonResponse = (data: Record<string, unknown>, status = 200) =>
    new Response(JSON.stringify(data), {
        status,
        headers: { "content-type": "application/json" },
    });

const readFormField = (value: FormDataEntryValue | null) =>
    typeof value === "string" ? value.trim() : "";

const handleContact = async (request: Request, env: Env) => {
    const formData = await request.formData();
    const name = readFormField(formData.get("name"));
    const email = readFormField(formData.get("email"));
    const message = readFormField(formData.get("message"));
    const turnstileToken = readFormField(formData.get("cf-turnstile-response"));

    if (!name || !email || !message) {
        return jsonResponse(
            { ok: false, error: "Missing required fields." },
            400,
        );
    }

    if (!env.TURNSTILE_SECRET_KEY) {
        return jsonResponse(
            { ok: false, error: "Turnstile secret key not configured." },
            500,
        );
    }

    if (!turnstileToken) {
        return jsonResponse(
            { ok: false, error: "Turnstile verification failed." },
            400,
        );
    }

    const verifyBody = new URLSearchParams({
        secret: env.TURNSTILE_SECRET_KEY,
        response: turnstileToken,
        remoteip: request.headers.get("CF-Connecting-IP") ?? "",
    });

    const verifyResponse = await fetch(
        "https://challenges.cloudflare.com/turnstile/v0/siteverify",
        {
            method: "POST",
            body: verifyBody,
        },
    );
    const verifyResult = (await verifyResponse.json()) as {
        success?: boolean;
    };

    if (!verifyResult.success) {
        return jsonResponse(
            { ok: false, error: "Turnstile verification failed." },
            400,
        );
    }

    if (!env.RESEND_API_KEY) {
        return jsonResponse(
            { ok: false, error: "Email provider not configured." },
            500,
        );
    }

    const fromEmail = env.CONTACT_FROM_EMAIL;
    if (!fromEmail) {
        return jsonResponse(
            { ok: false, error: "Sender email not configured." },
            500,
        );
    }

    const toEmail = env.CONTACT_TO_EMAIL ?? "calum@muir.in";
    const emailPayload = {
        from: fromEmail,
        to: [toEmail],
        reply_to: email,
        subject: "New contact form submission",
        text: `Name: ${name}\nEmail: ${email}\n\n${message}`,
    };

    const response = await fetch("https://api.resend.com/emails", {
        method: "POST",
        headers: {
            Authorization: `Bearer ${env.RESEND_API_KEY}`,
            "Content-Type": "application/json",
        },
        body: JSON.stringify(emailPayload),
    });
    if (!response.ok) {
        const contentType = response.headers.get("content-type") ?? "";
        const errorText = contentType.includes("application/json")
            ? JSON.stringify(await response.json().catch(() => ({})))
            : await response.text();
        const errorCode = response.headers.get("x-ms-error-code");
        const details = [
            `${response.status} ${response.statusText}`.trim(),
            errorCode ? `code=${errorCode}` : "",
            errorText.trim(),
        ]
            .filter(Boolean)
            .join(" | ")
            .slice(0, 500);
        return jsonResponse(
            {
                ok: false,
                error: "Failed to send email.",
                details,
            },
            502,
        );
    }

    return jsonResponse({ ok: true });
};

export default {
    async fetch(request: Request, env: Env): Promise<Response> {
        const url = new URL(request.url);
        if (url.pathname === "/__worker_ping") {
            return jsonResponse({ ok: true });
        }
        const contactPath = url.pathname;
        const isContact =
            contactPath === "/api/contact" ||
            contactPath === "/api/contact/" ||
            contactPath.endsWith("/api/contact") ||
            contactPath.endsWith("/api/contact/");
        if (isContact) {
            if (request.method === "GET" && url.searchParams.has("debug")) {
                return jsonResponse({
                    ok: true,
                    hasTurnstileSecret: Boolean(env.TURNSTILE_SECRET_KEY),
                    hasResendApiKey: Boolean(env.RESEND_API_KEY),
                    hasContactFromEmail: Boolean(env.CONTACT_FROM_EMAIL),
                    hasContactToEmail: Boolean(env.CONTACT_TO_EMAIL),
                });
            }
            if (request.method !== "POST") {
                return jsonResponse(
                    { ok: false, error: "Method not allowed." },
                    405,
                );
            }
            return handleContact(request, env);
        }
        if (url.pathname.includes("/api/")) {
            return jsonResponse({ ok: false, error: "Not found." }, 404);
        }
        if (env.ASSETS?.fetch) {
            return env.ASSETS.fetch(request);
        }
        return new Response("Not found", { status: 404 });
    },
};
