// app/api/auth/signup-with-vendor/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { unstable_noStore } from 'next/cache'
import { revalidateTag } from 'next/cache'
import { eq, and } from 'drizzle-orm'
import { PgTransaction } from 'drizzle-orm/pg-core'

import db from '@/db/db'
import { 
  users, 
  vendors, 
  vendorContacts, 
  vendorAttachments,
  userConsents,
  consentLogs,
  policyVersions
} from '@/db/schema'
import { insertVendor } from '@/lib/vendors/repository'
import { getErrorMessage } from '@/lib/handle-error'
import { saveFile, SaveFileResult } from '@/lib/file-stroage'

// Types
interface AccountData {
  name: string
  email: string
  phone: string
  country: string
}

interface VendorData {
  vendorName: string
  vendorCode?: string
  address?: string
  country?: string
  phone?: string
  email: string
  website?: string
  status?: string
  taxId: string
  vendorTypeId: number
  items?: string
  representativeName?: string
  representativeBirth?: string
  representativeEmail?: string
  representativePhone?: string
  corporateRegistrationNumber?: string
  representativeWorkExpirence?: boolean
  contacts: ContactData[]
}

interface ContactData {
  contactName: string
  contactPosition?: string
  contactDepartment?: string
  contactTask?: string
  contactEmail: string
  contactPhone?: string
  isPrimary?: boolean
}

interface ConsentData {
  privacy_policy: {
    agreed: boolean
    version: string
  }
  terms_of_service: {
    agreed: boolean
    version: string
  }
  marketing: {
    agreed: boolean
    version: string
  }
}

interface CompleteSignupData {
  account: AccountData
  vendor: VendorData
  consents: ConsentData
}

// File attachment types
const FILE_TYPES = {
  BUSINESS_REGISTRATION: 'BUSINESS_REGISTRATION',
  ISO_CERTIFICATION: 'ISO_CERTIFICATION', 
  CREDIT_REPORT: 'CREDIT_REPORT',
  BANK_ACCOUNT_COPY: 'BANK_ACCOUNT_COPY'
} as const

type FileType = typeof FILE_TYPES[keyof typeof FILE_TYPES]

// 보안 강화된 파일 저장 함수
async function storeVendorFiles(
  tx: PgTransaction<any, any, any>,
  vendorId: number,
  files: File[],
  attachmentType: FileType,
  userId?: number
) {
  const vendorDirectory = `vendors/${vendorId}`

  for (const file of files) {
    console.log(`📄 업체 파일 저장 시작: ${file.name} (타입: ${attachmentType})`)
    
    // 보안 강화된 파일 저장
    const saveResult: SaveFileResult = await saveFile({
      file,
      directory: vendorDirectory,
      originalName: file.name,
      userId: userId?.toString(),
    })

    if (!saveResult.success) {
      throw new Error(`파일 저장 실패 (${file.name}): ${saveResult.error}`)
    }

    // 파일 정보 DB에 저장
    await tx.insert(vendorAttachments).values({
      vendorId,
      fileName: saveResult.originalName || file.name,
      filePath: saveResult.publicPath!,
      attachmentType,
    })

    console.log(`✅ 업체 파일 저장 완료: ${saveResult.fileName}`)
  }
}

// 사용자 계정 생성 함수 (승인 대기 상태)
async function createUserAccount(
  tx: PgTransaction<any, any, any>,
  accountData: AccountData,
  vendorId?: number
) {
  console.log(`👤 사용자 계정 생성: ${accountData.email} (승인 대기 상태)`)
  
  // 국가코드에 따른 언어 설정
  const language = accountData.country === 'KR' ? 'ko' : 'en'
  
  // 사용자 생성 (승인 대기 상태로)
  const [newUser] = await tx.insert(users).values({
    name: accountData.name,
    email: accountData.email.toLowerCase(),
    phone: accountData.phone,
    domain: 'partners', // 파트너 도메인
    companyId: vendorId || null,
    language, // 🌍 국가코드 기반 언어 설정 (KR → 'ko', 그외 → 'en')
    
    // 🔒 승인 대기 상태로 설정
    isActive: false, // 관리자 승인 후 활성화 예정
    
    // 보안 관련 초기 설정
    mfaEnabled: false,
    isLocked: false,
    failedLoginAttempts: 0,
    passwordChangeRequired: false, // 패스워드 링크로 설정 예정
    
    // 동의 관련 초기 설정
    requiresConsentUpdate: false,
    lastConsentUpdate: new Date(),
  }).returning()

  console.log(`✅ 사용자 계정 생성 완료: ${newUser.email} (ID: ${newUser.id}, 언어: ${language})`)
  return newUser
}

