import { betterAuth } from 'better-auth'
import Database from 'better-sqlite3'
import { organization, jwt } from 'better-auth/plugins'
import { resend } from './mail'
import {
  accessControl,
  employerRole,
  worksCouncilMemberRole,
  employeeRole,
  adminRole,
  ownerRole,
  ROLES,
  type LegalRole
} from './permissions'

const db = new Database('./sqlite.db')

export const auth = betterAuth({
  database: db,
  onAPIError: { throw: true },
  emailAndPassword: { enabled: true, autoSignIn: false, minPasswordLength: 1 },
  trustedOrigins: ['http://localhost:3001'],
  plugins: [
    jwt({
      jwt: {
        issuer: 'http://192.168.178.114:3001',
        expirationTime: '1yr',
        definePayload: ({ user, session }) => {
          let userRoles: string[] = []

          if (session.activeOrganizationId) {
            try {
              const roleQuery = db.prepare(`
                SELECT role 
                FROM member 
                WHERE userId = ? AND organizationId = ?
              `)
              const memberRole = roleQuery.get(user.id, session.activeOrganizationId) as { role: string } | undefined

              if (memberRole?.role) {
                userRoles = [memberRole.role]
              }
            } catch (error) {
              console.error('Error querying user role:', error)
            }
          }

          return {
            id: user.id,
            name: user.name,
            roles: userRoles,
            organizationId: session.activeOrganizationId
          }
        }
      },
      jwks: {
        keyPairConfig: {
          // Supported by NimbusJwtDecoder
          alg: 'ES512'
        }
      }
    }),
    organization({
      // Pass the access control instance and roles
      ac: accessControl,
      roles: {
        [ROLES.EMPLOYER]: employerRole,
        [ROLES.WORKS_COUNCIL_MEMBER]: worksCouncilMemberRole,
        [ROLES.EMPLOYEE]: employeeRole,
        [ROLES.ADMIN]: adminRole,
        [ROLES.OWNER]: ownerRole
      },
      creatorRole: ROLES.ADMIN, // OWNER fixen here!

      async sendInvitationEmail(data) {
        console.log('Sending invitation email', data)
        const inviteLink = `http://192.168.178.114:3001/accept-invitation/${data.id}`

        const roleDisplayNames = {
          [ROLES.EMPLOYER]: 'Arbeitgeber',
          [ROLES.EMPLOYEE]: 'Arbeitnehmer',
          [ROLES.WORKS_COUNCIL_MEMBER]: 'Betriebsrat',
          [ROLES.ADMIN]: 'Administrator',
          [ROLES.OWNER]: 'Eigentümer'
        }

        const roleDisplayName = roleDisplayNames[data.role as LegalRole] || data.role

        try {
          const result = await resend.emails.send({
            from: 'Acme <onboarding@resend.dev>',
            to: data.email,
            subject: `Einladung als ${roleDisplayName} - ${data.organization.name}`,
            html: `
              <h2>Einladung zur Organisation ${data.organization.name}</h2>
              <p>Sie wurden als <strong>${roleDisplayName}</strong> eingeladen.</p>
              <p><a href="${inviteLink}" style="background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Einladung annehmen</a></p>
              <p>Diese Einladung läuft ab am: ${new Date(data.invitation.expiresAt).toLocaleDateString('de-DE')}</p>
            `
          })

          if (result.error) {
            throw new Error(`Email sending failed: ${result.error.message || result.error.name || 'Unknown error'}`)
          }

          console.log('Email invite link:', inviteLink)
          console.log('Invitation email sent successfully to:', data.email, 'with ID:', result.data?.id)
        } catch (error) {
          console.error('Failed to send invitation email:', error)

          // Log specific error details for debugging
          const errorObj = error as { response?: { status: number; data: unknown }; message?: string }
          if (errorObj.response) {
            console.error('HTTP Status:', errorObj.response.status)
            console.error('Response data:', errorObj.response.data)
          }

          // Re-throw the error so BetterAuth knows the email failed
          const message = errorObj.message || String(error)
          throw new Error(`Email sending failed: ${message}`)
        }
      }
    })
  ]
})

export { ROLES }
export type { LegalRole }
