import { Elysia, t } from "elysia";
import { html } from "@elysiajs/html";
import { cookie } from "@elysiajs/cookie";
import { KeyCloak, generateState, generateCodeVerifier } from "arctic";
import * as elements from "typed-html";
import { BaseHtml } from "../components/BaseHtml";
import { InputGroup, TextAreaGroup, ExperienceForm, EducationForm, ProjectForm } from "../components/AdminForms";
import { getAdminProfile, getAdminExperience, getAdminEducation, getAdminProjects, getAdminExperienceById, getAdminEducationById, getAdminProjectById } from "../db/queries";
import { updateProfile, createExperience, updateExperience, deleteExperience, createEducation, updateEducation, deleteEducation, updateExperienceOrder, updateEducationOrder, createProject, updateProject, deleteProject, updateProjectOrder } from "../db/mutations";

// Initialize Keycloak (Arctic)
const realmURL = process.env.KEYCLOAK_REALM_URL || "";
const clientId = process.env.KEYCLOAK_CLIENT_ID || "";
const clientSecret = process.env.KEYCLOAK_CLIENT_SECRET || "";
const redirectURI = process.env.KEYCLOAK_REDIRECT_URI || "http://localhost:3000/admin/callback";

const keycloak = new KeyCloak(realmURL, clientId, clientSecret, redirectURI);

const AdminLayout = ({ children }: elements.Children) => (
  <div class="min-h-screen bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-white">
    <nav class="bg-white dark:bg-gray-800 shadow p-4 mb-8">
      <div class="container mx-auto flex justify-between items-center">
        <div class="font-bold text-xl">CV Admin</div>
        <div class="flex gap-4">
            <a href="/admin/dashboard" class="hover:text-blue-500">Dashboard</a>
            <a href="/" target="_blank" class="hover:text-blue-500">View Site</a>
            <a href="/admin/logout" class="text-red-500">Logout</a>
        </div>
      </div>
    </nav>
    <div class="container mx-auto p-4">
      {children}
    </div>
    
    {/* SortableJS Initialization Script */}
    <script>
      {`
      function initSortable(id, endpoint) {
        const el = document.getElementById(id);
        if (!el) {
            console.warn('Sortable container not found:', id);
            return;
        }
        
        if (el._sortable) return;

        console.log('Initializing Sortable on:', id);
        el._sortable = new Sortable(el, {
          group: id,
          draggable: 'form',
          handle: '.drag-handle',
          animation: 150,
          ghostClass: 'bg-blue-100',
          onStart: function(evt) {
             console.log('Drag started', evt);
          },
          onEnd: function (evt) {
            console.log('Drag ended', evt);
            const ids = Array.from(el.querySelectorAll('form')).map(f => f.getAttribute('data-id'));
            console.log('New order:', ids);
            fetch(endpoint, {
               method: 'POST',
               headers: { 'Content-Type': 'application/json' },
               body: JSON.stringify({ ids: ids })
            });
          }
        });
      }
      
      document.addEventListener('DOMContentLoaded', () => {
         initSortable('experience-list', '/admin/experience/reorder');
         initSortable('education-list', '/admin/education/reorder');
         initSortable('project-list', '/admin/project/reorder');
      });

      document.body.addEventListener('htmx:afterSwap', (evt) => {
         initSortable('experience-list', '/admin/experience/reorder');
         initSortable('education-list', '/admin/education/reorder');
         initSortable('project-list', '/admin/project/reorder');
      });
      `}
    </script>
  </div>
);

