'use client'

import * as React from 'react'
import { Calendar, Save, RefreshCw, Clock, Send } from 'lucide-react'
import { updateBiddingSchedule, getBiddingById, getSpecificationMeetingDetailsAction } from '@/lib/bidding/service'
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'

import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Switch } from '@/components/ui/switch'
import { BiddingInvitationDialog } from '@/lib/bidding/detail/table/bidding-invitation-dialog'
import { sendBiddingBasicContracts, getSelectedVendorsForBidding } from '@/lib/bidding/pre-quote/service'
import { registerBidding } from '@/lib/bidding/detail/service'
import { useToast } from '@/hooks/use-toast'

interface BiddingSchedule {
  submissionStartDate?: string
  submissionEndDate?: string
  remarks?: string
  isUrgent?: boolean
  hasSpecificationMeeting?: boolean
}

interface SpecificationMeetingInfo {
  meetingDate: string
  meetingTime: string
  location: string
  address: string
  contactPerson: string
  contactPhone: string
  contactEmail: string
  agenda: string
  materials: string
  notes: string
  isRequired: boolean
}

interface BiddingScheduleEditorProps {
  biddingId: number
}

interface VendorContractRequirement {
  vendorId: number
  vendorName: string
  vendorCode?: string | null
  vendorCountry?: string
  vendorEmail?: string | null
  contactPerson?: string | null
  contactEmail?: string | null
  ndaYn?: boolean
  generalGtcYn?: boolean
  projectGtcYn?: boolean
  agreementYn?: boolean
  biddingCompanyId: number
  biddingId: number
}

interface VendorWithContactInfo extends VendorContractRequirement {
  contacts: Array<{
    id: number
    contactName: string
    contactEmail: string
    contactPhone?: string | null
    contactPosition?: string | null
    contactDepartment?: string | null
  }>
  selectedMainEmail: string
  additionalEmails: string[]
  customEmails: Array<{
    id: string
    email: string
    name?: string
  }>
  hasExistingContracts: boolean
}

interface BiddingInvitationData {
  vendors: VendorWithContactInfo[]
  generatedPdfs: Array<{
    key: string
    buffer: number[]
    fileName: string
  }>
  message?: string
}

