// https://github.com/portier/portier-node

// https://paul-senon.medium.com/node-express-js-cookies-set-get-secure-884311606148

import express from "express";
const formParser = require("body-parser").urlencoded({ extended: false });
import { PortierClient } from "portier";

const cookieParser = require('cookie-parser');

const baseURL = function () {
  switch (process.env.FLYLOCAL_ENV) {
    case "prod":
      return process.env.PROD_URL;
    case "dev":
      return process.env.DEV_URL;
    case "local":
      return "http://" + process.env.LOCAL_IP + ":" + process.env.LOCAL_PORT;
    default:
      break;
  }
};

// GET  /           Render homepage
// POST /login      Redirect to the broker and begin authentication
// POST /verify     Receive an id_token via the broker and complete login
// POST /logout     Clear session cookies
// GET  /logout     Display a button to POST /logout

const portier = new PortierClient({
  //broker: process.env.PORTIER_URL,
  redirectUri: baseURL() + "/login/verify",
});


const stylesheet = `
  <style>
    html {
      font-size: max(4vmin, 18px);
      font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
      line-height: 1.5;
    }

    body {
      display: flex;
      flex-direction: column;
      align-items: center;
      height: 100%;
      padding: 0 1rem;
      justify-content: center;
      margin: 0;
    }

    header {
      font-size: min(3vmin, 18px);
      position: fixed;
      top: 0;
      width: 100vw;
      z-index: 403;
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      padding: 1em 1em 0.75em 1em;
      pointer-events: none;
    }

    .header__col{
      text-align: center;
    }

    #flylocal-logo {
      height: clamp(20px, 4rem, 50px);
      transition: all 0.3s;
    }
    
    .cls-1 {
      fill: #9cb7f3;
    }
    
    .cls-2 {
      fill: #2f80ed;
    }
    
    .cls-3 {
      fill: #000;
      transition: all 0.3s;
    }
    
    .nav-is-showing #flylocal-logo {
      height: 3rem;
    }
    
    .nav-is-showing .cls-3 {
      fill: #000;
    }
    
    .white-bkg .cls-3 {
      fill: #000;
    }

    main {
      max-width: 15rem;
    }

    form {
      display: flex;
      gap: .5rem;
      flex-wrap: wrap;
      justify-content: end;
    }

    h1 {
      font-size: 1rem;
      text-transform: uppercase;
      font-weight: 900;
    }

    .btn {
      border-radius: 999px;
      padding: 0.5em 0.8em;
      font-size: .75rem;
      white-space: nowrap;
      transition: 0.2s all;
      display: flex;
      align-items: center;
      /* justify-content: space-around; what was this for? */
      justify-content: center;
      gap: 0.25rem;
      line-height: 1;
      min-height: 1em;
      border: 0;
      text-decoration: none;
      cursor: pointer;
    }
    
    .btn svg {
      height: 1rem;
      width: 1rem;
      display: inline-block;
      aspect-ratio: 1;
      transition: 0.2s all;
    }
    
    .btn.btn--primary {
      background: #007fff;
      color: #fff;
    }
    
    .btn.btn--primary:hover {
      background: #00ca00;
      color: #fff;
    }
    
    .btn.btn--primary:hover svg {
      stroke: #ffffff;
    }

    input {
      background: #eee;
      border-radius: 0.5rem 3rem 3rem 3rem;
      transition: 0.3s all;
      padding: 0.5em 0.8em;
      font-size: .75rem;
      line-height: 1;
      border: 0;
      width: 100%;
    }
  </style>`;

