import type {
  ContractDeliverableStatus,
  ContractDocumentKind,
  ContractPaymentStatus,
  ContractStatus,
} from "@prisma/client";
import { z } from "zod";

export type ContractKpiSnapshot = {
  activeContracts: number;
  totalCollected: number;
  pendingDeliverables: number;
  overdueDeliverables: number;
};

export type ContractProgressSnapshot = {
  completed: number;
  total: number;
  percent: number;
};

export type ContractDeliverableView = {
  id: string;
  contractId: string;
  title: string;
  dueDate: string | null;
  amountLinked: number | null;
  status: ContractDeliverableStatus;
  deliveredAt: string | null;
  approvedAt: string | null;
  notes: string;
  isOverdue: boolean;
  createdAt: string;
  updatedAt: string;
};

export type ContractPaymentView = {
  id: string;
  contractId: string;
  amount: number;
  paymentDate: string;
  invoiceNumber: string | null;
  concept: string;
  status: ContractPaymentStatus;
  createdAt: string;
  updatedAt: string;
};

export type ContractDocumentView = {
  id: string;
  contractId: string;
  fileName: string;
  filePath: string;
  mimeType: string;
  sizeBytes: number;
  checksumSha256: string | null;
  kind: ContractDocumentKind;
  createdAt: string;
};

export type ContractRecordView = {
  id: string;
  sourceProposalId: string | null;
  title: string;
  counterpartyEntity: string;
  contractNumber: string | null;
  contractType: string;
  startDate: string | null;
  endDate: string | null;
  totalAmount: number | null;
  currency: string;
  status: ContractStatus;
  description: string;
  progress: ContractProgressSnapshot;
  isActiveOperational: boolean;
  createdAt: string;
  updatedAt: string;
  deliverables: ContractDeliverableView[];
  payments: ContractPaymentView[];
  documents: ContractDocumentView[];
};

export type ContractExtractionWarning = {
  code: string;
  message: string;
};

export type ContractRiskClause = {
  title: string;
  snippet: string;
  riskLevel: "low" | "medium" | "high";
  requiresLegalValidation: boolean;
};

export type ContractDeliverableExtracted = {
  title: string;
  dueDate: string | null;
  amountLinked: number | null;
  notes: string | null;
};

export type ContractPaymentMilestoneExtracted = {
  concept: string;
  paymentDate: string | null;
  amount: number | null;
};

export type ContractAiExtractionInput = {
  fileName: string;
  text: string;
};

export type ContractAiExtractionOutput = {
  fields: {
    title: string | null;
    counterpartyEntity: string | null;
    contractNumber: string | null;
    contractType: string | null;
    startDate: string | null;
    endDate: string | null;
    totalAmount: number | null;
    currency: string | null;
    description: string | null;
  };
  deliverables: ContractDeliverableExtracted[];
  paymentMilestones: ContractPaymentMilestoneExtracted[];
  riskClauses: ContractRiskClause[];
  warnings: ContractExtractionWarning[];
  engine: "openai_json_object" | "regex_fallback";
  model: string | null;
  usage:
    | {
        promptTokens: number | null;
        completionTokens: number | null;
        totalTokens: number | null;
      }
    | null;
};

export const ContractCreateInputSchema = z.object({
  sourceProposalId: z.string().trim().min(1).optional().nullable(),
  title: z.string().trim().min(3).max(220),
  counterpartyEntity: z.string().trim().min(2).max(220),
  contractNumber: z.string().trim().max(120).optional().nullable(),
  contractType: z.string().trim().min(2).max(120),
  startDate: z.string().datetime().optional().nullable(),
  endDate: z.string().datetime().optional().nullable(),
  totalAmount: z.number().finite().nonnegative().optional().nullable(),
  currency: z.string().trim().min(3).max(10).optional(),
  status: z.enum(["ACTIVE", "COMPLETED", "PAUSED", "CANCELLED"]).optional(),
  description: z.string().trim().max(6000).optional(),
});

export const ContractUpdateInputSchema = ContractCreateInputSchema.partial().extend({
  status: z.enum(["ACTIVE", "COMPLETED", "PAUSED", "CANCELLED"]).optional(),
});

export const ContractListFiltersSchema = z.object({
  q: z.string().trim().optional(),
  status: z.enum(["ACTIVE", "COMPLETED", "PAUSED", "CANCELLED"]).optional(),
  sort: z.enum(["updatedAt", "endDate", "createdAt"]).optional(),
});

export const DeliverableCreateInputSchema = z.object({
  title: z.string().trim().min(2).max(220),
  dueDate: z.string().datetime().optional().nullable(),
  amountLinked: z.number().finite().nonnegative().optional().nullable(),
  notes: z.string().trim().max(3000).optional(),
});

export const DeliverableUpdateInputSchema = z.object({
  status: z.enum(["PENDING", "DELIVERED", "APPROVED", "REJECTED", "OVERDUE"]).optional(),
  dueDate: z.string().datetime().optional().nullable(),
  deliveredAt: z.string().datetime().optional().nullable(),
  approvedAt: z.string().datetime().optional().nullable(),
  notes: z.string().trim().max(3000).optional(),
  amountLinked: z.number().finite().nonnegative().optional().nullable(),
  title: z.string().trim().min(2).max(220).optional(),
});

export const PaymentCreateInputSchema = z.object({
  amount: z.number().finite().positive(),
  paymentDate: z.string().datetime(),
  invoiceNumber: z.string().trim().max(120).optional().nullable(),
  concept: z.string().trim().min(2).max(500),
  status: z.enum(["REGISTERED", "CONFIRMED", "DISPUTED"]).optional(),
});

export type ContractCreateInput = z.infer<typeof ContractCreateInputSchema>;
export type ContractUpdateInput = z.infer<typeof ContractUpdateInputSchema>;
export type ContractListFilters = z.infer<typeof ContractListFiltersSchema>;
export type DeliverableCreateInput = z.infer<typeof DeliverableCreateInputSchema>;
export type DeliverableUpdateInput = z.infer<typeof DeliverableUpdateInputSchema>;
export type PaymentCreateInput = z.infer<typeof PaymentCreateInputSchema>;
