package com.example.los_chatos.screens

import android.Manifest
import android.content.ContentValues
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Paint
import android.graphics.pdf.PdfDocument
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.los_chatos.network.ReportStudent
import com.example.los_chatos.network.RetrofitClient
import com.example.los_chatos.ui.theme.Los_chatosTheme
import kotlinx.coroutines.launch

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ReportsScreen(navController: NavController, modifier: Modifier = Modifier) {
    var semesters by remember { mutableStateOf<List<String>>(emptyList()) }
    var selectedSemester by remember { mutableStateOf("") }
    var expanded by remember { mutableStateOf(false) }
    var reportData by remember { mutableStateOf<List<ReportStudent>>(emptyList()) }
    var isLoading by remember { mutableStateOf(false) }
    var errorMessage by remember { mutableStateOf<String?>(null) }
    val coroutineScope = rememberCoroutineScope()
    val context = LocalContext.current

    val permissionLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestPermission(),
        onResult = { isGranted: Boolean ->
            if (isGranted) {
                savePdfToDownloads(context, reportData, "reporte_${selectedSemester}.pdf")
            } else {
                Toast.makeText(context, "Permiso denegado. No se puede guardar el reporte.", Toast.LENGTH_LONG).show()
            }
        }
    )

    LaunchedEffect(Unit) {
        isLoading = true
        try {
            val response = RetrofitClient.instance.getSemesters()
            if (response.isSuccessful) {
                semesters = response.body() ?: emptyList()
                if (semesters.isNotEmpty()) {
                    selectedSemester = semesters[0]
                }
            } else {
                errorMessage = "No se pudieron cargar los semestres."
            }
        } catch (e: Exception) {
            errorMessage = "Error de red al cargar semestres."
        } finally {
            isLoading = false
        }
    }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Generar Reportes") },
                navigationIcon = {
                    IconButton(onClick = { navController.popBackStack() }) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Atrás")
                    }
                }
            )
        }
    ) { innerPadding ->
        Column(modifier = Modifier.padding(innerPadding).padding(16.dp)) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                ExposedDropdownMenuBox(
                    expanded = expanded,
                    onExpandedChange = { expanded = !expanded },
                    modifier = Modifier.weight(1f)
                ) {
                    OutlinedTextField(
                        modifier = Modifier.menuAnchor().fillMaxWidth(),
                        value = selectedSemester,
                        onValueChange = {},
                        readOnly = true,
                        label = { Text("Seleccionar Semestre") },
                        trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }
                    )
                    ExposedDropdownMenu(
                        expanded = expanded,
                        onDismissRequest = { expanded = false }
                    ) {
                        semesters.forEach { semester ->
                            DropdownMenuItem(
                                text = { Text(semester) },
                                onClick = {
                                    selectedSemester = semester
                                    expanded = false
                                }
                            )
                        }
                    }
                }
                Spacer(modifier = Modifier.width(8.dp))
                Button(onClick = {
                    coroutineScope.launch {
                        isLoading = true
                        errorMessage = null
                        reportData = emptyList()
                        try {
                            val response = RetrofitClient.instance.getReportData(selectedSemester)
                            if (response.isSuccessful) {
                                reportData = response.body() ?: emptyList()
                            } else {
                                errorMessage = "Error al generar el reporte."
                            }
                        } catch (e: Exception) {
                            errorMessage = "Error de red: ${e.message}"
                        } finally {
                            isLoading = false
                        }
                    }
                }, enabled = selectedSemester.isNotEmpty() && !isLoading) {
                    Text("Generar")
                }
            }

            Spacer(modifier = Modifier.height(16.dp))

            if (isLoading) {
                CircularProgressIndicator(modifier = Modifier.align(Alignment.CenterHorizontally))
            }

            errorMessage?.let {
                Text(it, color = MaterialTheme.colorScheme.error)
            }

            if (reportData.isNotEmpty()) {
                Button(
                    onClick = {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            savePdfToDownloads(context, reportData, "reporte_${selectedSemester}.pdf")
                        } else {
                            when {
                                ContextCompat.checkSelfPermission(
                                    context,
                                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                                ) == PackageManager.PERMISSION_GRANTED -> {
                                    savePdfToDownloads(context, reportData, "reporte_${selectedSemester}.pdf")
                                }
                                else -> {
                                    permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                                }
                            }
                        }
                    },
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Text("Descargar Reporte en PDF")
                }
                Spacer(modifier = Modifier.height(16.dp))
                LazyColumn {
                    items(reportData) { student ->
                        StudentReportCard(student = student)
                    }
                }
            }
        }
    }
}