// 동의 정보 저장 함수
async function saveUserConsents(
  tx: PgTransaction<any, any, any>,
  userId: number,
  consents: ConsentData,
  clientIP?: string,
  userAgent?: string
) {
  const timestamp = new Date()

  // 각 동의 타입에 대해 처리
  const consentTypes = [
    { type: 'privacy_policy' as const, data: consents.privacy_policy },
    { type: 'terms_of_service' as const, data: consents.terms_of_service },
    { type: 'marketing' as const, data: consents.marketing }
  ]

  for (const { type, data } of consentTypes) {
    // 동의 상태 저장
    await tx.insert(userConsents).values({
      userId,
      consentType: type,
      consentStatus: data.agreed,
      policyVersion: data.version,
      consentedAt: timestamp,
      ipAddress: clientIP || null,
      userAgent: userAgent || null,
    })

    // 동의 로그 저장
    await tx.insert(consentLogs).values({
      userId,
      consentType: type,
      action: 'consent',
      oldStatus: null, // 신규 사용자이므로 이전 상태 없음
      newStatus: data.agreed,
      policyVersion: data.version,
      ipAddress: clientIP || null,
      userAgent: userAgent || null,
      actionTimestamp: timestamp,
      additionalData: {
        source: 'signup',
        initialConsent: true
      }
    })
  }

  // users 테이블의 동의 관련 필드 업데이트
  await tx.update(users)
    .set({
      lastConsentUpdate: timestamp,
      consentVersion: consents.privacy_policy.version, // 대표 버전으로 privacy policy 사용
      requiresConsentUpdate: false,
      updatedAt: timestamp
    })
    .where(eq(users.id, userId))
}

// 유효성 검사 함수들
function validateAccountData(account: AccountData): string[] {
  const errors: string[] = []

  if (!account.name?.trim()) errors.push('이름은 필수입니다.')
  if (!account.email?.trim()) errors.push('이메일은 필수입니다.')
  if (!account.phone?.trim()) errors.push('전화번호는 필수입니다.')
  if (!account.country?.trim()) errors.push('국가는 필수입니다.')

  // 이메일 형식 검증
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  if (account.email && !emailRegex.test(account.email)) {
    errors.push('유효한 이메일 형식이 아닙니다.')
  }

  return errors
}

function validateVendorData(vendor: VendorData): string[] {
  const errors: string[] = []

  if (!vendor.vendorName?.trim()) errors.push('업체명은 필수입니다.')
  if (!vendor.vendorTypeId) errors.push('업체 유형은 필수입니다.')
  if (!vendor.items?.trim()) errors.push('공급품목은 필수입니다.')
  if (!vendor.taxId?.trim()) errors.push('사업자등록번호는 필수입니다.')
  if (!vendor.country?.trim()) errors.push('국가는 필수입니다.')
  if (!vendor.phone?.trim()) errors.push('대표 전화번호는 필수입니다.')
  if (!vendor.email?.trim()) errors.push('대표 이메일은 필수입니다.')

  // 연락처 검증
  if (!vendor.contacts?.length) {
    errors.push('최소 1명의 담당자 정보가 필요합니다.')
  } else {
    vendor.contacts.forEach((contact, index) => {
      if (!contact.contactName?.trim()) {
        errors.push(`담당자 ${index + 1}의 이름은 필수입니다.`)
      }
      if (!contact.contactEmail?.trim()) {
        errors.push(`담당자 ${index + 1}의 이메일은 필수입니다.`)
      }
    })
  }

  return errors
}