const header = `
  <header>
  <div class="header__col"></div>
  <div class="header__col">
    <svg id="flylocal-logo" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1107.17 373.96">
      <path class="cls-1" d="M.1,242.9a55.68,55.68,0,0,0,111.24-2.42,54.61,54.61,0,0,0-.44-8.21l-.05,0c-3.86-37.55-29.44-82.66-32.6-90.5-6.84,5.84-48.77,34.79-68.78,66.73l-.05,0A55.95,55.95,0,0,0,.1,242.9Z" /><path class="cls-2" d="M141.36,52.27A55.68,55.68,0,0,0,33.8,35.74a57.55,57.55,0,0,0-2.27,7.42,55.82,55.82,0,0,0-1.41,11.53,54.75,54.75,0,0,0,.45,8.22h.05c3.86,37.55,29.79,83.67,32.59,90.5,6.2-4.83,48.77-34.79,68.79-66.73h.05a55.89,55.89,0,0,0,9.31-34.41ZM85.88,56a13,13,0,1,1,15.59-9.74A13,13,0,0,1,85.88,56Z" /><path class="cls-3" d="M156.34,293.15l34.58-173.28H166.33l5.36-26.81h24.6l5.18-25.71q6.83-34,24.5-50.3C242.74,1.6,268.46-2.8,290,3.55c1.12.33,2.24.69,3.34,1.08-.58,2.8-7.2,29.89-7,30-7.63-2.37-16.2-3.35-24-1.43C246.75,37,241.44,53.31,238.64,67.35l-5.18,25.71h32.73l-5.36,26.81H228.09L193.51,293.15Z" /><path class="cls-3" d="M290.8,293.15h-37L311.51,4.66h37Z" /><path class="cls-3" d="M393,224.17l.19,11.1,1.11.18,64-142.39H498.6L385.79,324.22a140.35,140.35,0,0,1-25.06,35.13Q346.21,374,324.58,374a47.75,47.75,0,0,1-9.34-1q-5.08-1-9.89-2.31L315,342.89q2,.38,5.27.74a46.84,46.84,0,0,0,5.09.37q9.44,0,17.85-9.71a91.86,91.86,0,0,0,14-21.72l10.17-20L348.44,93.06h40.31Z" /><path class="cls-3" d="M511.33,293.15h-37L532,4.66h37Z" /><path class="cls-3" d="M553.53,180.53q6.47-41.43,30.14-66.3t58.81-24.87q33.09,0,49.56,25.89t10.17,65.28l-4.07,25.52q-6.66,41.61-30.24,66.29T609.56,297q-33.46,0-50-25.7t-10.08-65.28Zm32.91,25.52q-4.62,28.48,1.85,45.49t25.71,17q17.75,0,30.14-17.75T661,206.05L665,180.53q4.44-27.92-1.94-45.12t-25.25-17.2q-18.3,0-30.69,17.75t-16.65,44.57Z" /><path class="cls-3" d="M779.81,268.55q12.57,0,23.49-10.81t13.87-29h33.1l.37,1.11q-4.26,29.41-26,48.27T775.37,297q-34.39,0-50-25.61t-9.52-64.26l4.44-27.56q6.47-40.48,29.31-65.37t58.9-24.87q28.1,0,43.45,20.53t10.17,53.26H827.52q3.33-20.72-3.14-32.83t-20.53-12.11q-19.23,0-30.79,17.57T757.44,179.6L753,207.16q-4.44,28.11,1,44.75T779.81,268.55Z" /><path class="cls-3" d="M956.91,293.15q-.37-7.39-.37-13.69a101.53,101.53,0,0,1,.74-12.39,93.25,93.25,0,0,1-23.95,21.64Q919.92,297,905.68,297q-22.56,0-33.93-16.27t-6-42.53q6.1-30.53,27.46-46T949,176.83h25.89l4.06-20.53q3.71-19.41-1.57-29.12t-19.51-9.71q-11.64,0-21.45,9.34a41.72,41.72,0,0,0-12.39,23l-35.32-.18-.37-1.11q4.07-24.6,25.8-41.89t51.68-17.29q26.64,0,41.61,17.75t8.69,49.56l-18.67,92.84a183.7,183.7,0,0,0-3.15,22.56,133.93,133.93,0,0,0,.19,21.08Zm-37-25q11.28,0,23-7.76a63.41,63.41,0,0,0,18.95-19.24L970,200.13H943.78q-14.81,0-26.26,11.28A49.81,49.81,0,0,0,903.1,238q-3,14.43,1.29,22.28T919.92,268.18Z" /><path class="cls-3" d="M1049.48,293.15h-37l57.7-288.49h37Z" />
    </svg>
  </div>
  <div class="header__col"></div>
  </header>
`;

