Imports Microsoft.VisualBasic
Imports System.Data
Imports System.Net.Mail
Imports System.Data.SqlClient
Imports AppCommon
Imports AppVariable
Imports AppVariable_Mail
Imports System.Configuration
Imports System.Security.Cryptography
Imports System.Text


Public Class AppMail

    Public Class UserInfo
        Public Property PortalId As String
        Public Property UserCd As String
        Public Property UserName As String
        Public Property UserKbn As String
        Public Property PortalKbn As String
        Public Property Email As String
        Public Property GakuenCd As String
        Public Property CityCd As String
        Public Property CityName As String
        Public Property InvoiceNo As String
        Public Property AccountKey As String

        Public Sub New(userCd As String)
            Dim dt As DataTable = GetUserDataByUserCd(userCd)
            Initialize(dt)
        End Sub

        ' PortalId でのコンストラクタ（フラグを追加）
        Public Sub New(portalId As String, isPortalId As Boolean)
            If isPortalId Then
                Dim dt As DataTable = GetUserDataByPortalId(portalId)
                Initialize(dt)
            Else
                Throw New ArgumentException("Invalid constructor parameters")
            End If
        End Sub

        ' 共通の初期化メソッド
        Private Sub Initialize(dt As DataTable)
            If dt.Rows.Count > 0 Then
                Me.UserCd = dt.Rows(0)("USERCD").ToString()
                Me.PortalId = dt.Rows(0)("PORTALID").ToString()
                Me.UserName = dt.Rows(0)("名前").ToString()
                Me.PortalKbn = dt.Rows(0)("PORTAL区分").ToString()
                Me.UserKbn = dt.Rows(0)("利用者区分").ToString()
                Me.Email = dt.Rows(0)("EMAIL").ToString()
                Me.GakuenCd = dt.Rows(0)("学園CD").ToString()
                Me.CityCd = dt.Rows(0)("市区町村CD").ToString()
                Me.CityName = dt.Rows(0)("市区町村名").ToString()
                Me.InvoiceNo = dt.Rows(0)("請求NO").ToString()
            Else
                Me.UserCd = String.Empty
                Me.PortalId = String.Empty
                Me.UserName = String.Empty
                Me.PortalKbn = String.Empty
                Me.UserKbn = String.Empty
                Me.Email = String.Empty
                Me.GakuenCd = "01" 'デフォルト値01
                Me.CityCd = String.Empty
                Me.CityName = String.Empty
                Me.InvoiceNo = String.Empty
            End If
            Me.AccountKey = String.Empty
        End Sub
    End Class

    '申込情報
    Public Class ApplyInfo
        Public Property ApplyNo As String
        Public Property PKey As String
        Public Property SeqNo As String 'DB申込.連番
        Public Property StudentDept As String
        Public Property StudentName As String
        Public Property StaffDept As String
        Public Property StaffName As String
        Public Property StaffEmail As String
        Public Property CourseCd As String '科目CD
        Public Property CourseName As String
        Public Property LessonCd As String '講座CD
        Public Property LessonName As String
        Public Property LessonPeriod As String
        Public Property CityCd As String
        Public Property CityName As String
        Public Sub New(applyNo As String)
            Dim dt As DataTable = GetApplyData(applyNo)

            If dt.Rows.Count > 0 Then
                Me.ApplyNo = applyNo
                Me.PKey = dt.Rows(0)("PKey").ToString()
                Me.SeqNo = dt.Rows(0)("連番").ToString()
                Me.StudentDept = dt.Rows(0)("所属部課").ToString()
                Me.StudentName = dt.Rows(0)("氏名").ToString()
                Me.StaffDept = dt.Rows(0)("研修担当所属").ToString()
                Me.StaffName = dt.Rows(0)("研修担当氏名").ToString()
                Me.StaffEmail = dt.Rows(0)("研修担当EMAIL").ToString()
                Me.CourseCd = dt.Rows(0)("科目CD").ToString()
                Me.CourseName = dt.Rows(0)("科目名").ToString()
                Me.LessonCd = dt.Rows(0)("講座CD").ToString()
                Me.LessonName = dt.Rows(0)("回名").ToString()
                Dim lessonStart As DateTime? = If(IsDBNull(dt.Rows(0)("研修期間開始")), CType(Nothing, DateTime?), Convert.ToDateTime(dt.Rows(0)("研修期間開始")))
                Dim lessonEnd As DateTime? = If(IsDBNull(dt.Rows(0)("研修期間終了")), CType(Nothing, DateTime?), Convert.ToDateTime(dt.Rows(0)("研修期間終了")))
                If Not lessonStart.HasValue And Not lessonEnd.HasValue Then
                    Me.LessonPeriod = ""
                Else
                    Me.LessonPeriod = FormatDateTime(lessonStart) + " ~ " + FormatDateTime(lessonEnd)
                End If
                Me.CityCd = dt.Rows(0)("市区町村CD").ToString()
                Me.CityName = dt.Rows(0)("市区町村名").ToString()
            Else
                Me.ApplyNo = String.Empty
                Me.PKey = String.Empty
                Me.SeqNo = String.Empty
                Me.StudentDept = String.Empty
                Me.StudentName = String.Empty
                Me.StaffDept = String.Empty
                Me.StaffName = String.Empty
                Me.StaffEmail = String.Empty
                Me.CourseCd = String.Empty
                Me.CourseName = String.Empty
                Me.LessonCd = String.Empty
                Me.LessonName = String.Empty
                Me.LessonPeriod = String.Empty
                Me.CityCd = String.Empty
                Me.CityName = String.Empty
            End If
        End Sub
    End Class

        Private Shared ReadOnly canSendMail As Boolean = ConfigurationManager.AppSettings("mail_sending_enabled").ToString() = "true"
    Private Shared ReadOnly smtpUser As String = ConfigurationManager.AppSettings("smtp_user_id").ToString()
    Private Shared ReadOnly smtpPass As String = ConfigurationManager.AppSettings("smtp_user_pass").ToString()
    Private Shared ReadOnly rootUrl As String = GetRootUrl()
    Private Shared ReadOnly ptUser As String = Com_Get_変数("PT_USER")
    Private Shared ReadOnly ptTitle As String = Com_Get_変数("PT_TITLE")

    Private Const funcKbn_QA As String = "問い合わせ"
    Private Const funcKbn_SignupApply As String = "アカウント登録申請"
    Private Const funcKbn_SignupForm As String = "アカウント申請フォーム配信"
    Private Const funcKbn_UserCdReminder As String = "アカウント問い合わせ"
    Private Const funcKbn_PwReset As String = "パスワード問い合わせ"
    Private Const funcKbn_SysContact As String = "システム問い合わせ"
    Private Const funcKbn_SysContactLog As String = "Backlog課題追加用"
    Private Const funcKbn_ApplyRegister As String = "研修申込"
    Private Const funcKbn_ApplyUpdate As String = "研修申込更新"
    Private Const funcKbn_ApplyCancel As String = "研修申込キャンセル"
    Private Const funcKbn_UserInfoUpdate As String = "アカウント情報変更" 'ADD 20251223 S.Iguchi
    Private Const funcKbn_TeacherProfUpdate As String = "講師プロフィール変更" 'ADD 20251223 S.Iguchi

    Private Const valCd_VW_PT_USERS As String = "01"
    Private Const valCd_VW_PT_Apply As String = "02"
    Private Const valCd_VW_PT_QA As String = "03"
    Private Const valCd_VW_PT_Gakuen As String = "04"
    Private Const valCd_VW_PT_Teachers As String = "05" 'ADD 20260114 S.Iguchi
    Private Const valCd_TBL_Gakuen As String = "01"
    Private Const valCd_TBL_Course As String = "02"
    Private Const valCd_TBL_Lesson As String = "03"
    Private Const valCd_TBL_Apply As String = "04"
    Private Const valCd_TBL_BaseInfo As String = "05"
    Private Const valCd_TBL_Staff As String = "06"
    Private Const valCd_TBL_QA As String = "07"
    Private Const valCd_TBL_City As String = "08"
    Private Const valCd_TBL_NewAccount As String = "09"

    'アカウント申請
    Shared Function SendSignupFormMail(newCnt As Integer, mkey As String, email As String) As Boolean

        Dim funcKbn As String = funcKbn_SignupForm
        Dim contentPath As String = IIf(rootUrl.Last() = "/", "SignupForm.aspx", "/SignupForm.aspx")
        Dim signupFormUrl As String = rootUrl & contentPath & "?mid=" & newCnt.ToString() & "&mkey=" & mkey

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo("")
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "アカウント申請メール", fromUserInfo)
        mail.Body = String.Format(mail.Body, email, signupFormUrl, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function

    'アカウント仮登録通知メール
    Shared Function SendSignupApplyMail(email As String, userId As String, userName As String, newCnt As Integer) As Boolean

        Dim funcKbn As String = funcKbn_SignupApply

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo("")
        toUserInfo.UserCd = userId
        toUserInfo.UserName = userName
        toUserInfo.AccountKey = newCnt.ToString()
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "アカウント仮登録申請完了メール", fromUserInfo)
        mail.Body = String.Format(mail.Body, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function

    'アカウント問い合わせ
    Shared Function SendUserCdReminderMail(email As String, portalId As String) As Boolean

        Dim funcKbn As String = funcKbn_UserCdReminder

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(portalId, True)
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "アカウント問い合わせ", fromUserInfo)
        mail.Body = String.Format(mail.Body, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function

    'パスワード問い合わせ
    Shared Function SendPasswordResetMail(newCnt As Integer, mkey As String, portalId As String, email As String) As Boolean

        Dim funcKbn As String = funcKbn_PwReset
        Dim contentPath As String = IIf(rootUrl.Last() = "/", "PasswordReset.aspx", "/PasswordReset.aspx")
        Dim pwResetUrl As String = rootUrl & contentPath & "?mid=" & newCnt.ToString() & "&mkey=" & mkey

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(portalId, True)
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = toUserInfo.Email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "パスワード問い合わせ", fromUserInfo)
        mail.Body = String.Format(mail.Body, pwResetUrl, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function

    'アカウント情報更新 ADD 20251222 S.Iguchi
    Shared Function SendUpdateUserInfoMail(email As String, portalId As String, userName As String) As Boolean

        Dim funcKbn As String = funcKbn_UserInfoUpdate

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo("")
        toUserInfo.PortalId = portalId
        toUserInfo.UserName = userName
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "アカウント情報変更", fromUserInfo)
        mail.Body = String.Format(mail.Body, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function
    Shared Function SendUpdateTeacherProfMail(toUserCd As String, fromUserCd As String, 出講師PKey As String) As Boolean

        Dim funcKbn As String = funcKbn_TeacherProfUpdate

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(toUserCd)
        Dim fromUserInfo As UserInfo = New UserInfo(fromUserCd)

        mail.To.Add(toUserInfo.Email)
        mail = SetMailSubjectAndBody(mail:=mail, title:="講師プロフィール変更", userInfo:=fromUserInfo, 出講師PKey:=出講師PKey)
        mail.Body = String.Format(mail.Body, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function
    Shared Function SendUpdateTeacherRequestMail(toUserCd As String, fromUserCd As String, 出講師PKey As String) As Boolean

        Dim funcKbn As String = funcKbn_TeacherProfUpdate

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(toUserCd)
        Dim fromUserInfo As UserInfo = New UserInfo(fromUserCd)

        mail.To.Add(toUserInfo.Email)
        mail = SetMailSubjectAndBody(mail:=mail, title:="講師事務連絡票提出", userInfo:=fromUserInfo, 出講師PKey:=出講師PKey)
        mail.Body = String.Format(mail.Body, ptUser, ptTitle, rootUrl)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function
    Shared Function SendSystemContactMail(contactData As Dictionary(Of String, String)) As Boolean

        Dim funcKbn As String = funcKbn_SysContact
        Dim cityCd As String = GetDicVal(contactData, "CityCd")
        Dim orgName As String = GetDicVal(contactData, "OrgName")
        Dim deptName As String = GetDicVal(contactData, "DeptName")
        Dim userName As String = GetDicVal(contactData, "UserName")
        Dim userKana As String = GetDicVal(contactData, "UserKana")
        Dim email As String = GetDicVal(contactData, "Email")
        Dim tel As String = GetDicVal(contactData, "Tel")
        Dim screen As String = GetDicVal(contactData, "Screen")
        Dim screenOther As String = GetDicVal(contactData, "ScreenOther")
        Dim content As String = GetDicVal(contactData, "Content")

        '問い合わせユーザ宛通知メール
        '送信メール情報の格納
        Dim mail As New MailMessage()

        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo("")
        toUserInfo.UserName = userName
        toUserInfo.GakuenCd = "01"
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email
        Dim sucFlg = False
        Dim supportEmail As String = Com_Get_変数("PT_FROM_ADDRESS_SVN")

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, funcKbn, fromUserInfo)
        mail.Body = String.Format(mail.Body, userName, supportEmail)

        sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        'BackLog通知用メール
        mail = New MailMessage()
        funcKbn = funcKbn_SysContactLog
        mail = SetMailSubjectAndBody(mail, funcKbn, fromUserInfo)
        toAddress = Com_Get_変数("PT_BACKLOG_ADDRESS")
        mail.To.Add(toAddress)

        '件名
        mail.Subject = String.Format(mail.Subject, DateTime.Now.ToString("yyyyMMdd"), cityCd, orgName)
        '本文
        mail.Body = String.Format(mail.Body, screen, screenOther, content, cityCd, orgName, deptName, userName, userKana, tel, email)

        sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg
    End Function

    '研修申込
    Shared Function SendApplyRegisterMail(userCd As String, applyNo As String) As Boolean
        Dim funcKbn As String = funcKbn_ApplyRegister

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(userCd)
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = toUserInfo.Email

        '申込情報
        Dim applyInfo As ApplyInfo = New ApplyInfo(applyNo)

        mail.To.Add(toAddress)

        mail = SetMailSubjectAndBody(mail, "研修受付メール", fromUserInfo, applyInfo)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg

    End Function

    '研修修正
    Shared Function SendApplyUpdateMail(userCd As String, applyNo As String) As Boolean
        Dim funcKbn As String = funcKbn_ApplyUpdate

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(userCd)
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = toUserInfo.Email

        '申込情報
        Dim applyInfo As ApplyInfo = New ApplyInfo(applyNo)

        mail.To.Add(toAddress)

        mail = SetMailSubjectAndBody(mail, "修正完了メール", fromUserInfo, applyInfo)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg

    End Function

    Shared Function SendApplyCancelMail(userCd As String, applyNo As String) As Boolean
        Dim funcKbn As String = funcKbn_ApplyCancel

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(userCd)
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = toUserInfo.Email

        '申込情報
        Dim applyInfo As ApplyInfo = New ApplyInfo(applyNo)

        mail.To.Add(toAddress)

        mail = SetMailSubjectAndBody(mail, "キャンセルメール", fromUserInfo, applyInfo)

        Dim sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

        Return sucFlg

    End Function


    '掲示板通知メール
    Shared Function SendQABoardInfoMails(loginUserInfo As LoginUser,
                                     qaId As String,
                                     subject As String,
                                     toUserCds As String) As Boolean
        '掲示板通知メールをJAMP担当者に送信
        Dim funcKbn = funcKbn_QA

        'ユーザの重複を回避
        Dim toUserCdsArr As String() = toUserCds.Split("/")
        Dim uniqueUserCds As New HashSet(Of String)(toUserCdsArr)
        Dim uniqueUserCdsArr As String() = uniqueUserCds.ToArray()

        Dim sucFlg As Boolean = False

        '研修情報他の取得
        Dim qaData = AppQA.Get問合せ詳細(qaId.Split("-")(0))
        Dim trainingName As String = qaData.Rows(0)("回名").ToString
        Dim orgName As String = qaData.Rows(0)("所属部課").ToString
        Dim orgTel As String = qaData.Rows(0)("電話番号").ToString

        Dim fromUserInfo As UserInfo = New UserInfo(loginUserInfo.USERCD)

        For Each toUserCd As String In uniqueUserCdsArr

            '送信先が自分の場合は、通知メールを送らない
            If toUserCd = fromUserInfo.UserCd Then
                Continue For
            End If

            '送信メール情報の格納
            Dim mail As New MailMessage()
            Dim toUserInfo As New UserInfo(toUserCd)
            Dim toEmail As String = toUserInfo.Email
            If Not String.IsNullOrEmpty(toEmail) Then
                mail.To.Add(toEmail)
            End If
            '宛先ユーザのポータル区分
            Dim toUserPortalKbn As String = toUserInfo.PortalKbn

            '宛先ユーザの利用者区分
            Dim toUserKbn As String = toUserInfo.UserKbn

            '申込情報の取得
            Dim applyNo As String = String.Empty
            If toUserPortalKbn = "学生" Then
                applyNo = toUserInfo.UserCd
            End If
            If fromUserInfo.PortalKbn = "学生" Then
                applyNo = fromUserInfo.UserCd
            End If

            Dim appInfo As ApplyInfo = New ApplyInfo(applyNo)

            '研修担当者→職員　に問い合わせ時、申込データが紐づかないので問い合わせデータから講座情報を取得する
            If applyNo Is String.Empty Then
                appInfo.LessonCd = qaData.Rows(0)("講座CD").ToString()
                appInfo.CourseCd = qaData.Rows(0)("科目CD").ToString()
            End If

            'JAMP宛か否かでテンプレートの切替
            If toUserPortalKbn = "職員" And Not toUserKbn = "申込者" Then

                '掲示板通知メールの送付
                mail = SetMailSubjectAndBody(mail, "掲示板通知メール(事務局宛)", fromUserInfo, appInfo, qaId)

                sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)

            Else
                mail = SetMailSubjectAndBody(mail, "掲示板通知メール(事務局以外宛)", fromUserInfo, appInfo, qaId)

                sucFlg = SendMail(mail, funcKbn, fromUserInfo, toUserInfo)
            End If
        Next

        Return sucFlg

    End Function

    '問い合わせ閲覧メール
    Shared Function SendQAViewMail(loginUserInfo As LoginUser, qaId As String, toUserCd As String) As Boolean

        '問い合わせ閲覧通知メールの送付
        Dim funcKbn As String = funcKbn_QA

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo(toUserCd)
        Dim fromUserInfo As UserInfo = New UserInfo(loginUserInfo.USERCD)
        Dim toAddress = toUserInfo.Email

        Dim applyNo = loginUserInfo.USERCD
        Dim appInfo = New ApplyInfo(applyNo)

        '送信先アドレス不明の場合はメールを送らない
        If String.IsNullOrEmpty(toAddress) Then
            Return False
        End If

        mail.To.Add(toAddress)

        mail = SetMailSubjectAndBody(mail, "問い合わせ閲覧通知メール", fromUserInfo, appInfo, qaId)

        Dim sucFlg = SendMail(mail:=mail, funcKbn:=funcKbn, fromUserInfo:=fromUserInfo, toUserInfo:=toUserInfo)


        Return sucFlg

    End Function

    'アカウント情報変更テスト送信メール
    Shared Function SendTestMail(email As String) As Boolean

        '問い合わせ閲覧通知メールの送付
        Dim funcKbn As String = funcKbn_QA

        '送信メール情報の格納
        Dim mail As New MailMessage()
        '通知先メールアドレス
        '通知先メールアドレス
        Dim toUserInfo As UserInfo = New UserInfo("")
        Dim fromUserInfo As UserInfo = toUserInfo
        Dim toAddress = email

        mail.To.Add(toAddress)
        mail = SetMailSubjectAndBody(mail, "テスト送信メール", fromUserInfo)

        Dim sucFlg = SendMail(mail:=mail, funcKbn:=funcKbn, fromUserInfo:=fromUserInfo, toUserInfo:=toUserInfo)


        Return sucFlg

    End Function

    Shared Function SendMail(mail As MailMessage, funcKbn As String, fromUserInfo As UserInfo, toUserInfo As UserInfo) As Boolean

        'メールサーバ情報の取得
        Dim smtpServer As String = Com_Get_変数("PT_SMTP_ADDRESS")
        Dim smtpPort As String = Com_Get_変数("PT_SMTP_PORT")
        Dim fromAddress As String = Com_Get_変数("PT_FROM_ADDRESS")

        Select Case funcKbn
            Case funcKbn_SignupApply, funcKbn_SignupForm, funcKbn_UserCdReminder, funcKbn_PwReset
                fromAddress = Com_Get_変数("PT_FROM_ADDRESS")

            Case funcKbn_ApplyRegister, funcKbn_ApplyUpdate, funcKbn_ApplyCancel
                fromAddress = Com_Get_変数("PT_FROM_ADDRESS_TRAINING")

            Case funcKbn_QA
                fromAddress = Com_Get_変数("PT_FROM_ADDRESS_QA")

            Case funcKbn_SysContact, funcKbn_SysContactLog
                fromAddress = Com_Get_変数("PT_FROM_ADDRESS_SVN")

            Case Else
                fromAddress = Com_Get_変数("PT_FROM_ADDRESS")
        End Select


        '送信不可設定時は処理しない
        If Not canSendMail Then
            Return True
        End If

        'メールアドレス未登録アカウント用のエラー回避
        If mail.To.Count = 0 Then
            Return False
        End If

        Try
            mail.IsBodyHtml = False
            mail.From = New MailAddress(fromAddress)

            Using smtp As New SmtpClient(smtpServer, smtpPort)
                smtp.Credentials = New Net.NetworkCredential(smtpUser, smtpPass)
                smtp.EnableSsl = True
                smtp.Send(mail)
            End Using

            'メール送信ログの登録
            Dim mailSucFlg As Boolean = SetDBMailLog(mail:=mail, funcKbn:=funcKbn,
                                                     status:="成功",
                                                     fromUserInfo:=fromUserInfo,
                                                     toUserInfo:=toUserInfo)

        Catch ex As Exception
            ' エラー処理
            Console.WriteLine("メール送信に失敗しました: " & ex.Message)

            'メール送信ログの登録
            Dim mailSucFlg As Boolean = SetDBMailLog(mail:=mail, funcKbn:=funcKbn,
                                                     status:="失敗",
                                                     fromUserInfo:=fromUserInfo,
                                                     toUserInfo:=toUserInfo)
            Return False
            Throw
        End Try

        Return True
    End Function

    Shared Function SetDBMailLog(mail As MailMessage,
                                  funcKbn As String,
                                  status As String,
                                  fromUserInfo As UserInfo,
                                  toUserInfo As UserInfo) As Boolean

        Dim fromUserEmail As String = mail.From.Address

        'fromUserがDB内に存在するときは、送信元ユーザにfromUserを入れる
        If Not String.IsNullOrEmpty(fromUserInfo.UserCd) Then
            Dim dt As DataTable = GetUserData(fromUserInfo.UserCd, True)
            If dt.Rows.Count > 0 Then
                fromUserEmail = dt.Rows(0)("EMAIL").ToString
            End If
        End If

        Using spm As New StoredProcedureManager("PT_DBEmail_send_INSERT")
            spm.AddPrmIn("@使用区分", Data.SqlDbType.VarChar, 20, funcKbn)
            spm.AddPrmIn("@利用者", Data.SqlDbType.VarChar, 50, fromUserInfo.UserName)
            spm.AddPrmIn("@作成日", Data.SqlDbType.DateTime, Now)
            spm.AddPrmIn("@件名", Data.SqlDbType.NVarChar, 200, mail.Subject)
            spm.AddPrmIn("@本文", Data.SqlDbType.NVarChar, 4000, mail.Body)
            spm.AddPrmIn("@送信元", Data.SqlDbType.VarChar, 100, fromUserEmail)
            spm.AddPrmIn("@送信先TO", Data.SqlDbType.Text, mail.To(0).Address)
            spm.AddPrmIn("@状態", Data.SqlDbType.VarChar, 50, status)
            spm.AddPrmIn("@名前", Data.SqlDbType.NVarChar, 200, fromUserInfo.UserName)
            spm.AddPrmIn("@送信元名", Data.SqlDbType.VarChar, 200, fromUserInfo.UserName)
            spm.AddPrmIn("@送信先名", Data.SqlDbType.VarChar, 200, toUserInfo.UserName)
            spm.AddPrmIn("@学園CD", Data.SqlDbType.VarChar, 20, fromUserInfo.GakuenCd)

            spm.Exec()
        End Using

        If status = "成功" Then
            Return True
        Else
            Return False
        End If
    End Function

    Public Shared Function GetRootUrl() As String
        Dim request As HttpRequest = HttpContext.Current.Request
        Dim appUrl As String = HttpRuntime.AppDomainAppVirtualPath

        If Not appUrl.EndsWith("/") Then
            appUrl &= "/"
        End If

        Dim rootUrl As String = String.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl)
        Return rootUrl
    End Function

    Public Shared Function GenerateURL(portalUrl As String, constPath As String, cnt As Integer, pid As String) As String
        ' ベースURLと固定パスを結合
        Dim url As String = portalUrl & constPath & "?mid=" & cnt.ToString()

        ' mkeyの生成
        Dim cntStr As String = cnt.ToString()
        Dim pidStr As String = If(pid, "")
        Dim hashInput As String = cntStr & pidStr
        Dim mkey As String = GenerateMD5Hash(hashInput)

        ' 最終的なURLを生成
        url &= "&mkey=" & mkey
        Return url
    End Function

    Public Shared Function GenerateMD5Hash(input As String) As String
        ' 入力文字列をMD5ハッシュ化
        Dim inputBytes As Byte() = Encoding.UTF8.GetBytes(input)

        Using md5 As MD5 = MD5.Create()
            Dim hashBytes As Byte() = md5.ComputeHash(inputBytes)
            Dim sb As New StringBuilder()
            For Each b As Byte In hashBytes
                sb.Append(b.ToString("x2"))
            Next
            ' 32文字の16進数文字列の最後の32文字を返す
            Dim hashHex As String = sb.ToString()
            'Return sb.ToString().Substring(0, 32)
            Return hashHex.Substring(hashHex.Length - 32, 32)
        End Using
    End Function

    Public Shared Function FormatDateTime(d As DateTime) As String

        Dim formattedDate As String = d.ToString("yyyy/MM/dd (ddd)", New System.Globalization.CultureInfo("ja-JP"))

        Return formattedDate

    End Function

    Public Shared Function SetMailSubjectAndBody(mail As MailMessage, title As String,
                                                 userInfo As UserInfo, Optional appInfo As ApplyInfo = Nothing,
                                                 Optional qaId As String = Nothing, Optional 出講師PKey As String = Nothing) As MailMessage

        '件名と本文をメールに設定する
        Using spm As New StoredProcedureManager("PT_EMAIL_TEXT_OUTPUT")
            spm.AddPrmIn("@TITLE", Data.SqlDbType.NVarChar, 20, title)
            spm.AddPrmOut("@mailId", Data.SqlDbType.NVarChar, 20)
            spm.AddPrmOut("@件名", Data.SqlDbType.NVarChar, -1)
            spm.AddPrmOut("@本文", Data.SqlDbType.NVarChar, -1)
            spm.Fill()

            mail.Subject = spm.GetValue("@件名")
            mail.Body = spm.GetValue("@本文")
            Dim mailId As String = spm.GetValue("@mailId")

            '変数名-参照テーブル名-参照項目名のリスト
            Dim dt = spm.ds.Tables(0)

            If dt.Rows.Count > 0 Then
                For Each r As DataRow In dt.Rows
                    Dim valName As String = If(r("変数名") Is DBNull.Value, String.Empty, r("変数名").ToString())
                    Dim tblName As String = If(r("TBL名") Is DBNull.Value, String.Empty, r("TBL名").ToString())
                    Dim itemName As String = If(r("項目名") Is DBNull.Value, String.Empty, r("項目名").ToString())
                    Dim tblCd As String = String.Empty
                    Dim vwCd As String = String.Empty
                    Dim vwName As String = If(r("VW名") Is DBNull.Value, String.Empty, r("VW名").ToString())
                    Dim vwKey As String = If(r("VWKey") Is DBNull.Value, String.Empty, r("VWKey").ToString())
                    Dim filterKey As String = String.Empty
                    Dim repValue As String = String.Empty

                    If Not String.IsNullOrEmpty(vwName) AndAlso Not String.IsNullOrEmpty(vwKey) Then

                        Dim vwNamestbl As DataTable = Com_Get_変数TABLE("MAILSUB_REF_PTVW")

                        If vwNamestbl.Rows.Count > 0 Then
                            For Each row As DataRow In vwNamestbl.Rows
                                Dim vwNameItemName As String = row("内容").ToString()
                                If vwName = vwNameItemName Then
                                    vwCd = row("CD").ToString()
                                End If
                            Next
                        End If


                        Select Case vwCd
                            Case valCd_VW_PT_USERS 'VW_PT_USERS
                                filterKey = userInfo.PortalId
                            Case valCd_VW_PT_Apply　'VW_PT_申込
                                filterKey = appInfo.PKey
                            Case valCd_VW_PT_QA　'VW_PT_問合せ
                                filterKey = qaId
                            Case valCd_VW_PT_Gakuen　'VW_PT_学園
                                filterKey = userInfo.GakuenCd
                            Case valCd_VW_PT_Teachers　'VW_PT_出講師 ADD 20260114 S.Iguchi
                                filterKey = 出講師PKey
                            Case Else
                                '該当テーブルのキー設定が存在しない場合、変数を空文字列に置換して無効化
                                mail.Subject = mail.Subject.Replace(valName, "")
                                mail.Body = mail.Body.Replace(valName, "")
                                Continue For
                        End Select
                    Else

                        Dim tblNamestbl As DataTable = Com_Get_変数TABLE("MAILSUB_REF_TBL")

                        If tblNamestbl.Rows.Count > 0 Then
                            For Each row As DataRow In tblNamestbl.Rows
                                Dim tblNameItemName As String = row("内容").ToString()
                                If tblName = tblNameItemName Then
                                    tblCd = row("CD").ToString()
                                End If
                            Next
                        End If

                        'テーブル名に応じてキーの値を動的に設定
                        Select Case tblCd
                            Case valCd_TBL_Gakuen
                                filterKey = userInfo.GakuenCd
                            Case valCd_TBL_QA
                                filterKey = qaId.Split("-")(0)
                            Case valCd_TBL_Apply
                                filterKey = appInfo.SeqNo
                            Case valCd_TBL_BaseInfo '研修生ユーザの場合のみ適用
                                filterKey = userInfo.InvoiceNo
                            Case valCd_TBL_Staff
                                filterKey = userInfo.UserCd
                            Case valCd_TBL_NewAccount
                                filterKey = userInfo.AccountKey
                            Case Else
                                '該当テーブルのキー設定が存在しない場合、変数を空文字列に置換して無効化
                                mail.Subject = mail.Subject.Replace(valName, "")
                                mail.Body = mail.Body.Replace(valName, "")
                                Continue For
                        End Select

                    End If
                    '変数が存在しない場合は置換文字列を取得しない
                    If mail.Subject.IndexOf(valName) = -1 AndAlso mail.Body.IndexOf(valName) = -1 Then
                        Continue For
                    End If

                    '置換文字列の取得
                    repValue = GetReplacedValue(mailId, valName, filterKey)
                    ' プレースホルダを置換
                    mail.Subject = mail.Subject.Replace(valName, repValue)
                    mail.Body = mail.Body.Replace(valName, repValue)
                Next
            End If
        End Using

        Return mail
    End Function

    Public Shared Function GetReplacedValue(mailId As String, valName As String, key As String) As String

        Dim repVal As String = ""
        Using spm As New StoredProcedureManager("PT_EMAIL_REPLACEVALUE_OUTPUT")
            spm.AddPrmIn("@mailId", Data.SqlDbType.VarChar, 20, mailId)
            spm.AddPrmIn("@変数名", Data.SqlDbType.NVarChar, 50, valName)
            spm.AddPrmIn("@key", Data.SqlDbType.NVarChar, -1, key)
            spm.AddPrmOut("@repVal", Data.SqlDbType.NVarChar, -1)
            spm.Exec()

            repVal = spm.GetValue("@repVal")
        End Using
        Return repVal
    End Function

    Public Shared Function GetDicVal(dic As Dictionary(Of String, String), key As String) As String
        Dim val As String = ""
        If dic.ContainsKey(key) Then
            val = dic(key)
        End If
        Return val
    End Function
End Class
