import { ContractTaskStatus } from '@prisma/client';
import prisma from '../lib/prisma.js';

export interface ContractTaskFilters {
  contractId: number;
  status?: ContractTaskStatus;
  visibleInPortal?: boolean;
  // Für Kundenportal: Zeige Tasks die entweder sichtbar sind ODER vom Kunden erstellt wurden
  customerPortalEmails?: string[];
}

export async function getTasksByContract(filters: ContractTaskFilters) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const where: any = {
    contractId: filters.contractId,
  };

  if (filters.status) {
    where.status = filters.status;
  }

  // Spezielle Logik für Kundenportal
  if (filters.customerPortalEmails && filters.customerPortalEmails.length > 0) {
    // Zeige Tasks die:
    // 1. visibleInPortal = true ODER
    // 2. vom Kunden selbst erstellt wurden (createdBy in customerPortalEmails)
    where.OR = [
      { visibleInPortal: true },
      { createdBy: { in: filters.customerPortalEmails } },
    ];
  } else if (filters.visibleInPortal !== undefined) {
    where.visibleInPortal = filters.visibleInPortal;
  }

  return prisma.contractTask.findMany({
    where,
    include: {
      subtasks: {
        orderBy: { createdAt: 'asc' },
      },
    },
    orderBy: { createdAt: 'desc' },
  });
}

export async function getTaskById(id: number) {
  return prisma.contractTask.findUnique({
    where: { id },
  });
}

export async function createTask(data: {
  contractId?: number | null;
  title: string;
  description?: string;
  visibleInPortal?: boolean;
  createdBy?: string;
}) {
  // Ohne Vertrag (allgemeine Aufgabe) gibt es keinen Kunden → nie im Portal
  // sichtbar, egal was der Client schickt.
  const hasContract = data.contractId != null;
  return prisma.contractTask.create({
    data: {
      contractId: data.contractId ?? null,
      title: data.title,
      description: data.description,
      visibleInPortal: hasContract ? (data.visibleInPortal ?? false) : false,
      createdBy: data.createdBy,
    },
  });
}

export async function updateTask(
  id: number,
  data: {
    title?: string;
    description?: string;
    visibleInPortal?: boolean;
  }
) {
  return prisma.contractTask.update({
    where: { id },
    data,
  });
}

export async function completeTask(id: number) {
  return prisma.contractTask.update({
    where: { id },
    data: {
      status: 'COMPLETED',
      completedAt: new Date(),
    },
  });
}

export async function reopenTask(id: number) {
  return prisma.contractTask.update({
    where: { id },
    data: {
      status: 'OPEN',
      completedAt: null,
    },
  });
}

export async function deleteTask(id: number) {
  return prisma.contractTask.delete({
    where: { id },
  });
}

// ==================== SUBTASKS ====================

export async function createSubtask(data: { taskId: number; title: string; createdBy?: string }) {
  return prisma.contractTaskSubtask.create({
    data: {
      taskId: data.taskId,
      title: data.title,
      createdBy: data.createdBy,
    },
  });
}

export async function updateSubtask(id: number, data: { title?: string }) {
  return prisma.contractTaskSubtask.update({
    where: { id },
    data,
  });
}

export async function completeSubtask(id: number) {
  // Complete the subtask
  const subtask = await prisma.contractTaskSubtask.update({
    where: { id },
    data: {
      status: 'COMPLETED',
      completedAt: new Date(),
    },
  });

  // Check if all subtasks of the parent task are now completed
  const remainingOpenSubtasks = await prisma.contractTaskSubtask.count({
    where: {
      taskId: subtask.taskId,
      status: 'OPEN',
    },
  });

  // If no open subtasks remain, automatically complete the parent task
  if (remainingOpenSubtasks === 0) {
    await prisma.contractTask.update({
      where: { id: subtask.taskId },
      data: {
        status: 'COMPLETED',
        completedAt: new Date(),
      },
    });
  }

  return subtask;
}

export async function reopenSubtask(id: number) {
  // Reopen the subtask
  const subtask = await prisma.contractTaskSubtask.update({
    where: { id },
    data: {
      status: 'OPEN',
      completedAt: null,
    },
  });

  // If the parent task was completed, reopen it as well
  const parentTask = await prisma.contractTask.findUnique({
    where: { id: subtask.taskId },
  });

  if (parentTask?.status === 'COMPLETED') {
    await prisma.contractTask.update({
      where: { id: subtask.taskId },
      data: {
        status: 'OPEN',
        completedAt: null,
      },
    });
  }

  return subtask;
}

export async function deleteSubtask(id: number) {
  return prisma.contractTaskSubtask.delete({
    where: { id },
  });
}

export async function getSubtaskById(id: number) {
  return prisma.contractTaskSubtask.findUnique({
    where: { id },
    include: { task: true },
  });
}

// ==================== ALL TASKS ====================

export interface AllTasksFilters {
  status?: ContractTaskStatus;
  customerId?: number;
  // Für Kundenportal: Nur Tasks für erlaubte Verträge und sichtbare/eigene Tasks
  customerPortalCustomerIds?: number[];
  customerPortalEmails?: string[];
}

export async function getAllTasks(filters: AllTasksFilters) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const where: any = {};

  if (filters.status) {
    where.status = filters.status;
  }

  // Für Kundenportal: Filter auf erlaubte Verträge + Sichtbarkeit
  if (filters.customerPortalCustomerIds && filters.customerPortalCustomerIds.length > 0) {
    where.contract = {
      customerId: { in: filters.customerPortalCustomerIds },
    };
    // Zeige nur sichtbare Tasks ODER vom Kunden erstellte
    if (filters.customerPortalEmails && filters.customerPortalEmails.length > 0) {
      where.OR = [
        { visibleInPortal: true },
        { createdBy: { in: filters.customerPortalEmails } },
      ];
    } else {
      where.visibleInPortal = true;
    }
  } else if (filters.customerId) {
    // Für Mitarbeiter: Optional nach Kunde filtern
    where.contract = {
      customerId: filters.customerId,
    };
  }

  return prisma.contractTask.findMany({
    where,
    include: {
      subtasks: {
        orderBy: { createdAt: 'asc' },
      },
      contract: {
        select: {
          id: true,
          contractNumber: true,
          customerId: true,
          customer: {
            select: {
              id: true,
              firstName: true,
              lastName: true,
              companyName: true,
              customerNumber: true,
            },
          },
          provider: {
            select: {
              id: true,
              name: true,
            },
          },
          tariff: {
            select: {
              id: true,
              name: true,
            },
          },
          providerName: true,
          tariffName: true,
        },
      },
    },
    orderBy: { createdAt: 'desc' },
  });
}

export async function getTaskStats(filters: AllTasksFilters) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const where: any = {
    status: 'OPEN',
  };

  // Für Kundenportal: Filter auf erlaubte Verträge + Sichtbarkeit
  if (filters.customerPortalCustomerIds && filters.customerPortalCustomerIds.length > 0) {
    where.contract = {
      customerId: { in: filters.customerPortalCustomerIds },
    };
    // Zeige nur sichtbare Tasks ODER vom Kunden erstellte
    if (filters.customerPortalEmails && filters.customerPortalEmails.length > 0) {
      where.OR = [
        { visibleInPortal: true },
        { createdBy: { in: filters.customerPortalEmails } },
      ];
    } else {
      where.visibleInPortal = true;
    }
  } else if (filters.customerId) {
    where.contract = {
      customerId: filters.customerId,
    };
  }

  const openCount = await prisma.contractTask.count({ where });

  return { openCount };
}
