/**
 * Provider Approval Workflow Service
 * Manages provider onboarding, KYC verification, and approval process
 */

import { db } from './db.ts';
import { sql } from 'drizzle-orm';

export interface ProviderApplication {
  id: string;
  companyName: string;
  contactEmail: string;
  contactPhone: string;
  website: string;
  description: string;
  gameCount: number;
  status: 'draft' | 'submitted' | 'under_review' | 'kyc_pending' | 'approved' | 'rejected';
  kycStatus: 'not_started' | 'in_progress' | 'verified' | 'failed';
  kycDocuments: string[];
  submittedAt: Date;
  reviewedAt?: Date;
  reviewedBy?: string;
  rejectionReason?: string;
  auditTrail: AuditEntry[];
}

export interface AuditEntry {
  timestamp: Date;
  action: string;
  performedBy: string;
  details: string;
  status: string;
}

export interface KYCVerification {
  providerId: string;
  businessRegistration: string;
  taxId: string;
  ownerName: string;
  ownerAddress: string;
  bankAccount: string;
  documents: KYCDocument[];
  verificationDate?: Date;
  verificationStatus: 'pending' | 'verified' | 'rejected';
}

export interface KYCDocument {
  type: 'business_registration' | 'tax_id' | 'owner_id' | 'bank_statement' | 'other';
  url: string;
  uploadedAt: Date;
  verified: boolean;
}

// In-memory storage for demo (replace with database)
const applications = new Map<string, ProviderApplication>();
const kycVerifications = new Map<string, KYCVerification>();

export async function createProviderApplication(
  data: Omit<ProviderApplication, 'id' | 'status' | 'kycStatus' | 'submittedAt' | 'auditTrail'>
): Promise<ProviderApplication> {
  const id = `provider_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  
  const application: ProviderApplication = {
    ...data,
    id,
    status: 'draft',
    kycStatus: 'not_started',
    kycDocuments: [],
    submittedAt: new Date(),
    auditTrail: [
      {
        timestamp: new Date(),
        action: 'APPLICATION_CREATED',
        performedBy: 'system',
        details: `Application created for ${data.companyName}`,
        status: 'draft',
      },
    ],
  };

  applications.set(id, application);
  return application;
}

export async function submitProviderApplication(
  applicationId: string,
  submittedBy: string
): Promise<ProviderApplication> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');

  app.status = 'submitted';
  app.auditTrail.push({
    timestamp: new Date(),
    action: 'APPLICATION_SUBMITTED',
    performedBy: submittedBy,
    details: 'Provider submitted application for review',
    status: 'submitted',
  });

  applications.set(applicationId, app);
  return app;
}

export async function startKYCVerification(
  applicationId: string,
  reviewedBy: string
): Promise<ProviderApplication> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');

  app.status = 'kyc_pending';
  app.kycStatus = 'in_progress';
  app.reviewedBy = reviewedBy;
  app.auditTrail.push({
    timestamp: new Date(),
    action: 'KYC_STARTED',
    performedBy: reviewedBy,
    details: 'KYC verification process initiated',
    status: 'kyc_pending',
  });

  applications.set(applicationId, app);
  return app;
}

export async function verifyKYC(
  applicationId: string,
  kycData: KYCVerification,
  verifiedBy: string
): Promise<ProviderApplication> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');

  kycData.verificationDate = new Date();
  kycData.verificationStatus = 'verified';
  kycVerifications.set(applicationId, kycData);

  app.kycStatus = 'verified';
  app.status = 'under_review';
  app.auditTrail.push({
    timestamp: new Date(),
    action: 'KYC_VERIFIED',
    performedBy: verifiedBy,
    details: 'KYC verification completed successfully',
    status: 'under_review',
  });

  applications.set(applicationId, app);
  return app;
}

export async function approveProvider(
  applicationId: string,
  approvedBy: string,
  notes?: string
): Promise<ProviderApplication> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');

  app.status = 'approved';
  app.reviewedAt = new Date();
  app.reviewedBy = approvedBy;
  app.auditTrail.push({
    timestamp: new Date(),
    action: 'PROVIDER_APPROVED',
    performedBy: approvedBy,
    details: `Provider approved${notes ? ': ' + notes : ''}`,
    status: 'approved',
  });

  applications.set(applicationId, app);
  return app;
}

export async function rejectProvider(
  applicationId: string,
  rejectedBy: string,
  reason: string
): Promise<ProviderApplication> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');

  app.status = 'rejected';
  app.rejectionReason = reason;
  app.reviewedAt = new Date();
  app.reviewedBy = rejectedBy;
  app.auditTrail.push({
    timestamp: new Date(),
    action: 'PROVIDER_REJECTED',
    performedBy: rejectedBy,
    details: `Provider rejected: ${reason}`,
    status: 'rejected',
  });

  applications.set(applicationId, app);
  return app;
}

export async function getProviderApplication(applicationId: string): Promise<ProviderApplication | null> {
  return applications.get(applicationId) || null;
}

export async function listProviderApplications(
  status?: string,
  limit = 50,
  offset = 0
): Promise<{ applications: ProviderApplication[]; total: number }> {
  let filtered = Array.from(applications.values());

  if (status) {
    filtered = filtered.filter((app) => app.status === status);
  }

  const total = filtered.length;
  const paginated = filtered.slice(offset, offset + limit);

  return { applications: paginated, total };
}

export async function getAuditTrail(applicationId: string): Promise<AuditEntry[]> {
  const app = applications.get(applicationId);
  if (!app) throw new Error('Application not found');
  return app.auditTrail;
}

export async function getKYCVerification(applicationId: string): Promise<KYCVerification | null> {
  return kycVerifications.get(applicationId) || null;
}

export async function getProviderStats(): Promise<{
  totalApplications: number;
  approved: number;
  rejected: number;
  pending: number;
  underReview: number;
}> {
  const apps = Array.from(applications.values());

  return {
    totalApplications: apps.length,
    approved: apps.filter((a) => a.status === 'approved').length,
    rejected: apps.filter((a) => a.status === 'rejected').length,
    pending: apps.filter((a) => a.status === 'submitted').length,
    underReview: apps.filter((a) => a.status === 'under_review').length,
  };
}

export async function uploadKYCDocument(
  applicationId: string,
  document: KYCDocument
): Promise<KYCVerification> {
  let kyc = kycVerifications.get(applicationId);
  if (!kyc) {
    kyc = {
      providerId: applicationId,
      businessRegistration: '',
      taxId: '',
      ownerName: '',
      ownerAddress: '',
      bankAccount: '',
      documents: [],
      verificationStatus: 'pending',
    };
  }

  kyc.documents.push(document);
  kycVerifications.set(applicationId, kyc);
  return kyc;
}
