import { NextRequest, NextResponse } from 'next/server';
import { dbHelpers } from '@/lib/db';
import { getSession } from '@/lib/auth';
import { createProjectSchema } from '@/lib/validators';
import { isLegacyLanguage, normalizeTier } from '@/lib/plan-access';
import { canCreateProjectInCompany } from '@/lib/companies';
import { db, schema } from '@/lib/db';
import { eq } from 'drizzle-orm';
import {
  applyMarkersToProjectPayloadConfig,
  buildMarkerMetadata,
} from '@/lib/export-bundle';

export async function GET(request: NextRequest) {
  try {
    const accessToken = request.cookies.get('scriba.access_token')?.value;
    const session = await getSession(accessToken);

    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const projects = await dbHelpers.getAllProjects();
    
    // Admins can see all projects.
    // Company owners can see all projects in their company.
    // Other users see only their own projects.
    let visibleProjects = projects.filter((p: any) => p.userId === session.user.id);
    if (session.user.role === 'admin') {
      visibleProjects = projects;
    } else if (session.user.isOwner && session.user.companyId) {
      const companyUsers = await db.query.users.findMany({
        where: eq(schema.users.companyId, session.user.companyId),
        columns: { id: true },
      });
      const companyUserIds = new Set(companyUsers.map((u) => u.id));
      visibleProjects = projects.filter((p: any) => companyUserIds.has(p.userId));
    }
    
    // Parse JSON fields (PostgreSQL returns JSONB as objects, but we normalize to ensure consistency)
    const parsedProjects = visibleProjects.map((p: any) => ({
      ...p,
      tags: Array.isArray(p.tags) ? p.tags : JSON.parse(p.tags || '[]'),
      team: Array.isArray(p.team) ? p.team : JSON.parse(p.team || '[]'),
      activity: Array.isArray(p.activity) ? p.activity : JSON.parse(p.activity || '[]'),
    })).map((p: any) => ({
      ...p,
      config: applyMarkersToProjectPayloadConfig(
        (p.config ?? {}) as Record<string, unknown>,
        buildMarkerMetadata(p)
      ),
    }));
    
    return NextResponse.json({ conversions: parsedProjects, projects: parsedProjects });
  } catch (error) {
    console.error('Error fetching conversions:', error);
    return NextResponse.json({ error: 'Failed to fetch conversions' }, { status: 500 });
  }
}

export async function POST(request: NextRequest) {
  try {
    const accessToken = request.cookies.get('scriba.access_token')?.value;
    const session = await getSession(accessToken);

    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const body = await request.json();
    const parsed = createProjectSchema.safeParse(body);
    if (!parsed.success) {
      return NextResponse.json({ error: parsed.error.issues[0]?.message ?? 'Input non valido' }, { status: 400 });
    }
    const { id, name, description, sourceLanguage, targetLanguage, repoUrl, tags, team, status: projectStatus, config } = parsed.data;

    // Guard against duplicate IDs (client-generated; DB unique constraint would return 500 otherwise)
    const existing = await db.query.projects.findFirst({
      where: eq(schema.projects.id, id),
      columns: { id: true },
    });
    if (existing) {
      return NextResponse.json({ error: 'A project with this ID already exists' }, { status: 409 });
    }

    // Enforce language tier gating server-side (company package is source of truth).
    const companyId = (session.user as any).companyId as string | null;
    const companyTier = companyId
      ? await db.query.companies.findFirst({
          where: eq(schema.companies.id, companyId),
          columns: { package: true },
        }).then((company) => company?.package ?? null)
      : null;
    const tier = normalizeTier(companyTier ?? (session.user as any).tier);
    if (tier === 'starter' && sourceLanguage && isLegacyLanguage(sourceLanguage)) {
      return NextResponse.json(
        { error: 'Legacy and mainframe languages require a Professional or Enterprise plan.' },
        { status: 403 }
      );
    }

    // Enforce company project cap
    if (companyId) {
      const canCreate = await canCreateProjectInCompany(companyId);
      if (!canCreate.allowed) {
        return NextResponse.json({ error: canCreate.reason }, { status: 403 });
      }
    }

    const newProject = await dbHelpers.createProject({
      id,
      name,
      description,
      sourceLanguage,
      targetLanguage,
      repoUrl,
      tags,
      team,
      userId: session.user.id,
      status: projectStatus || 'draft',
      config: config || {}
    });

    return NextResponse.json({ success: true, conversion: newProject, project: newProject }, { status: 201 });
  } catch (error) {
    console.error('Error creating conversion:', error);
    return NextResponse.json({ error: 'Failed to create conversion' }, { status: 500 });
  }
}