export function BiddingScheduleEditor({ biddingId }: BiddingScheduleEditorProps) {
  const { data: session } = useSession()
  const router = useRouter()
  const { toast } = useToast()
  const [schedule, setSchedule] = React.useState<BiddingSchedule>({})
  const [specMeetingInfo, setSpecMeetingInfo] = React.useState<SpecificationMeetingInfo>({
    meetingDate: '',
    meetingTime: '',
    location: '',
    address: '',
    contactPerson: '',
    contactPhone: '',
    contactEmail: '',
    agenda: '',
    materials: '',
    notes: '',
    isRequired: false,
  })
  const [isLoading, setIsLoading] = React.useState(false)
  const [isSubmitting, setIsSubmitting] = React.useState(false)
  const [biddingInfo, setBiddingInfo] = React.useState<{ title: string; projectName?: string; status: string } | null>(null)
  const [isBiddingInvitationDialogOpen, setIsBiddingInvitationDialogOpen] = React.useState(false)
  const [selectedVendors, setSelectedVendors] = React.useState<VendorContractRequirement[]>([])

  // 데이터 로딩
  React.useEffect(() => {
    const loadSchedule = async () => {
      setIsLoading(true)
      try {
        const bidding = await getBiddingById(biddingId)
        if (bidding) {
          // 입찰 정보 저장
          setBiddingInfo({
            title: bidding.title || '',
            projectName: bidding.projectName || undefined,
            status: bidding.status || '',
          })

          // 날짜를 문자열로 변환하는 헬퍼
          const formatDateTime = (date: unknown): string => {
            if (!date) return ''
            if (typeof date === 'string') {
              // 이미 datetime-local 형식인 경우
              if (date.includes('T')) {
                return date.slice(0, 16)
              }
              return date
            }
            if (date instanceof Date) return date.toISOString().slice(0, 16)
            return ''
          }

          setSchedule({
            submissionStartDate: formatDateTime(bidding.submissionStartDate),
            submissionEndDate: formatDateTime(bidding.submissionEndDate),
            remarks: bidding.remarks || '',
            isUrgent: bidding.isUrgent || false,
            hasSpecificationMeeting: bidding.hasSpecificationMeeting || false,
          })

          // 사양설명회 정보 로드
          if (bidding.hasSpecificationMeeting) {
            try {
              const meetingDetails = await getSpecificationMeetingDetailsAction(biddingId)
              if (meetingDetails.success && meetingDetails.data) {
                const meeting = meetingDetails.data
                setSpecMeetingInfo({
                  meetingDate: meeting.meetingDate ? new Date(meeting.meetingDate).toISOString().slice(0, 16) : '',
                  meetingTime: meeting.meetingTime || '',
                  location: meeting.location || '',
                  address: meeting.address || '',
                  contactPerson: meeting.contactPerson || '',
                  contactPhone: meeting.contactPhone || '',
                  contactEmail: meeting.contactEmail || '',
                  agenda: meeting.agenda || '',
                  materials: meeting.materials || '',
                  notes: meeting.notes || '',
                  isRequired: meeting.isRequired || false,
                })
              }
            } catch (error) {
              console.error('Failed to load specification meeting details:', error)
            }
          }
        }
      } catch (error) {
        console.error('Failed to load schedule:', error)
        toast({
          title: '오류',
          description: '일정 정보를 불러오는데 실패했습니다.',
          variant: 'destructive',
        })
      } finally {
        setIsLoading(false)
      }
    }

    loadSchedule()
  }, [biddingId, toast])

  // 선정된 업체들 조회
  const getSelectedVendors = React.useCallback(async (): Promise<VendorContractRequirement[]> => {
    try {
      const result = await getSelectedVendorsForBidding(biddingId)
      if (result.success) {
        // 타입 변환: null을 undefined로 변환
        return result.vendors.map((vendor): VendorContractRequirement => ({
          vendorId: vendor.vendorId,
          vendorName: vendor.vendorName,
          vendorCode: vendor.vendorCode ?? undefined,
          vendorCountry: vendor.vendorCountry,
          vendorEmail: vendor.vendorEmail ?? undefined,
          contactPerson: vendor.contactPerson ?? undefined,
          contactEmail: vendor.contactEmail ?? undefined,
          ndaYn: vendor.ndaYn,
          generalGtcYn: vendor.generalGtcYn,
          projectGtcYn: vendor.projectGtcYn,
          agreementYn: vendor.agreementYn,
          biddingCompanyId: vendor.biddingCompanyId,
          biddingId: vendor.biddingId,
        }))
      } else {
        console.error('선정된 업체 조회 실패:', 'error' in result ? result.error : '알 수 없는 오류')
        return []
      }
    } catch (error) {
      console.error('선정된 업체 조회 실패:', error)
      return []
    }
  }, [biddingId])

  // 본입찰 초대 다이얼로그가 열릴 때 선정된 업체들 조회
  React.useEffect(() => {
    if (isBiddingInvitationDialogOpen) {
      getSelectedVendors().then(vendors => {
        setSelectedVendors(vendors)
      })
    }
  }, [isBiddingInvitationDialogOpen, getSelectedVendors])

  // 입찰 초대 발송 핸들러
  const handleBiddingInvitationSend = async (data: BiddingInvitationData) => {
    try {
      const userId = session?.user?.id?.toString() || '1'

      // 1. 기본계약 발송
      // sendBiddingBasicContracts에 필요한 형식으로 변환
      const vendorDataForContract = data.vendors.map(vendor => ({
        vendorId: vendor.vendorId,
        vendorName: vendor.vendorName,
        vendorCode: vendor.vendorCode || undefined,
        vendorCountry: vendor.vendorCountry,
        selectedMainEmail: vendor.selectedMainEmail,
        additionalEmails: vendor.additionalEmails,
        customEmails: vendor.customEmails,
        contractRequirements: {
          ndaYn: vendor.ndaYn || false,
          generalGtcYn: vendor.generalGtcYn || false,
          projectGtcYn: vendor.projectGtcYn || false,
          agreementYn: vendor.agreementYn || false,
        },
        biddingCompanyId: vendor.biddingCompanyId,
        biddingId: vendor.biddingId,
        hasExistingContracts: vendor.hasExistingContracts,
      }))

      const contractResult = await sendBiddingBasicContracts(
        biddingId,
        vendorDataForContract,
        data.generatedPdfs,
        data.message
      )

      if (!contractResult.success) {
        const errorMessage = 'message' in contractResult 
          ? contractResult.message 
          : 'error' in contractResult 
            ? contractResult.error 
            : '기본계약 발송에 실패했습니다.'
        toast({
          title: '기본계약 발송 실패',
          description: errorMessage,
          variant: 'destructive',
        })
        return
      }

      // 2. 입찰 등록 진행
      const registerResult = await registerBidding(biddingId, userId)

      if (registerResult.success) {
        toast({
          title: '본입찰 초대 완료',
          description: '기본계약 발송 및 본입찰 초대가 완료되었습니다.',
        })
        setIsBiddingInvitationDialogOpen(false)
        router.refresh()
      } else {
        toast({
          title: '오류',
          description: 'error' in registerResult ? registerResult.error : '입찰 등록에 실패했습니다.',
          variant: 'destructive',
        })
      }
    } catch (error) {
      console.error('본입찰 초대 실패:', error)
      toast({
        title: '오류',
        description: '본입찰 초대에 실패했습니다.',
        variant: 'destructive',
      })
    }
  }

  const handleSave = async () => {
    setIsSubmitting(true)
    try {
      const userId = session?.user?.id?.toString() || '1'
      
      // 사양설명회 정보 유효성 검사
      if (schedule.hasSpecificationMeeting) {
        if (!specMeetingInfo.meetingDate || !specMeetingInfo.location || !specMeetingInfo.contactPerson) {
          toast({
            title: '오류',
            description: '사양설명회 필수 정보가 누락되었습니다. (회의일시, 장소, 담당자)',
            variant: 'destructive',
          })
          setIsSubmitting(false)
          return
        }
      }

      const result = await updateBiddingSchedule(
        biddingId, 
        schedule, 
        userId,
        schedule.hasSpecificationMeeting ? specMeetingInfo : undefined
      )

      if (result.success) {
        toast({
          title: '성공',
          description: '일정 정보가 성공적으로 저장되었습니다.',
        })
      } else {
        toast({
          title: '오류',
          description: 'error' in result ? result.error : '일정 정보 저장에 실패했습니다.',
          variant: 'destructive',
        })
      }
    } catch (error) {
      console.error('Failed to save schedule:', error)
      toast({
        title: '오류',
        description: '일정 정보 저장에 실패했습니다.',
        variant: 'destructive',
      })
    } finally {
      setIsSubmitting(false)
    }
  }

  const handleScheduleChange = (field: keyof BiddingSchedule, value: string | boolean) => {
    setSchedule(prev => ({ ...prev, [field]: value }))
    
    // 사양설명회 실시 여부가 false로 변경되면 상세 정보 초기화
    if (field === 'hasSpecificationMeeting' && value === false) {
      setSpecMeetingInfo({
        meetingDate: '',
        meetingTime: '',
        location: '',
        address: '',
        contactPerson: '',
        contactPhone: '',
        contactEmail: '',
        agenda: '',
        materials: '',
        notes: '',
        isRequired: false,
      })
    }
  }

  if (isLoading) {
    return (
      <div className="flex items-center justify-center p-8">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>
        <span className="ml-2">일정 정보를 불러오는 중...</span>
      </div>
    )
  }

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Calendar className="h-5 w-5" />
            입찰 일정 관리
          </CardTitle>
          <p className="text-sm text-muted-foreground mt-1">
            입찰의 주요 일정들을 설정하고 관리합니다.
          </p>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* 입찰서 제출 기간 */}
          <div className="space-y-4">
            <h3 className="text-lg font-medium flex items-center gap-2">
              <Clock className="h-4 w-4" />
              입찰서 제출 기간
            </h3>
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="submission-start">제출 시작일시</Label>
                <Input
                  id="submission-start"
                  type="datetime-local"
                  value={schedule.submissionStartDate || ''}
                  onChange={(e) => handleScheduleChange('submissionStartDate', e.target.value)}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="submission-end">제출 마감일시</Label>
                <Input
                  id="submission-end"
                  type="datetime-local"
                  value={schedule.submissionEndDate || ''}
                  onChange={(e) => handleScheduleChange('submissionEndDate', e.target.value)}
                />
              </div>
            </div>
          </div>

          {/* 긴급 여부 */}
          <div className="flex flex-row items-center justify-between rounded-lg border p-4">
            <div className="space-y-0.5">
              <Label className="text-base">긴급여부</Label>
              <p className="text-sm text-muted-foreground">
                긴급 입찰로 표시할 경우 활성화하세요
              </p>
            </div>
            <Switch
              checked={schedule.isUrgent || false}
              onCheckedChange={(checked) => handleScheduleChange('isUrgent', checked)}
            />
          </div>

          {/* 사양설명회 실시 여부 */}
          <div className="flex flex-row items-center justify-between rounded-lg border p-4">
            <div className="space-y-0.5">
              <Label className="text-base">사양설명회 실시</Label>
              <p className="text-sm text-muted-foreground">
                사양설명회를 실시할 경우 상세 정보를 입력하세요
              </p>
            </div>
            <Switch
              checked={schedule.hasSpecificationMeeting || false}
              onCheckedChange={(checked) => handleScheduleChange('hasSpecificationMeeting', checked)}
            />
          </div>

          {/* 사양설명회 상세 정보 */}
          {schedule.hasSpecificationMeeting && (
            <div className="space-y-6 p-4 border rounded-lg bg-muted/50">
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <Label>회의일시 <span className="text-red-500">*</span></Label>
                  <Input
                    type="datetime-local"
                    value={specMeetingInfo.meetingDate}
                    onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, meetingDate: e.target.value }))}
                    className={!specMeetingInfo.meetingDate ? 'border-red-200' : ''}
                  />
                  {!specMeetingInfo.meetingDate && (
                    <p className="text-sm text-red-500 mt-1">회의일시는 필수입니다</p>
                  )}
                </div>
                <div>
                  <Label>회의시간</Label>
                  <Input
                    placeholder="예: 14:00 ~ 16:00"
                    value={specMeetingInfo.meetingTime}
                    onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, meetingTime: e.target.value }))}
                  />
                </div>
              </div>
              <div>
                <Label>장소 <span className="text-red-500">*</span></Label>
                <Input
                  placeholder="회의 장소"
                  value={specMeetingInfo.location}
                  onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, location: e.target.value }))}
                  className={!specMeetingInfo.location ? 'border-red-200' : ''}
                />
                {!specMeetingInfo.location && (
                  <p className="text-sm text-red-500 mt-1">회의 장소는 필수입니다</p>
                )}
              </div>
              <div>
                <Label>주소</Label>
                <Input
                  placeholder="회의 장소 주소"
                  value={specMeetingInfo.address}
                  onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, address: e.target.value }))}
                />
              </div>
              <div className="grid grid-cols-3 gap-4">
                <div>
                  <Label>담당자 <span className="text-red-500">*</span></Label>
                  <Input
                    placeholder="담당자명"
                    value={specMeetingInfo.contactPerson}
                    onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, contactPerson: e.target.value }))}
                    className={!specMeetingInfo.contactPerson ? 'border-red-200' : ''}
                  />
                  {!specMeetingInfo.contactPerson && (
                    <p className="text-sm text-red-500 mt-1">담당자는 필수입니다</p>
                  )}
                </div>
                <div>
                  <Label>연락처</Label>
                  <Input
                    placeholder="전화번호"
                    value={specMeetingInfo.contactPhone}
                    onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, contactPhone: e.target.value }))}
                  />
                </div>
                <div>
                  <Label>이메일</Label>
                  <Input
                    type="email"
                    placeholder="이메일"
                    value={specMeetingInfo.contactEmail}
                    onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, contactEmail: e.target.value }))}
                  />
                </div>
              </div>
              <div>
                <Label>안건</Label>
                <Textarea
                  placeholder="회의 안건을 입력하세요"
                  value={specMeetingInfo.agenda}
                  onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, agenda: e.target.value }))}
                  rows={3}
                />
              </div>
              <div>
                <Label>자료</Label>
                <Textarea
                  placeholder="회의 자료 정보를 입력하세요"
                  value={specMeetingInfo.materials}
                  onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, materials: e.target.value }))}
                  rows={3}
                />
              </div>
              <div>
                <Label>비고</Label>
                <Textarea
                  placeholder="추가 사항을 입력하세요"
                  value={specMeetingInfo.notes}
                  onChange={(e) => setSpecMeetingInfo((prev) => ({ ...prev, notes: e.target.value }))}
                  rows={3}
                />
              </div>
            </div>
          )}

          {/* 비고 */}
          <div className="space-y-4">
            <h3 className="text-lg font-medium">비고</h3>
            <div className="space-y-2">
              <Label htmlFor="remarks">추가 사항</Label>
              <Textarea
                id="remarks"
                value={schedule.remarks || ''}
                onChange={(e) => handleScheduleChange('remarks', e.target.value)}
                placeholder="일정에 대한 추가 설명이나 참고사항을 입력하세요"
                rows={4}
              />
            </div>
          </div>
        </CardContent>
      </Card>

      {/* 일정 요약 카드 */}
      <Card>
        <CardHeader>
          <CardTitle>일정 요약</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="space-y-2 text-sm">
            <div className="flex justify-between">
              <span className="font-medium">입찰서 제출 기간:</span>
              <span>
                {schedule.submissionStartDate && schedule.submissionEndDate
                  ? `${new Date(schedule.submissionStartDate).toLocaleString('ko-KR')} ~ ${new Date(schedule.submissionEndDate).toLocaleString('ko-KR')}`
                  : '미설정'
                }
              </span>
            </div>
            <div className="flex justify-between">
              <span className="font-medium">긴급여부:</span>
              <span>
                {schedule.isUrgent ? '예' : '아니오'}
              </span>
            </div>
            <div className="flex justify-between">
              <span className="font-medium">사양설명회 실시:</span>
              <span>
                {schedule.hasSpecificationMeeting ? '예' : '아니오'}
              </span>
            </div>
            {schedule.hasSpecificationMeeting && specMeetingInfo.meetingDate && (
              <div className="flex justify-between">
                <span className="font-medium">사양설명회 일시:</span>
                <span>
                  {new Date(specMeetingInfo.meetingDate).toLocaleString('ko-KR')}
                </span>
              </div>
            )}
          </div>
        </CardContent>
      </Card>

      {/* 액션 버튼 */}
      <div className="flex justify-between gap-4">
        <Button
          variant="default"
          onClick={() => setIsBiddingInvitationDialogOpen(true)}
          disabled={!biddingInfo || biddingInfo.status !== 'bidding_generated'}
          className="min-w-[120px]"
        >
          <Send className="w-4 h-4 mr-2" />
          입찰공고
        </Button>
        <div className="flex gap-4">
          <Button
            onClick={handleSave}
            disabled={isSubmitting || !biddingInfo || biddingInfo.status !== 'bidding_generated'}
            className="min-w-[120px]"
          >
            {isSubmitting ? (
              <>
                <RefreshCw className="w-4 h-4 mr-2 animate-spin" />
                저장 중...
              </>
            ) : (
              <>
                <Save className="w-4 h-4 mr-2" />
                저장
              </>
            )}
          </Button>
        </div>
      </div>

      {/* 입찰 초대 다이얼로그 */}
      {biddingInfo && (
        <BiddingInvitationDialog
          open={isBiddingInvitationDialogOpen}
          onOpenChange={setIsBiddingInvitationDialogOpen}
          vendors={selectedVendors}
          biddingId={biddingId}
          biddingTitle={biddingInfo.title}
          onSend={handleBiddingInvitationSend}
        />
      )}
    </div>
  )
}