const app = express();
app.use(express.json())
app.use(express.urlencoded({ extended: false }))

// pass argument into cookie parser to make it secret
//app.use(cookieParser(process.env.PORTIER_SECRET));
app.use(cookieParser());

app.get("/", (req, res) => {
  const redirect = 
    (req.query.redirect && typeof req.query.redirect !== 'undefined') ? '<input name="redirect" type="hidden" value="' + req.query.redirect + '">' : '';
  const note = 
    (req.query.redirect && typeof req.query.redirect !== 'undefined') ? `<h1>Want to book a flight?<br/>Take 10 seconds and log in.</h1>` : '';
  res.type("html").end(`
    ${header}
    <main>
      ${note}
      <p>To log in, just enter your email address and we'll send you a magic link. </p>
      <p><strong>No new password to remember!</strong></p>
      <form method="post" action="/login/auth">
        ${redirect}
        <input name="email" type="email" value="spencer@seasteading.org" placeholder="coolname@website.com" pattern="/(?:[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/" required>
        <button type="submit" class="btn btn--primary">
          get my link
          <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-wand" width="40" height="40" viewBox="0 0 24 24" stroke-width="1.5" stroke="#ffffff" fill="none" stroke-linecap="round" stroke-linejoin="round">
            <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
            <polyline points="6 21 21 6 18 3 3 18 6 21" />
            <line x1="15" y1="6" x2="18" y2="9" />
            <path d="M9 3a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2" />
            <path d="M19 13a2 2 0 0 0 2 2a2 2 0 0 0 -2 2a2 2 0 0 0 -2 -2a2 2 0 0 0 2 -2" />
          </svg>
        </button>
      </form>
    </main>
    ${stylesheet}
  `);

  // email = cookies('email')
  // if email:
  //     return template('verified', email=email)
  // else:
  //     return template('index')
});

app.post("/auth", formParser, (req, res) => {

  console.log(baseURL());

  //console.log(req.body);
  portier.authenticate(req.body.email).then((authUrl) => {
    if (req.body.redirect && typeof req.body.redirect !== 'undefined') {
      res.redirect(303, authUrl + '?redirect=' + req.body.redirect);
    } else {
      res.redirect(303, authUrl);
    }
  });
});

app.post("/verify", formParser, (req, res) => {
  //console.log(req.body);

  console.log(baseURL());

  portier.verify(req.body.id_token).then((email) => {

    const redirectButton = (req.query.redirect && typeof req.query.redirect !== 'undefined') ? `<a class="btn btn--primary" href="${req.query.redirect}">back to your flight</a>` : `<a class="btn btn--primary" href="${baseURL()}">back to the map</a>`;

    // needed to string .cookie and .type together
    res.cookie('email', email,
      {
        //httpOnly: true, 
        // 👆 blocks access by JavaScript; prevents cookie manipulation
        // 👆 can't be gotten by $cookies.get. this probably needs to be hardened

        maxAge: 1000 * 60 * 60 * 24 * 30,
        //signed: false,
        //domain: baseURL(),
        path: "/"
      }).type("html").end(`
      ${header}
      <main>
      <p>Great! You're logged in.</p>
      ${redirectButton}
      </main>
      ${stylesheet}
    `);
  });
});

// app.get("/check", (req, res) => {
//   //req.signedCookies.name='Gourav';
//   //req.signedCookies.age=12;  
//   const cookie = req.signedCookies.email;
//   console.log(cookie);
//   //console.log(req.signedCookies.name);
//   res.send();
// });

// app.get("/logout", (req, res) => {
//   res.clearCookie("email");
//   res.send('forgotten');
// });

//app.post("/logout")
//res.clearCookie("email");

// app.get('/test', function (req, res) {
//   res.send('Test successful')
// })

export default {
  path: '/login',
  handler: app
}