export const adminRoutes = new Elysia()
    .use(cookie())
    .use(html())
    // Auth Middleware
    .derive(({ cookie: { auth_session } }) => {
        return {
            isLoggedIn: !!auth_session?.value
        };
    })
    
    // 1. Login Page
    .get("/admin/login", ({ isLoggedIn, set, html, cookie: { oauth_state, oauth_code_verifier } }) => {
        if (isLoggedIn) return Response.redirect("/admin/dashboard");
        
        const state = generateState();
        const codeVerifier = generateCodeVerifier();

        oauth_state.set({
             value: state,
             path: "/",
             secure: process.env.NODE_ENV === "production",
             httpOnly: true,
             maxAge: 600
        });

        oauth_code_verifier.set({
             value: codeVerifier,
             path: "/",
             secure: process.env.NODE_ENV === "production",
             httpOnly: true,
             maxAge: 600
        });

        try {
            const url = keycloak.createAuthorizationURL(state, codeVerifier, ["openid", "profile", "email"]);
            return html(
                <BaseHtml>
                    <div class="flex h-screen items-center justify-center bg-gray-100 dark:bg-gray-900">
                        <div class="bg-white dark:bg-gray-800 p-8 rounded shadow-md w-96 text-center">
                            <h1 class="text-2xl font-bold mb-6 dark:text-white">Admin Access</h1>
                            <a href={url.toString()} class="block w-full bg-blue-600 text-white p-3 rounded font-bold hover:bg-blue-700 transition-colors">
                                Login with Keycloak
                            </a>
                        </div>
                    </div>
                </BaseHtml>
            );
        } catch (e) {
             return "Error generating Keycloak URL. Check .env configuration.";
        }
    })

    // 2. Callback Handler
    .get("/admin/callback", async ({ query, cookie: { oauth_state, oauth_code_verifier, auth_session }, set }) => {
        const code = query.code as string;
        const state = query.state as string;
        const storedState = oauth_state.value;
        const storedVerifier = oauth_code_verifier.value;

        if (!code || !state || !storedState || !storedVerifier || state !== storedState) {
            return new Response("Invalid State or Code", { status: 400 });
        }

        try {
            const tokens = await keycloak.validateAuthorizationCode(code, storedVerifier);
            auth_session.set({
                value: tokens.accessToken(),
                httpOnly: true,
                path: "/",
                secure: process.env.NODE_ENV === "production",
                maxAge: 86400 // 1 day
            });

            oauth_state.remove();
            oauth_code_verifier.remove();

            return Response.redirect("/admin/dashboard");
        } catch (e: any) {
            console.error("Keycloak Error:", e);
            return new Response(`Authentication failed: ${e.message}\n\nStack: ${e.stack}`, { status: 500 });
        }
    })

    .get("/admin/logout", ({ cookie: { auth_session }, set }) => {
        auth_session.remove();
        return Response.redirect("/admin/login");
    })

    // Protected Routes Guard
    .onBeforeHandle(({ isLoggedIn, set }) => {
        if (!isLoggedIn) return Response.redirect("/admin/login");
    })
    
    // Dashboard
    .get("/admin/dashboard", ({ html }) => {
        const profile = getAdminProfile();
        const experience = getAdminExperience();
        const education = getAdminEducation();
        const projects = getAdminProjects();

        return html(
            <BaseHtml>
                <AdminLayout>
                    <h1 class="text-3xl font-bold mb-6">Dashboard</h1>
                    
                    {/* Profile Section */}
                    <div class="bg-white dark:bg-gray-800 p-6 rounded shadow mb-8">
                        <h2 class="text-2xl font-bold mb-4">Profile</h2>
                        <form action="/admin/profile" method="POST">
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <InputGroup label="Email" name="email" value={profile.email} />
                                <InputGroup label="Phone" name="phone" value={profile.phone} />
                                <InputGroup label="Website" name="website" value={profile.website} />
                                <InputGroup label="Avatar URL" name="avatar_url" value={profile.avatar_url} />
                                <InputGroup label="Github" name="github_url" value={profile.github_url} />
                                <InputGroup label="LinkedIn" name="linkedin_url" value={profile.linkedin_url} />
                            </div>
                            
                            <div class="mt-4 grid grid-cols-1 md:grid-cols-2 gap-6 border-t pt-4 dark:border-gray-700">
                                <div>
                                    <h3 class="font-bold text-lg mb-2 text-blue-600">English</h3>
                                    <InputGroup label="Name" name="name_en" value={profile.name_en} />
                                    <InputGroup label="Job Title" name="job_title_en" value={profile.job_title_en} />
                                    <TextAreaGroup label="Summary" name="summary_en" value={profile.summary_en} />
                                    <InputGroup label="Location" name="location_en" value={profile.location_en} />
                                </div>
                                <div>
                                    <h3 class="font-bold text-lg mb-2 text-blue-600">German</h3>
                                    <InputGroup label="Name" name="name_de" value={profile.name_de} />
                                    <InputGroup label="Job Title" name="job_title_de" value={profile.job_title_de} />
                                    <TextAreaGroup label="Summary" name="summary_de" value={profile.summary_de} />
                                    <InputGroup label="Location" name="location_de" value={profile.location_de} />
                                </div>
                            </div>
                            <button class="mt-4 bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">Save Profile</button>
                        </form>
                    </div>

                    {/* Projects Section */}
                    <div class="bg-white dark:bg-gray-800 p-6 rounded shadow mb-8">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-2xl font-bold">Projects</h2>
                            <button hx-post="/admin/project/new" hx-target="#project-list" hx-swap="beforeend" class="bg-orange-500 text-white px-3 py-1 rounded text-sm hover:bg-orange-600">+ Add Project</button>
                        </div>
                        <div id="project-list" class="">
                            {projects.map((proj: any) => (
                                <ProjectForm proj={proj} />
                            ))}
                        </div>
                    </div>

                    {/* Experience Section */}
                    <div class="bg-white dark:bg-gray-800 p-6 rounded shadow mb-8">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-2xl font-bold">Experience</h2>
                            <button hx-post="/admin/experience/new" hx-target="#experience-list" hx-swap="beforeend" class="bg-blue-500 text-white px-3 py-1 rounded text-sm hover:bg-blue-600">+ Add Job</button>
                        </div>
                        <div id="experience-list" class="">
                            {experience.map((exp: any) => (
                                <ExperienceForm exp={exp} />
                            ))}
                        </div>
                    </div>

                    {/* Education Section */}
                    <div class="bg-white dark:bg-gray-800 p-6 rounded shadow">
                        <div class="flex justify-between items-center mb-4">
                            <h2 class="text-2xl font-bold">Education</h2>
                             <button hx-post="/admin/education/new" hx-target="#education-list" hx-swap="beforeend" class="bg-blue-500 text-white px-3 py-1 rounded text-sm hover:bg-blue-600">+ Add Education</button>
                        </div>
                        <div id="education-list" class="">
                            {education.map((edu: any) => (
                                <EducationForm edu={edu} />
                            ))}
                        </div>
                    </div>

                </AdminLayout>
            </BaseHtml>
        );
    })
    
    // POST Handlers
    .post("/admin/profile", ({ body, set }) => {
        updateProfile(1, body);
        return Response.redirect("/admin/dashboard");
    })
    
    // Projects
    .post("/admin/project/new", ({ set }) => {
        const id = createProject();
        const newItem = getAdminProjectById(Number(id));
        if (!newItem) return "";
        return <ProjectForm proj={newItem} />;
    })
    
    .post("/admin/project/reorder", ({ body }) => {
        const { ids } = body as { ids: string[] };
        updateProjectOrder(ids.map(Number));
        return "OK";
    })

    .post("/admin/project/:id", ({ params, body, set }) => {
        const id = Number(params.id);
        updateProject(id, body);
        const updatedProj = getAdminProjectById(id);
        if (!updatedProj) return "";
        return <ProjectForm proj={updatedProj} />;
    })
    
    .post("/admin/project/:id/delete", ({ params, set }) => {
        deleteProject(Number(params.id));
        return ""; 
    })

    // Experience
    .post("/admin/experience/new", ({ set }) => {
        const id = createExperience();
        const newItem = getAdminExperienceById(Number(id));
        if (!newItem) return "";
        return <ExperienceForm exp={newItem} />;
    })
    
    .post("/admin/experience/reorder", ({ body }) => {
        const { ids } = body as { ids: string[] };
        updateExperienceOrder(ids.map(Number));
        return "OK";
    })

    .post("/admin/experience/:id", ({ params, body, set }) => {
        const id = Number(params.id);
        updateExperience(id, body);
        const updatedExp = getAdminExperienceById(id);
        if (!updatedExp) return "";
        return <ExperienceForm exp={updatedExp} />;
    })
    
    .post("/admin/experience/:id/delete", ({ params, set }) => {
        deleteExperience(Number(params.id));
        return ""; 
    })
    
    // Education
    .post("/admin/education/new", ({ set }) => {
        const id = createEducation();
        const newItem = getAdminEducationById(Number(id));
        if (!newItem) return "";
        return <EducationForm edu={newItem} />;
    })

    .post("/admin/education/reorder", ({ body }) => {
        const { ids } = body as { ids: string[] };
        updateEducationOrder(ids.map(Number));
        return "OK";
    })
    
    .post("/admin/education/:id", ({ params, body, set }) => {
        const id = Number(params.id);
        updateEducation(id, body);
        const updatedEdu = getAdminEducationById(id);
        if (!updatedEdu) return "";
        return <EducationForm edu={updatedEdu} />;
    })
    
    .post("/admin/education/:id/delete", ({ params, set }) => {
        deleteEducation(Number(params.id));
        return "";
    });