import type { FastifyInstance, FastifyReply } from "fastify";
import type {
  AuthRequest,
  AuthResponse,
  ForgotPasswordRequest,
  ForgotPasswordResponse,
  ResendVerificationRequest,
  ResetPasswordRequest,
  ResetPasswordResponse,
  VerifyEmailRequest,
  VerifyEmailResponse
} from "@skola/shared";
import {
  loginUser,
  registerUser,
  requestPasswordReset,
  resendVerificationEmail,
  resetPassword,
  verifyEmailToken
} from "../services/auth-store.js";

interface TokenQuery {
  token?: string;
}

function toErrorMessage(error: unknown): string {
  return error instanceof Error ? error.message : "Unexpected authentication error.";
}

function sendHtml(reply: FastifyReply, html: string, statusCode = 200): void {
  reply.code(statusCode).type("text/html; charset=utf-8").send(html);
}

function renderStatusPage(title: string, message: string): string {
  return `<!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>${title}</title>
        <style>
          body { font-family: Arial, sans-serif; background:#f5ecde; color:#17332c; margin:0; min-height:100vh; display:grid; place-items:center; }
          main { width:min(560px, calc(100vw - 32px)); background:#fff8f0; border:1px solid rgba(23,51,44,.14); border-radius:22px; padding:28px; box-shadow:0 18px 40px rgba(18,59,50,.12); }
          h1 { margin-top:0; }
          p { line-height:1.55; }
        </style>
      </head>
      <body>
        <main>
          <h1>${title}</h1>
          <p>${message}</p>
          <p>You can close this tab and return to Microsoft Word.</p>
        </main>
      </body>
    </html>`;
}

function renderResetPage(token: string): string {
  return `<!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Reset Skola password</title>
        <style>
          body { font-family: Arial, sans-serif; background:#f5ecde; color:#17332c; margin:0; min-height:100vh; display:grid; place-items:center; }
          main { width:min(560px, calc(100vw - 32px)); background:#fff8f0; border:1px solid rgba(23,51,44,.14); border-radius:22px; padding:28px; box-shadow:0 18px 40px rgba(18,59,50,.12); }
          label, input, button { display:block; width:100%; box-sizing:border-box; }
          input { margin:8px 0 16px; padding:12px; border-radius:12px; border:1px solid rgba(23,51,44,.18); }
          button { border:0; border-radius:999px; padding:12px 16px; background:#c9623d; color:white; cursor:pointer; }
          #message { margin-top:16px; line-height:1.55; }
        </style>
      </head>
      <body>
        <main>
          <h1>Reset your Skola password</h1>
          <label>
            New password
            <input id="password" type="password" autocomplete="new-password" minlength="8" />
          </label>
          <button id="submit">Reset Password</button>
          <p id="message"></p>
        </main>
        <script>
          const token = ${JSON.stringify(token)};
          const message = document.getElementById("message");
          document.getElementById("submit").addEventListener("click", async () => {
            const password = document.getElementById("password").value;
            message.textContent = "Resetting password...";
            const response = await fetch("/v1/auth/reset-password", {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({ token, password })
            });
            const data = await response.json().catch(() => ({ message: "Password reset failed." }));
            message.textContent = data.message || "Password reset failed.";
          });
        </script>
      </body>
    </html>`;
}

export async function registerAuthRoutes(app: FastifyInstance): Promise<void> {
  app.post<{ Body: AuthRequest; Reply: AuthResponse }>("/v1/auth/register", async (request) => {
    return registerUser(request.body.email, request.body.password, request.body.name);
  });

  app.post<{ Body: AuthRequest; Reply: AuthResponse }>("/v1/auth/login", async (request) => {
    return loginUser(request.body.email, request.body.password);
  });

  app.post<{ Body: ForgotPasswordRequest; Reply: ForgotPasswordResponse }>(
    "/v1/auth/forgot-password",
    async (request) => requestPasswordReset(request.body.email)
  );

  app.post<{ Body: ResendVerificationRequest; Reply: ForgotPasswordResponse }>(
    "/v1/auth/resend-verification",
    async (request) => resendVerificationEmail(request.body.email)
  );

  app.post<{ Body: VerifyEmailRequest; Reply: VerifyEmailResponse }>(
    "/v1/auth/verify-email",
    async (request) => verifyEmailToken(request.body.token)
  );

  app.get<{ Querystring: TokenQuery }>("/v1/auth/verify-email", async (request, reply) => {
    try {
      const response = await verifyEmailToken(request.query.token ?? "");
      sendHtml(reply, renderStatusPage("Email verified", response.message));
    } catch (error) {
      sendHtml(reply, renderStatusPage("Verification failed", toErrorMessage(error)), 400);
    }
  });

  app.get<{ Querystring: TokenQuery }>("/v1/auth/reset-password", async (request, reply) => {
    sendHtml(reply, renderResetPage(request.query.token ?? ""));
  });

  app.post<{ Body: ResetPasswordRequest; Reply: ResetPasswordResponse }>(
    "/v1/auth/reset-password",
    async (request) => resetPassword(request.body.token, request.body.password)
  );
}
