import type { Context } from "koa";
import { ObjectId } from "mongodb";
import dbConfig from "../config/database";
import type { Transaction } from "../models";
import DatabaseService from "../services/database";
import pushController from "./push";

const db = DatabaseService.getInstance();

export default {
  // Protected endpoint that requires authentication
  async getProtectedData(ctx: Context) {
    // The user property is added by koa-jwt middleware
    const user = (ctx.state as any).user;

    ctx.body = {
      success: true,
      message: "You have access to protected data",
      data: {
        secret: "This is protected data",
        timestamp: new Date().toISOString(),
        user: user.username,
        userId: user.id,
      },
    };
  },

  // Get user's transactions
  async getUserTransactions(ctx: Context) {
    const user = (ctx.state as any).user;
    const userId = user.id;

    try {
      const transactionsCollection = db.getCollection<Transaction>(
        dbConfig.collections.transactions,
      );

      // Get the latest 10 transactions for the user
      const transactions = await transactionsCollection
        .find({
          userId: new ObjectId(String(userId)),
        })
        .sort({ date: -1 })
        .limit(10)
        .toArray();

      ctx.body = {
        success: true,
        data: transactions,
      };
    } catch (error) {
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: "Error retrieving transactions",
        error: (error as Error).message,
      };
    }
  },

  // Add new transaction
  async addTransaction(ctx: Context) {
    const user = (ctx.state as any).user;
    const userId = user.id;

    try {
      const { amount, type, categoryId, description, date } = ctx.request
        .body as {
        amount: number;
        type: "income" | "expense";
        categoryId: string;
        description: string;
        date?: string;
      };

      console.log("Received transaction data:", ctx.request.body);

      // Validate input
      if (!amount || !type || !categoryId) {
        ctx.status = 400;
        ctx.body = {
          success: false,
          message: "Amount, type and category are required",
        };
        return;
      }

      const transactionsCollection = db.getCollection<Transaction>(
        dbConfig.collections.transactions,
      );

      const now = new Date();
      const transactionDate = date ? new Date(date) : now;

      // Check if categoryId is a valid ObjectId
      let categoryObjectId;
      try {
        categoryObjectId = new ObjectId(categoryId);
      } catch (err) {
        ctx.status = 400;
        ctx.body = {
          success: false,
          message: "Invalid category ID format",
        };
        return;
      }

      const newTransaction: Transaction = {
        userId: new ObjectId(userId),
        amount: Number(amount),
        type,
        categoryId: categoryObjectId,
        description: description || "",
        date: transactionDate,
        createdAt: now,
        updatedAt: now,
      };

      console.log("Inserting transaction:", newTransaction);
      const result = await transactionsCollection.insertOne(newTransaction);
      
      // Send push notification for the new transaction
      try {
        await pushController.sendTransactionNotification(
          userId,
          { ...newTransaction, _id: result.insertedId }
        );
      } catch (notificationError) {
        console.error("Failed to send notification:", notificationError);
        // Continue even if notification fails
      }

      ctx.status = 201;
      ctx.body = {
        success: true,
        message: "Transaction added successfully",
        transactionId: result.insertedId,
      };
    } catch (error) {
      console.error("Transaction error:", error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: "Error adding transaction",
        error: (error as Error).message,
      };
    }
  },
};
