import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/auth";
import { prisma } from "@/lib/db";

function slugify(name: string): string {
  return name
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

export async function GET() {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const membership = await prisma.orgMember.findFirst({
      where: { userId: session.user.id },
      include: {
        organization: {
          select: {
            id: true,
            onboardingComplete: true,
            onboardingStep: true,
          },
        },
      },
    });

    if (!membership) {
      return NextResponse.json({
        onboardingComplete: false,
        currentStep: 0,
        orgId: null,
      });
    }

    return NextResponse.json({
      onboardingComplete: membership.organization.onboardingComplete,
      currentStep: membership.organization.onboardingStep,
      orgId: membership.organizationId,
    });
  } catch (error) {
    console.error("[onboarding] GET error:", error);
    return NextResponse.json(
      { error: "Failed to fetch onboarding status" },
      { status: 500 }
    );
  }
}

export async function POST(req: NextRequest) {
  try {
    const session = await auth();
    if (!session?.user?.id) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    const body = await req.json();
    const { step, data } = body;

    const membership = await prisma.orgMember.findFirst({
      where: { userId: session.user.id },
      include: {
        organization: {
          select: { id: true, onboardingComplete: true, onboardingStep: true },
        },
      },
    });

    switch (step) {
      case 1: {
        const { name, type, timezone } = data;
        if (!name) {
          return NextResponse.json(
            { error: "Organization name is required" },
            { status: 400 }
          );
        }

        if (membership) {
          await prisma.organization.update({
            where: { id: membership.organizationId },
            data: {
              name,
              slug: slugify(name),
              type: type || "church",
              timezone: timezone || "America/Chicago",
              onboardingStep: 1,
            },
          });
          return NextResponse.json({
            nextStep: 2,
            orgId: membership.organizationId,
          });
        }

        const org = await prisma.organization.create({
          data: {
            name,
            slug: slugify(name),
            type: type || "church",
            timezone: timezone || "America/Chicago",
            onboardingStep: 1,
          },
        });

        await prisma.orgMember.create({
          data: {
            userId: session.user.id,
            organizationId: org.id,
            role: "owner",
          },
        });

        await prisma.user.update({
          where: { id: session.user.id },
          data: { activeOrgId: org.id },
        });

        return NextResponse.json({ nextStep: 2, orgId: org.id });
      }

      case 2: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete step 1 first" },
            { status: 400 }
          );
        }

        const { locations } = data;
        if (!locations || !Array.isArray(locations) || locations.length === 0) {
          return NextResponse.json(
            { error: "At least one location is required" },
            { status: 400 }
          );
        }

        for (const loc of locations) {
          if (!loc.name) continue;
          const existing = await prisma.location.findFirst({
            where: {
              organizationId: membership.organizationId,
              name: loc.name,
            },
          });
          if (!existing) {
            await prisma.location.create({
              data: {
                name: loc.name,
                address: loc.address || null,
                organizationId: membership.organizationId,
              },
            });
          }
        }

        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingStep: 2 },
        });

        return NextResponse.json({ nextStep: 3 });
      }

      case 3: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete previous steps first" },
            { status: 400 }
          );
        }

        const { services } = data;
        if (services && Array.isArray(services)) {
          const locations = await prisma.location.findMany({
            where: { organizationId: membership.organizationId },
            take: 1,
          });
          const locationId = locations[0]?.id;

          if (locationId) {
            for (const svc of services) {
              if (!svc.name) continue;
              await prisma.collectionDay.create({
                data: {
                  locationId,
                  name: svc.name,
                  dayOfWeek: svc.dayOfWeek ?? 0,
                  timeStart: svc.timeStart || null,
                  timeEnd: svc.timeEnd || null,
                  isRecurring: true,
                },
              });
            }
          }
        }

        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingStep: 3 },
        });

        return NextResponse.json({ nextStep: 4 });
      }

      case 4: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete previous steps first" },
            { status: 400 }
          );
        }

        const { uploadSource } = data;

        if (uploadSource === "email" && data.emailConfig) {
          await prisma.appSettings.upsert({
            where: { id: "singleton" },
            update: {
              emailImapHost: data.emailConfig.host || "",
              emailImapPort: data.emailConfig.port || 993,
              emailImapUser: data.emailConfig.user || "",
              emailImapPass: data.emailConfig.pass || "",
              emailImapTls: data.emailConfig.tls ?? true,
            },
            create: { id: "singleton" },
          });
        }

        if (uploadSource === "folder" && data.watchDir) {
          await prisma.appSettings.upsert({
            where: { id: "singleton" },
            update: { watchDir: data.watchDir },
            create: { id: "singleton" },
          });
        }

        if (uploadSource === "api") {
          const crypto = await import("crypto");
          const rawKey = `ek_${crypto.randomBytes(24).toString("hex")}`;
          const hashedKey = crypto
            .createHash("sha256")
            .update(rawKey)
            .digest("hex");

          await prisma.apiKey.create({
            data: {
              name: "Onboarding API Key",
              hashedKey,
              prefix: rawKey.slice(0, 7),
              organizationId: membership.organizationId,
              permissions: ["cards:create", "cards:read"],
            },
          });

          await prisma.organization.update({
            where: { id: membership.organizationId },
            data: { onboardingStep: 4 },
          });

          return NextResponse.json({ nextStep: 5, apiKey: rawKey });
        }

        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingStep: 4 },
        });

        return NextResponse.json({ nextStep: 5 });
      }

      case 5: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete previous steps first" },
            { status: 400 }
          );
        }

        const { aiProvider, aiModel } = data;
        await prisma.appSettings.upsert({
          where: { id: "singleton" },
          update: {
            aiProvider: aiProvider || "gateway",
            aiModel: aiModel || "",
          },
          create: {
            id: "singleton",
            aiProvider: aiProvider || "gateway",
            aiModel: aiModel || "",
          },
        });

        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingStep: 5 },
        });

        return NextResponse.json({ nextStep: 6 });
      }

      case 6: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete previous steps first" },
            { status: 400 }
          );
        }

        // Integration selection is optional — just advance step
        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingStep: 6 },
        });

        return NextResponse.json({ nextStep: 7 });
      }

      case 7: {
        if (!membership) {
          return NextResponse.json(
            { error: "Complete previous steps first" },
            { status: 400 }
          );
        }

        await prisma.organization.update({
          where: { id: membership.organizationId },
          data: { onboardingComplete: true, onboardingStep: 7 },
        });

        await prisma.systemConfig.upsert({
          where: { id: "singleton" },
          update: { isSetupComplete: true },
          create: { id: "singleton", isSetupComplete: true },
        });

        return NextResponse.json({ complete: true });
      }

      default:
        return NextResponse.json(
          { error: "Invalid step" },
          { status: 400 }
        );
    }
  } catch (error) {
    console.error("[onboarding] POST error:", error);
    return NextResponse.json(
      { error: "Onboarding step failed" },
      { status: 500 }
    );
  }
}