private fun savePdfToDownloads(context: Context, data: List<ReportStudent>, fileName: String) {
    val pdfDocument = PdfDocument()
    val pageInfo = PdfDocument.PageInfo.Builder(595, 842, 1).create() // A4 page size
    var page = pdfDocument.startPage(pageInfo)
    var canvas = page.canvas
    val paint = Paint()
    var yPosition = 40f
    val leftMargin = 40f

    paint.textSize = 16f
    paint.isFakeBoldText = true
    canvas.drawText("Reporte de Calificaciones", leftMargin, yPosition, paint)
    yPosition += 40f

    paint.isFakeBoldText = false
    paint.textSize = 12f

    data.forEach { student ->
        val estimatedHeight = 40f + (student.courses.size * 25f) + (student.courses.sumOf { it.grades.size } * 15f)

        if (yPosition + estimatedHeight > 800) {
            pdfDocument.finishPage(page)
            page = pdfDocument.startPage(pageInfo)
            canvas = page.canvas
            yPosition = 40f

            paint.textSize = 16f
            paint.isFakeBoldText = true
            canvas.drawText("Reporte de Calificaciones (Cont.)", leftMargin, yPosition, paint)
            yPosition += 40f
            paint.isFakeBoldText = false
            paint.textSize = 12f
        }

        paint.isFakeBoldText = true
        canvas.drawText(student.fullName, leftMargin, yPosition, paint)
        yPosition += 15f
        paint.isFakeBoldText = false
        canvas.drawText("@${student.username}", leftMargin, yPosition, paint)
        yPosition += 25f

        student.courses.forEach { course ->
            canvas.drawText("Curso: ${course.name} (Prof: ${course.professor})", leftMargin + 10f, yPosition, paint)
            yPosition += 20f

            course.grades.forEach { grade ->
                canvas.drawText("${grade.gradeName}: ${grade.gradeValue}", leftMargin + 20f, yPosition, paint)
                yPosition += 15f
            }
            yPosition += 10f
        }
        yPosition += 20f
    }

    pdfDocument.finishPage(page)

    val contentValues = ContentValues().apply {
        put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
        put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
        put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
    }

    val resolver = context.contentResolver
    val uri = resolver.insert(MediaStore.Files.getContentUri("external"), contentValues)

    if (uri != null) {
        try {
            resolver.openOutputStream(uri)?.use { outputStream ->
                pdfDocument.writeTo(outputStream)
                Toast.makeText(context, "Reporte guardado en Descargas", Toast.LENGTH_LONG).show()
            }
        } catch (e: Exception) {
            Toast.makeText(context, "Error al guardar el PDF: ${e.message}", Toast.LENGTH_LONG).show()
        } finally {
            pdfDocument.close()
        }
    } else {
        Toast.makeText(context, "No se pudo crear el archivo PDF.", Toast.LENGTH_LONG).show()
        pdfDocument.close()
    }
}

@Composable
fun StudentReportCard(student: ReportStudent) {
    Card(modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(student.fullName, fontWeight = FontWeight.Bold, fontSize = 18.sp)
            Text("@${student.username}", fontSize = 14.sp, color = MaterialTheme.colorScheme.secondary)
            Spacer(modifier = Modifier.height(8.dp))
            student.courses.forEach { course ->
                Text(course.name, fontWeight = FontWeight.SemiBold, modifier = Modifier.padding(top = 8.dp))
                course.grades.forEach { grade ->
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        Text(grade.gradeName)
                        Text(grade.gradeValue)
                    }
                }
            }
        }
    }
}

@Preview(showBackground = true)
@Composable
fun ReportsScreenPreview() {
    Los_chatosTheme {
        ReportsScreen(rememberNavController())
    }
}
