/**
 * POST /report
 *
 * Design intent:
 * - Strict reasons only.
 * - Reports never auto-remove content.
 * - Reporting accuracy affects reporter trust.
 *
 * Flow:
 * 1. Validate auth and inputs
 * 2. Ensure target exists and is visible
 * 3. Create report record
 * 4. Log audit event
 * 5. Queue for moderation review
 */

import { serve } from 'https://deno.land/std@0.177.0/http/server.ts';
import { createSupabaseClient, createServiceClient } from '../_shared/supabase-client.ts';
import { validateReportReason, validateUUID, ValidationError } from '../_shared/validation.ts';

type TargetType = 'post' | 'comment' | 'profile';

interface ReportRequest {
  target_type: TargetType;
  target_id: string;
  reason: string;
}

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, {
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST',
        'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
      },
    });
  }

  try {
    // 1. Validate auth
    const authHeader = req.headers.get('Authorization');
    if (!authHeader) {
      return new Response(JSON.stringify({ error: 'Missing authorization header' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    const supabase = createSupabaseClient(authHeader);
    const {
      data: { user },
      error: authError,
    } = await supabase.auth.getUser();

    if (authError || !user) {
      return new Response(JSON.stringify({ error: 'Unauthorized' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    // 2. Parse request
    const { target_type, target_id, reason } = (await req.json()) as ReportRequest;

    // 3. Validate inputs
    if (!['post', 'comment', 'profile'].includes(target_type)) {
      throw new ValidationError('Invalid target type', 'target_type');
    }

    validateUUID(target_id, 'target_id');
    validateReportReason(reason);

    // 4. Verify target exists and is visible to reporter
    let targetExists = false;
    let targetAuthorId: string | null = null;

    if (target_type === 'post') {
      const { data: post } = await supabase
        .from('posts')
        .select('author_id')
        .eq('id', target_id)
        .single();

      if (post) {
        targetExists = true;
        targetAuthorId = post.author_id;
      }
    } else if (target_type === 'comment') {
      const { data: comment } = await supabase
        .from('comments')
        .select('author_id')
        .eq('id', target_id)
        .single();

      if (comment) {
        targetExists = true;
        targetAuthorId = comment.author_id;
      }
    } else if (target_type === 'profile') {
      const { data: profile } = await supabase
        .from('profiles')
        .select('id')
        .eq('id', target_id)
        .single();

      if (profile) {
        targetExists = true;
        targetAuthorId = target_id;
      }
    }

    if (!targetExists) {
      return new Response(
        JSON.stringify({
          error: 'Target not found',
          message: 'The content you are trying to report does not exist or you cannot see it.',
        }),
        {
          status: 404,
          headers: { 'Content-Type': 'application/json' },
        }
      );
    }

    // 5. Prevent self-reporting
    if (targetAuthorId === user.id) {
      return new Response(
        JSON.stringify({
          error: 'Invalid report',
          message: 'You cannot report your own content.',
        }),
        {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        }
      );
    }

    // 6. Check for duplicate reports (constraint will prevent, but give better message)
    const { data: existingReport } = await supabase
      .from('reports')
      .select('id')
      .eq('reporter_id', user.id)
      .eq('target_type', target_type)
      .eq('target_id', target_id)
      .single();

    if (existingReport) {
      return new Response(
        JSON.stringify({
          error: 'Duplicate report',
          message: 'You have already reported this.',
        }),
        {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        }
      );
    }

    // 7. Create report
    const { data: report, error: reportError } = await supabase
      .from('reports')
      .insert({
        reporter_id: user.id,
        target_type,
        target_id,
        reason,
        status: 'pending',
      })
      .select()
      .single();

    if (reportError) {
      console.error('Error creating report:', reportError);
      return new Response(JSON.stringify({ error: 'Failed to create report' }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' },
      });
    }

    // 8. Update reporter's trust counters
    const serviceClient = createServiceClient();
    await serviceClient.rpc('log_audit_event', {
      p_actor_id: user.id,
      p_event_type: 'report_filed',
      p_payload: {
        report_id: report.id,
        target_type,
        target_id,
        target_author_id: targetAuthorId,
      },
    });

    // Increment reports_filed counter
    const { error: counterError } = await serviceClient
      .from('trust_state')
      .update({
        counters: supabase.rpc('jsonb_set', {
          target: supabase.rpc('counters'),
          path: '{reports_filed}',
          new_value: supabase.rpc('to_jsonb', [
            supabase.rpc('jsonb_extract_path_text', ['counters', 'reports_filed']) + 1,
          ]),
        }),
        updated_at: new Date().toISOString(),
      })
      .eq('user_id', user.id);

    if (counterError) {
      console.warn('Failed to update report counter:', counterError);
      // Continue anyway - report was created
    }

    // 9. Return success
    return new Response(
      JSON.stringify({
        success: true,
        report_id: report.id,
        message:
          'Report received. All reports are reviewed. False reports may affect your account standing.',
      }),
      {
        status: 201,
        headers: { 'Content-Type': 'application/json' },
      }
    );
  } catch (error) {
    if (error instanceof ValidationError) {
      return new Response(
        JSON.stringify({
          error: 'Validation error',
          message: error.message,
          field: error.field,
        }),
        {
          status: 400,
          headers: { 'Content-Type': 'application/json' },
        }
      );
    }

    console.error('Unexpected error:', error);
    return new Response(JSON.stringify({ error: 'Internal server error' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' },
    });
  }
});
