import { FormEvent, useCallback, useEffect, useState } from 'react';
import {
    Alert,
    Box,
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Grid,
    MenuItem,
    Stack,
} from '@mui/material';
import CloudUploadIcon from '@mui/icons-material/CloudUpload';
import api from '../services/api';
import CdrGrid from '../components/ui/CdrGrid';
import AppCard from '../components/ui/Card';
import AppButton from '../components/ui/Button';
import AppTextField from '../components/ui/TextField';
import TypographyAnimated from '@/components/ui/TypographyAnimated';
import { useLocale } from '@/context/LocaleContext';
import Swal from 'sweetalert2';

export type CdrAgent = {
    id: number;
    name: string;
    surname: string;
};

export type CdrContact = {
    id: number;
    name: string;
};

export type CdrRow = {
    id: number;
    calldate: string;
    phone: string;
    total_duration: number;
    audio_url: string | null;
    agent: CdrAgent | null;
    contact: CdrContact | null;
    compliance_avg: number;
};

export type AgentOption = {
    id: number;
    name: string;
    surname: string;
};

type PaginatorMeta = {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
};

const LIST_PATH = import.meta.env.VITE_CDRS_ENDPOINT ?? '/api/cdrs';
const AGENTS_PATH = import.meta.env.VITE_AGENTS_ENDPOINT ?? '/api/agents';
const CONTACTS_PATH = import.meta.env.VITE_CONTACTS_ENDPOINT ?? '/api/contacts';
const CDR_UPLOAD_AUDIO_PATH =
    import.meta.env.VITE_CDRS_UPLOAD_AUDIO_ENDPOINT ?? '/api/cdrs/upload-audio';
const CDR_DELETE_PATH = import.meta.env.VITE_CDRS_DELETE_ENDPOINT ?? '/api/cdrs';

const CDR_UPLOAD_AUDIO_ACCEPT =
    '.mp3,.wav,.flac,audio/mpeg,audio/mp3,audio/wav,audio/x-wav,audio/flac,audio/x-flac';

function isAllowedCdrUploadExtension(file: File): boolean {
    const name = file.name.toLowerCase();
    return name.endsWith('.mp3') || name.endsWith('.wav') || name.endsWith('.flac');
}

function todayAsDdMmYyyy(): string {
    const now = new Date();
    const day = String(now.getDate()).padStart(2, '0');
    const month = String(now.getMonth() + 1).padStart(2, '0');
    const year = now.getFullYear();
    return `${day}/${month}/${year}`;
}

function withHighZIndex() {
    const container = Swal.getContainer();
    if (container) {
        container.style.zIndex = '2000';
    }
}


