use rouille::{input::json_input, Request, Response};
use serde_json::json;
use std::sync::Arc;

use super::helpers::{get_conn, json_error, require_auth};
use super::AppState;

pub fn list(request: &Request, state: &Arc<AppState>) -> Response {
    let mut conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    if let Err(e) = require_auth(request, &mut conn) {
        return e;
    }

    match conn.query(
        "SELECT id, url, name, is_active, created_at::text \
         FROM webhooks WHERE is_active = true ORDER BY created_at DESC",
        &[],
    ) {
        Ok(rows) => {
            let webhooks: Vec<_> = rows
                .into_iter()
                .map(|row| {
                    json!({
                        "id": row.get::<_, i32>(0),
                        "url": row.get::<_, String>(1),
                        "name": row.get::<_, String>(2),
                        "is_active": row.get::<_, bool>(3),
                        "created_at": row.get::<_, String>(4),
                    })
                })
                .collect();
            Response::json(&webhooks)
        }
        Err(e) => {
            log::error!("Database error: {}", e);
            json_error(500, "Database error")
        }
    }
}

pub fn create(request: &Request, state: &Arc<AppState>) -> Response {
    let data: serde_json::Value = match json_input(request) {
        Ok(f) => f,
        Err(_) => return json_error(400, "Invalid JSON"),
    };

    let mut conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    if let Err(e) = require_auth(request, &mut conn) {
        return e;
    }

    let url = data.get("url").and_then(|v| v.as_str()).unwrap_or_default().to_string();
    let name = data.get("name").and_then(|v| v.as_str()).unwrap_or(&url).to_string();
    let event_type = data.get("event_type").and_then(|v| v.as_str()).unwrap_or("sync_complete").to_string();
    let events_json = serde_json::to_string(&vec![&event_type]).unwrap_or_default();

    match conn.query_one(
        "INSERT INTO webhooks (name, url, events, is_active) \
         VALUES ($1, $2, $3::text::jsonb, $4) RETURNING id",
        &[&name, &url, &events_json, &true],
    ) {
        Ok(r) => Response::json(&json!({
            "id": r.get::<_, i32>(0), "name": name, "url": url,
            "event_type": event_type, "is_active": true,
        })),
        Err(e) => {
            log::error!("Database error: {}", e);
            json_error(500, "Database error")
        }
    }
}

pub fn delete(request: &Request, state: &Arc<AppState>, id: i32) -> Response {
    let mut conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    if let Err(e) = require_auth(request, &mut conn) {
        return e;
    }

    match conn.execute("DELETE FROM webhooks WHERE id = $1", &[&id]) {
        Ok(0) => json_error(404, "Webhook not found"),
        Ok(_) => Response::json(&json!({"message": "Webhook deleted"})),
        Err(e) => json_error(500, &format!("Delete error: {}", e)),
    }
}