function validateConsents(consents: ConsentData): string[] {
  const errors: string[] = []

  // 필수 동의 항목 확인
  if (!consents.privacy_policy?.agreed) {
    errors.push('개인정보 처리방침에 동의해주세요.')
  }
  if (!consents.terms_of_service?.agreed) {
    errors.push('서비스 이용약관에 동의해주세요.')
  }

  // 버전 정보 확인
  if (!consents.privacy_policy?.version) {
    errors.push('개인정보 처리방침 버전 정보가 없습니다.')
  }
  if (!consents.terms_of_service?.version) {
    errors.push('서비스 이용약관 버전 정보가 없습니다.')
  }

  return errors
}

export async function POST(request: NextRequest) {
  unstable_noStore()

  try {
    const formData = await request.formData()

    // 완전한 가입 데이터 파싱
    const completeDataString = formData.get('completeData') as string
    if (!completeDataString) {
      return NextResponse.json(
        { error: '가입 정보가 누락되었습니다.' },
        { status: 400 }
      )
    }

    const completeData: CompleteSignupData = JSON.parse(completeDataString)
    const { account, vendor, consents } = completeData

    // 유효성 검사
    const accountErrors = validateAccountData(account)
    const vendorErrors = validateVendorData(vendor)
    const consentErrors = validateConsents(consents)

    const allErrors = [...accountErrors, ...vendorErrors, ...consentErrors]
    if (allErrors.length > 0) {
      return NextResponse.json(
        { error: allErrors.join('\n') },
        { status: 400 }
      )
    }

    // 파일 추출
    const businessRegistrationFiles = formData.getAll('businessRegistration') as File[]
    const isoCertificationFiles = formData.getAll('isoCertification') as File[]
    const creditReportFiles = formData.getAll('creditReport') as File[]
    const bankAccountFiles = formData.getAll('bankAccount') as File[]

    // 필수 파일 검증
    if (businessRegistrationFiles.length === 0) {
      return NextResponse.json(
        { error: '사업자등록증을 업로드해주세요.' },
        { status: 400 }
      )
    }

    if (isoCertificationFiles.length === 0) {
      return NextResponse.json(
        { error: 'ISO 인증서를 업로드해주세요.' },
        { status: 400 }
      )
    }

    if (creditReportFiles.length === 0) {
      return NextResponse.json(
        { error: '신용평가보고서를 업로드해주세요.' },
        { status: 400 }
      )
    }

    if (vendor.country !== "KR" && bankAccountFiles.length === 0) {
      return NextResponse.json(
        { error: '대금지급 통장사본을 업로드해주세요.' },
        { status: 400 }
      )
    }

    // 중복 검사
    const existingUser = await db
      .select({ id: users.id })
      .from(users)
      .where(eq(users.email, account.email.toLowerCase()))
      .limit(1)

    if (existingUser.length > 0) {
      return NextResponse.json(
        { error: '이미 등록된 이메일입니다.' },
        { status: 400 }
      )
    }

    const existingVendor = await db
      .select({ id: vendors.id })
      .from(vendors)
      .where(eq(vendors.taxId, vendor.taxId))
      .limit(1)

    if (existingVendor.length > 0) {
      return NextResponse.json(
        { error: '이미 등록된 사업자등록번호입니다.' },
        { status: 400 }
      )
    }

    // 클라이언트 정보 추출
    const clientIP = request.headers.get('x-forwarded-for') || 
                    request.headers.get('x-real-ip') ||
                    request.ip || 
                    '127.0.0.1'
    const userAgent = request.headers.get('user-agent') || 'Unknown'

    let newUser: any
    let newVendor: any

    // 트랜잭션으로 모든 데이터 생성
    await db.transaction(async (tx) => {
      // 1. 업체 생성
      [newVendor] = await insertVendor(tx, {
        vendorName: vendor.vendorName,
        vendorCode: vendor.vendorCode || null,
        address: vendor.address || null,
        country: vendor.country || null,
        phone: vendor.phone || null,
        email: vendor.email,
        website: vendor.website || null,
        status: "PENDING_REVIEW", // 관리자 승인 대기
        taxId: vendor.taxId,
        vendorTypeId: vendor.vendorTypeId,
        items: vendor.items || null,
        // 한국 사업자 정보
        representativeName: vendor.representativeName || null,
        representativeBirth: vendor.representativeBirth || null,
        representativeEmail: vendor.representativeEmail || null,
        representativePhone: vendor.representativePhone || null,
        corporateRegistrationNumber: vendor.corporateRegistrationNumber || null,
        representativeWorkExpirence: vendor.representativeWorkExpirence || false,
      })

      // 2. 사용자 계정 생성 (업체 ID와 연결)
      newUser = await createUserAccount(tx, account, newVendor.id)

      // 3. 동의 정보 저장
      await saveUserConsents(tx, newUser.id, consents, clientIP, userAgent)

      // 4. 파일 저장 (보안 강화된 파일 저장 함수 사용)
      if (businessRegistrationFiles.length > 0) {
        await storeVendorFiles(tx, newVendor.id, businessRegistrationFiles, FILE_TYPES.BUSINESS_REGISTRATION, newUser.id)
      }

      if (isoCertificationFiles.length > 0) {
        await storeVendorFiles(tx, newVendor.id, isoCertificationFiles, FILE_TYPES.ISO_CERTIFICATION, newUser.id)
      }

      if (creditReportFiles.length > 0) {
        await storeVendorFiles(tx, newVendor.id, creditReportFiles, FILE_TYPES.CREDIT_REPORT, newUser.id)
      }

      if (bankAccountFiles.length > 0) {
        await storeVendorFiles(tx, newVendor.id, bankAccountFiles, FILE_TYPES.BANK_ACCOUNT_COPY, newUser.id)
      }

      // 5. 담당자 정보 저장
      for (const [index, contact] of vendor.contacts.entries()) {
        await tx.insert(vendorContacts).values({
          vendorId: newVendor.id,
          contactName: contact.contactName,
          contactPosition: contact.contactPosition || null,
          contactDepartment: contact.contactDepartment || null,
          contactTask: contact.contactTask || null,
          contactEmail: contact.contactEmail,
          contactPhone: contact.contactPhone || null,
          isPrimary: index === 0, // 첫 번째 담당자를 주담당자로 설정
        })
      }
    })

    // 캐시 무효화
    revalidateTag("vendors")
    revalidateTag("users")

    console.log(`🎉 통합 회원가입 완료:`)
    console.log(`   - 사용자: ${newUser.email} (ID: ${newUser.id})`)
    console.log(`   - 업체: ${newVendor.vendorName} (ID: ${newVendor.id})`)
    console.log(`   - 상태: 승인 대기 (isActive: false)`)
    console.log(`   - 다음 단계: 관리자 승인 → 패스워드 설정 링크 발송`)

    return NextResponse.json({
      message: '회원가입 및 업체 등록이 완료되었습니다.',
      notice: '관리자 승인 후 계정이 활성화됩니다. 승인 완료 시 패스워드 설정 링크가 이메일로 전송됩니다.',
      data: {
        userId: newUser.id,
        vendorId: newVendor.id,
        email: newUser.email,
        status: 'PENDING_APPROVAL', // 승인 대기 상태
        isActive: false
      }
    }, { status: 201 })

  } catch (error) {
    console.error('통합 회원가입 처리 오류:', error)
    return NextResponse.json(
      { 
        error: '회원가입 및 업체 등록 처리 중 오류가 발생했습니다.',
        details: getErrorMessage(error),
        notice: '문제가 지속될 경우 관리자에게 문의해주세요.'
      },
      { status: 500 }
    )
  }
}