export default function Cdr() {
    const { t } = useLocale();

    const [phone, setPhone] = useState('');
    const [agentId, setAgentId] = useState('');
    const [appliedPhone, setAppliedPhone] = useState('');
    const [appliedAgentId, setAppliedAgentId] = useState('');
    const [agents, setAgents] = useState<AgentOption[]>([]);
    const [contacts, setContacts] = useState<CdrContact[]>([]);
    const [rows, setRows] = useState<CdrRow[]>([]);
    const [meta, setMeta] = useState<PaginatorMeta | null>(null);
    const [page, setPage] = useState(1);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [success, setSuccess] = useState<string | null>(null);
    const [uploadOpen, setUploadOpen] = useState(false);
    const [uploading, setUploading] = useState(false);
    const [uploadDate, setUploadDate] = useState(todayAsDdMmYyyy());
    const [uploadPhone, setUploadPhone] = useState('');
    const [uploadAgentId, setUploadAgentId] = useState('');
    const [uploadContactId, setUploadContactId] = useState('');
    const [uploadFile, setUploadFile] = useState<File | null>(null);

    const fetchAgents = useCallback(async () => {
        try {
            const { data } = await api.get<AgentOption[] | { data: AgentOption[] }>(
                AGENTS_PATH,
            );
            const list = Array.isArray(data) ? data : data?.data ?? [];
            setAgents(list);
        } catch {
            setAgents([]);
        }
    }, []);

    const fetchContacts = useCallback(async () => {
        try {
            const { data } = await api.get<CdrContact[] | { data: CdrContact[] }>(
                CONTACTS_PATH,
            );
            const list = Array.isArray(data) ? data : data?.data ?? [];
            setContacts(list);
        } catch {
            setContacts([]);
        }
    }, []);

    const fetchList = useCallback(
        async (p: number, phoneFilter: string, agent: string) => {
            setLoading(true);
            setError(null);
            try {
                const { data } = await api.get<
                    | {
                          data: CdrRow[];
                          current_page: number;
                          last_page: number;
                          per_page: number;
                          total: number;
                      }
                    | {
                          cdrs: {
                              data: CdrRow[];
                              current_page: number;
                              last_page: number;
                              per_page: number;
                              total: number;
                          };
                      }
                >(LIST_PATH, {
                    params: {
                        page: p,
                        phone: phoneFilter || undefined,
                        agent_id: agent || undefined,
                    },
                });

                const payload =
                    'cdrs' in data && data.cdrs
                        ? data.cdrs
                        : (data as {
                              data: CdrRow[];
                              current_page: number;
                              last_page: number;
                              per_page: number;
                              total: number;
                          });

                setRows(Array.isArray(payload.data) ? payload.data : []);
                setMeta({
                    current_page: payload.current_page ?? 1,
                    last_page: payload.last_page ?? 1,
                    per_page: payload.per_page ?? 15,
                    total: payload.total ?? 0,
                });
            } catch {
                setRows([]);
                setMeta(null);
                setError(t('cdr', 'error_carga'));
            } finally {
                setLoading(false);
            }
        },
        [],
    );

    useEffect(() => {
        void fetchAgents();
    }, [fetchAgents]);

    useEffect(() => {
        void fetchContacts();
    }, [fetchContacts]);

    useEffect(() => {
        void fetchList(page, appliedPhone, appliedAgentId);
    }, [page, appliedPhone, appliedAgentId, fetchList]);

    function onSearch(e: FormEvent) {
        e.preventDefault();
        setAppliedPhone(phone);
        setAppliedAgentId(agentId);
        setPage(1);
    }

    function onClear() {
        setPhone('');
        setAgentId('');
        setAppliedPhone('');
        setAppliedAgentId('');
        setPage(1);
        setSuccess(null);
        setError(null);
    }

    function resetUploadForm() {
        setUploadDate(todayAsDdMmYyyy());
        setUploadPhone('');
        setUploadAgentId('');
        setUploadContactId('');
        setUploadFile(null);
    }

    function openUploadModal() {
        resetUploadForm();
        setUploadOpen(true);
    }

    async function onUploadSave() {
        if (!uploadFile) {
            await Swal.fire({
                title: t('cdr', 'falta_archivo'),
                text: t('cdr', 'debe_seleccionar_un_archivo_de_audio'),
                icon: 'warning',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
            return;
        }
        if (!isAllowedCdrUploadExtension(uploadFile)) {
            await Swal.fire({
                title: t('cdr', 'formato_archivo_no_permitido'),
                text: t('cdr', 'solo_se_permiten_mp3_wav_flac'),
                icon: 'warning',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
            return;
        }
        if (!uploadDate || !uploadPhone || !uploadAgentId || !uploadContactId) {
            await Swal.fire({
                title: t('cdr', 'faltan_datos'),
                text: t('cdr', 'complete_todos_los_campos_del_formulario_de_carga'),
                icon: 'warning',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
            return;
        }

        const confirm = await Swal.fire({
            title: t('cdr', 'confirmar_carga'),
            text: t('cdr', 'se_guardara_el_audio_y_se_creara_el_registro_cdr'),
            icon: 'question',
            showCancelButton: true,
            confirmButtonText: t('cdr', 'si_guardar'),
            cancelButtonText: 'Cancelar',
            didOpen: withHighZIndex,
        });
        if (!confirm.isConfirmed) {
            return;
        }

        setUploading(true);
        setError(null);
        setSuccess(null);
        try {
            const fd = new FormData();
            fd.append('calldate', uploadDate);
            fd.append('phone', uploadPhone);
            fd.append('agent_id', uploadAgentId);
            fd.append('contact_id', uploadContactId);
            fd.append('audio', uploadFile);

            const { data } = await api.post<{ message?: string }>(
                CDR_UPLOAD_AUDIO_PATH,
                fd,
            );

            setUploadOpen(false);
            setSuccess(data.message ?? t('cdr', 'audio_guardado_correctamente'));
            await Swal.fire({
                title: t('cdr', 'guardado'),
                text: data.message ?? t('cdr', 'audio_guardado_correctamente'),
                icon: 'success',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
            void fetchList(page, appliedPhone, appliedAgentId);
        } catch (err: unknown) {
            const apiMessage =
                err &&
                typeof err === 'object' &&
                'response' in err &&
                err.response &&
                typeof err.response === 'object' &&
                'data' in err.response &&
                err.response.data &&
                typeof err.response.data === 'object' &&
                'message' in err.response.data &&
                typeof err.response.data.message === 'string'
                    ? err.response.data.message
                    : t('cdr', 'no_se_pudo_guardar_el_audio');
            setError(apiMessage);
            await Swal.fire({
                title: t('cdr', 'error'),
                text: apiMessage,
                icon: 'error',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
        } finally {
            setUploading(false);
        }
    }

    async function onDeleteCdr(cdrId: number) {
        const confirm = await Swal.fire({
            title: t('cdr', 'confirmar_eliminacion'),
            text: t('cdr', 'se_eliminara_el_audio_cdr_transcripcion_e_indicadores_relacionados'),
            icon: 'warning',
            showCancelButton: true,
            confirmButtonText: t('cdr', 'si_eliminar'),
            cancelButtonText: t('cdr', 'cancelar'),
            didOpen: withHighZIndex,
        });
        if (!confirm.isConfirmed) {
            return;
        }

        setLoading(true);
        setError(null);
        setSuccess(null);
        try {
            const { data } = await api.delete<{ message?: string }>(
                `${CDR_DELETE_PATH}/${cdrId}`,
            );
            setSuccess(data.message ?? t('cdr', 'cdr_eliminado_correctamente'));
            await Swal.fire({
                title: t('cdr', 'eliminado'),
                text: data.message ?? t('cdr', 'cdr_eliminado_correctamente'),
                icon: 'success',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
            void fetchList(page, appliedPhone, appliedAgentId);
        } catch (err: unknown) {
            const apiMessage =
                err &&
                typeof err === 'object' &&
                'response' in err &&
                err.response &&
                typeof err.response === 'object' &&
                'data' in err.response &&
                err.response.data &&
                typeof err.response.data === 'object' &&
                'message' in err.response.data &&
                typeof err.response.data.message === 'string'
                    ? err.response.data.message
                    : t('cdr', 'no_se_pudo_eliminar_el_cdr');
            setError(apiMessage);
            await Swal.fire({
                title: t('cdr', 'error'),
                text: apiMessage,
                icon: 'error',
                confirmButtonText: t('cdr', 'aceptar'),
                didOpen: withHighZIndex,
            });
        } finally {
            setLoading(false);
        }
    }

    return (
        <div className="container-fluid">
            <AppCard>
                <Stack spacing={2.5}>
                    <TypographyAnimated
                        variant="subtitle2"
                        prefix={t('cdr', 'top_heading_prefix')}
                        rotatingWords={t('cdr', 'top_heading_rotating')
                            .split('|')
                            .map((s) => s.trim())
                            .filter(Boolean)}
                        sx={{
                            color: 'text.primary',
                            fontWeight: 600,
                            textTransform: 'uppercase',
                            letterSpacing: '0.18em',
                            fontSize: '1.3rem',
                        }}
                    />
                    <Box component="form" onSubmit={onSearch}>
                        <Grid container spacing={2} alignItems="flex-end" mt={3}>
                            <Grid size={{ xs: 12, md: 3 }}>
                                <AppTextField
                                    fullWidth
                                    label={t('cdr', 'telefono')}
                                    name="phone"
                                    value={phone}
                                    onChange={(e) => setPhone(e.target.value)}
                                    placeholder={t('cdr', 'buscar_por_telefono_placeholder')}
                                    size="small"
                                />
                            </Grid>

                            <Grid size={{ xs: 12, md: 4 }}>
                                <AppTextField
                                    fullWidth
                                    select
                                    label={t('cdr', 'agente')}
                                    name="agent_id"
                                    value={agentId}
                                    onChange={(e) => setAgentId(e.target.value)}
                                    size="small"
                                >
                                    <MenuItem value="">{t('cdr', 'todos_agentes')}</MenuItem>
                                    {agents.map((agent) => (
                                        <MenuItem key={agent.id} value={agent.id}>
                                            {agent.name} {agent.surname}
                                        </MenuItem>
                                    ))}
                                </AppTextField>
                            </Grid>

                            <Grid size={{ xs: 12, md: 5 }}>
                                <Stack direction="row" spacing={1.5}>
                                    <AppButton
                                        type="submit"
                                        variant="contained"
                                        disabled={loading}
                                    >
                                        {t('cdr', 'buscar')}
                                    </AppButton>
                                    <AppButton
                                        type="button"
                                        variant="outlined"
                                        onClick={onClear}
                                        disabled={loading}
                                    >
                                        {t('cdr', 'limpiar')}
                                    </AppButton>
                                    <AppButton
                                        type="button"
                                        variant="contained"
                                        color="success"
                                        onClick={openUploadModal}
                                        disabled={loading}
                                    >
                                        <CloudUploadIcon fontSize="small" sx={{ mr: 1 }} />
                                        {t('cdr', 'subir')}
                                    </AppButton>
                                </Stack>
                            </Grid>
                        </Grid>
                    </Box>

                    <Dialog
                        open={uploadOpen}
                        onClose={() => setUploadOpen(false)}
                        fullWidth
                        maxWidth="sm"
                    >
                        <DialogTitle>{t('cdr', 'subir_audio')}</DialogTitle>
                        <DialogContent>
                            <Stack spacing={2} sx={{ mt: 2 }}>
                                <Grid container spacing={2} padding={2}>
                                    <Grid size={{ xs: 12, md: 12 }} mb={3}>
                                        <AppTextField
                                            label={t('cdr', 'fecha')}
                                            value={uploadDate}
                                            onChange={(e) => setUploadDate(e.target.value)}
                                            placeholder="dd/mm/yyyy"
                                            fullWidth
                                        />
                                    </Grid>
                                    <Grid size={{ xs: 12, md: 12 }} mb={3}>
                                        <AppTextField
                                            label={t('cdr', 'telefono')}
                                            value={uploadPhone}
                                            onChange={(e) => setUploadPhone(e.target.value)}
                                            fullWidth
                                        />
                                    </Grid>
                                    <Grid size={{ xs: 12, md: 12 }} mb={3}>
                                        <AppTextField
                                            select
                                            label={t('cdr', 'agente')}
                                            value={uploadAgentId}
                                            onChange={(e) => setUploadAgentId(e.target.value)}
                                            fullWidth
                                        >
                                            <MenuItem value="">{t('cdr', 'seleccionar_agente')}</MenuItem>
                                            {agents.map((agent) => (
                                                <MenuItem key={agent.id} value={String(agent.id)}>
                                                    {agent.name} {agent.surname}
                                                </MenuItem>
                                            ))}
                                        </AppTextField>
                                    </Grid>
                                    <Grid size={{ xs: 12, md: 12 }} mb={3}>
                                        <AppTextField
                                            select
                                            label={t('cdr', 'contacto')}
                                            value={uploadContactId}
                                            onChange={(e) => setUploadContactId(e.target.value)}
                                            fullWidth
                                        >
                                            <MenuItem value="">{t('cdr', 'seleccionar_contacto')}</MenuItem>
                                            {contacts.map((contact) => (
                                                <MenuItem key={contact.id} value={String(contact.id)}>
                                                    {contact.name}
                                                </MenuItem>
                                            ))}
                                        </AppTextField>
                                    </Grid>
                                    <Grid size={{ xs: 12, md: 12 }} mb={3}>
                                        <AppTextField
                                            type="file"
                                            inputProps={{ accept: CDR_UPLOAD_AUDIO_ACCEPT }}
                                            label={t('cdr', 'audio_file')}
                                            onChange={(e) => {
                                                const input = e.target as HTMLInputElement;
                                                const file = input.files?.[0] ?? null;
                                                if (file && !isAllowedCdrUploadExtension(file)) {
                                                    input.value = '';
                                                    setUploadFile(null);
                                                    void Swal.fire({
                                                        title: t('cdr', 'formato_archivo_no_permitido'),
                                                        text: t('cdr', 'solo_se_permiten_mp3_wav_flac'),
                                                        icon: 'warning',
                                                        confirmButtonText: t('cdr', 'aceptar'),
                                                        didOpen: withHighZIndex,
                                                    });
                                                    return;
                                                }
                                                setUploadFile(file);
                                            }}
                                            fullWidth
                                        />
                                        <span className="text-sm text-gray-500">{t('cdr', 'solo_se_permiten_2_canales')}</span>
                                    </Grid>
                                </Grid>
                            </Stack>
                        </DialogContent>
                        <DialogActions sx={{ px: 3, pb: 2 }}>
                            <AppButton
                                type="button"
                                variant="outlined"
                                onClick={() => setUploadOpen(false)}
                                disabled={uploading}
                            >
                                {t('cdr', 'cancelar')}
                            </AppButton>
                            <AppButton
                                type="button"
                                variant="contained"
                                onClick={() => void onUploadSave()}
                                disabled={uploading}
                            >
                                {uploading ? t('cdr', 'guardando') : t('cdr', 'guardar')}
                            </AppButton>
                        </DialogActions>
                    </Dialog>

                    {success ? (
                        <Alert severity="success" onClose={() => setSuccess(null)}>
                            {success}
                        </Alert>
                    ) : null}

                    {error ? (
                        <Alert severity="error" onClose={() => setError(null)}>
                            {error}
                        </Alert>
                    ) : null}

                    <CdrGrid
                        rows={rows}
                        loading={loading}
                        meta={meta}
                        labels={{
                            fecha: t('cdr', 'fecha'),
                            telefono: t('cdr', 'telefono'),
                            agente: t('cdr', 'agente'),
                            contacto: t('cdr', 'contacto'),
                            duracion: t('cdr', 'duracion'),
                            archivo: t('cdr', 'archivo'),
                            cumplimiento: t('cdr', 'cumplimiento'),
                            acciones: t('cdr', 'acciones'),
                            sinAgente: t('cdr', 'sin_agente'),
                            sinContacto: t('cdr', 'sin_contacto'),
                            sinArchivo: t('cdr', 'sin_archivo'),
                            ver: t('cdr', 'ver'),
                            noLlamadas: t('cdr', 'no_data_to_show'),
                            audioNoSoporte: t('cdr', 'audioNoSoporte'),
                            cargando: t('cdr', 'cargando'),
                        }}
                        onPageChange={setPage}
                        onDelete={(id) => void onDeleteCdr(id)}
                    />
                </Stack>
            </AppCard>
        </div>
    );
}
