"use client";

import React, { useState, useMemo, useEffect } from 'react';
import { useSession } from "next-auth/react";
import { SessionWithTokens } from "@/config/authConfig";
import { AUTH } from "@/authorities";
import { 
  Box, 
  Card, 
  CardContent, 
  Typography, 
  MenuItem, 
  TextField, 
  Button, 
  Grid, 
  Divider,
  Chip,
  Autocomplete,
  Checkbox,
  FormControlLabel,
} from '@mui/material';
import DownloadIcon from '@mui/icons-material/Download';
import { REPORTS, ReportDefinition } from '@/config/reportConfig';
import { NEXT_PUBLIC_API_URL } from '@/config/api';
import { clientAuthFetch } from '@/app/utils/clientAuthFetch';
import SemiFGProductionAnalysisReport from './SemiFGProductionAnalysisReport';
import ReportSelectionDashboard from './ReportSelectionDashboard';
import { 
  fetchSemiFGItemCodes, 
  fetchSemiFGItemCodesWithCategory 
} from './semiFGProductionAnalysisApi';
import { generateGrnReportExcel } from './grnReportApi';
import {
  FEATURE_USAGE,
  FEATURE_USAGE_ACTION,
  logFeatureUsage,
} from '@/lib/featureUsageLog';

interface ItemCodeWithName {
  code: string;
  name: string;
}

export default function ReportPage() {
  const { data: session } = useSession() as { data: SessionWithTokens | null };
  const includeGrnFinancialColumns =
    session?.abilities?.includes(AUTH.ADMIN) ?? false;

  const [selectedReportId, setSelectedReportId] = useState<string>('');
  const [criteria, setCriteria] = useState<Record<string, string>>({});
  const [loading, setLoading] = useState(false);
  const [dynamicOptions, setDynamicOptions] = useState<Record<string, { label: string; value: string }[]>>({});
  const [showConfirmDialog, setShowConfirmDialog] = useState(false);
  
  // Find the configuration for the currently selected report
  const rep012RoundIds = useMemo(() => {
    if (selectedReportId !== 'rep-012') return [] as string[];
    return (criteria.stockTakeRoundId || '')
      .split(',')
      .map((s) => s.trim())
      .filter(Boolean);
  }, [selectedReportId, criteria.stockTakeRoundId]);

  const rep012MultiRound = rep012RoundIds.length > 1;

  const currentReport = useMemo(() => 
    REPORTS.find((r) => r.id === selectedReportId), 
  [selectedReportId]);

  const handleSelectReport = (reportId: string) => {
    if (reportId === selectedReportId) return;
    setSelectedReportId(reportId);
    setCriteria({});
  };

  const handleFieldChange = (name: string, value: string | string[]) => {
    const stringValue = Array.isArray(value) ? value.join(',') : value;
    setCriteria((prev) => ({ ...prev, [name]: stringValue }));
    
    // If this is stockCategory and there's a field that depends on it, fetch dynamic options
    if (name === 'stockCategory' && currentReport) {
      const itemCodeField = currentReport.fields.find(f => f.name === 'itemCode' && f.dynamicOptions);
      if (itemCodeField && itemCodeField.dynamicOptionsEndpoint) {
        fetchDynamicOptions(itemCodeField, stringValue);
      }
    }
  };

  const fetchDynamicOptions = async (field: any, paramValue: string) => {
    if (!field.dynamicOptionsEndpoint) return;
    
    try {
      // Use API service for SemiFG Production Analysis Report (rep-005)
      if (currentReport?.id === 'rep-005' && field.name === 'itemCode') {
        const itemCodesWithName = await fetchSemiFGItemCodes(paramValue);
        const itemsWithCategory = await fetchSemiFGItemCodesWithCategory(paramValue);
        
        const categoryMap: Record<string, { code: string; category: string; name?: string }> = {};
        itemsWithCategory.forEach(item => {
          categoryMap[item.code] = item;
        });
        
        const options = itemCodesWithName.map(item => {
          const code = item.code;
          const name = item.name || '';
          const category = categoryMap[code]?.category || '';
          
          let label = name ? `${code} ${name}` : code;
          if (category) {
            label = `${label} (${category})`;
          }
          
          return { label, value: code };
        });
        
        setDynamicOptions((prev) => ({ ...prev, [field.name]: options }));
        return;
      }
      
      // Handle other reports with dynamic options
      let url = field.dynamicOptionsEndpoint;
      if (paramValue && paramValue !== 'All' && !paramValue.includes('All')) {
        url = `${field.dynamicOptionsEndpoint}?${field.dynamicOptionsParam}=${paramValue}`;
      }

      const response = await clientAuthFetch(url, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
      });

      if (response.status === 401 || response.status === 403) return;
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);

      const data = await response.json();
      const options = Array.isArray(data) 
        ? data.map((item: any) => ({ label: item.label || item.name || item.code || String(item), value: item.value || item.code || String(item) }))
        : [];
      
      setDynamicOptions((prev) => ({ ...prev, [field.name]: options }));
    } catch (error) {
      console.error("Failed to fetch dynamic options:", error);
      setDynamicOptions((prev) => ({ ...prev, [field.name]: [] }));
    }
  };

  // Load initial options when report is selected
  useEffect(() => {
    if (currentReport) {
      currentReport.fields.forEach(field => {
        if (field.dynamicOptions && field.dynamicOptionsEndpoint) {
          // Load all options initially
          fetchDynamicOptions(field, '');
        }
      });
    }
    // Clear dynamic options when report changes
    setDynamicOptions({});

    // Default "All" (no filter) for stock take variance report conditions.
    if (selectedReportId === 'rep-012') {
      setCriteria({
        store_id: 'All',
        status: 'All',
      });
    }
  }, [selectedReportId]);

  /** rep-012：多選輪次時狀態固定為已審核 */
  useEffect(() => {
    if (selectedReportId !== 'rep-012' || !rep012MultiRound) return;
    if (criteria.status === 'completed') return;
    setCriteria((prev) => ({ ...prev, status: 'completed' }));
  }, [selectedReportId, rep012MultiRound, criteria.status]);

  // React 18 Strict Mode (dev) mounts → unmounts → remounts, so effects with [] run twice.
  // Dedupe PAGE_VIEW within a short window so 進入頁面次數 is +1 per real visit.
  useEffect(() => {
    if (typeof window === "undefined") return;
    const w = window as Window & { __fpsmsReportPageViewLoggedAt?: number };
    const now = Date.now();
    if (w.__fpsmsReportPageViewLoggedAt != null && now - w.__fpsmsReportPageViewLoggedAt < 2000) {
      return;
    }
    w.__fpsmsReportPageViewLoggedAt = now;
    logFeatureUsage(FEATURE_USAGE.REPORT_MANAGEMENT, FEATURE_USAGE_ACTION.PAGE_VIEW);
  }, []);

  const validateRequiredFields = () => {
    if (!currentReport) return true;

    if (currentReport.id === 'rep-012') {
      if (rep012RoundIds.length === 0) {
        alert('缺少必填條件:\n- 盤點輪次');
        return false;
      }
      return true;
    }

    // Mandatory Field Validation
    const missingFields = currentReport.fields
      .filter((field) => {
        if (!field.required) return false;
        return !criteria[field.name];
      })
      .map(field => field.label);

    if (missingFields.length > 0) {
      alert(`缺少必填條件:\n- ${missingFields.join('\n- ')}`);
      return false;
    }

    return true;
  };

  /** rep-012：單輪送 status；多輪送 stockTakeRoundId 清單且 status=completed */
  const buildRep012QueryString = (): string => {
    const p = new URLSearchParams();
    p.set('stockTakeRoundId', rep012RoundIds.join(','));
    const code = criteria.itemCode?.trim();
    if (code) p.set('itemCode', code);
    const store = criteria.store_id?.trim();
    if (store && store !== 'All') p.set('store_id', store);
    if (rep012MultiRound) {
      p.set('status', 'completed');
    } else {
      const status = criteria.status?.trim();
      if (status && status !== 'All') p.set('status', status);
    }
    return p.toString();
  };

  const handlePrint = async () => {
    if (!currentReport) return;
    if (!validateRequiredFields()) return;

    // For rep-005, the print logic is handled by SemiFGProductionAnalysisReport component
    if (currentReport.id === 'rep-005') return;

    // For Excel reports (e.g. GRN), fetch JSON and download as .xlsx
    if (currentReport.responseType === 'excel') {
      await executeExcelReport();
      return;
    }

    await executePrint();
  };

  const handleExcelPrint = async () => {
    if (!currentReport) return;
    if (!validateRequiredFields()) return;
    await executeExcelReport();
  };

  const executeExcelReport = async () => {
    if (!currentReport) return;
    setLoading(true);
    try {
      if (currentReport.id === 'rep-014') {
        await generateGrnReportExcel(
          criteria,
          currentReport.title,
          includeGrnFinancialColumns
        );
      } else {
        // Backend returns actual .xlsx bytes for this Excel endpoint.
        const queryParams =
          currentReport.id === 'rep-012'
            ? buildRep012QueryString()
            : new URLSearchParams(criteria).toString();
        const excelUrl = `${currentReport.apiEndpoint}-excel?${queryParams}`;

        const response = await clientAuthFetch(excelUrl, {
          method: 'GET',
          headers: { Accept: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' },
        });

        if (response.status === 401 || response.status === 403) return;
        if (!response.ok) {
          const errorText = await response.text();
          console.error("Response error:", errorText);
          throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
        }

        const blob = await response.blob();
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = downloadUrl;

        const contentDisposition = response.headers.get('Content-Disposition');
        let fileName = `${currentReport.title}.xlsx`;
        if (contentDisposition?.includes('filename=')) {
          fileName = contentDisposition.split('filename=')[1].split(';')[0].replace(/"/g, '');
        }

        link.setAttribute('download', fileName);
        document.body.appendChild(link);
        link.click();
        link.remove();
        window.URL.revokeObjectURL(downloadUrl);
      }
      if (currentReport) {
        logFeatureUsage(
          FEATURE_USAGE.REPORT_MANAGEMENT,
          FEATURE_USAGE_ACTION.DOWNLOAD,
          `${currentReport.id}:excel`,
        );
      }
      setShowConfirmDialog(false);
    } catch (error) {
      console.error("Failed to generate Excel report:", error);
      alert("An error occurred while generating the report. Please try again.");
    } finally {
      setLoading(false);
    }
  };

  const executePrint = async () => {
    if (!currentReport) return;

    setLoading(true);
    try {
      const queryParams =
        currentReport.id === 'rep-012'
          ? buildRep012QueryString()
          : new URLSearchParams(criteria).toString();
      const url = `${currentReport.apiEndpoint}?${queryParams}`;

      const response = await clientAuthFetch(url, {
        method: 'GET',
        headers: { 'Accept': 'application/pdf' },
      });

      if (response.status === 401 || response.status === 403) return;
      if (!response.ok) {
        const errorText = await response.text();
        console.error("Response error:", errorText);
        throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
      }

      const blob = await response.blob();
      const downloadUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;
      
      const contentDisposition = response.headers.get('Content-Disposition');
      let fileName = `${currentReport.title}.pdf`;
      if (contentDisposition?.includes('filename=')) {
        fileName = contentDisposition.split('filename=')[1].split(';')[0].replace(/"/g, '');
      }
      
      link.setAttribute('download', fileName);
      document.body.appendChild(link);
      link.click();
      link.remove();
      window.URL.revokeObjectURL(downloadUrl);

      logFeatureUsage(
        FEATURE_USAGE.REPORT_MANAGEMENT,
        FEATURE_USAGE_ACTION.DOWNLOAD,
        `${currentReport.id}:pdf`,
      );
      
      setShowConfirmDialog(false);
    } catch (error) {
      console.error("Failed to generate report:", error);
      alert("An error occurred while generating the report. Please try again.");
    } finally {
      setLoading(false);
    }
  };

  return (
    <Box sx={{ p: 4, maxWidth: 1280, margin: '0 auto' }}>
      <Typography variant="h4" gutterBottom fontWeight="bold">
        報告管理
      </Typography>

      <ReportSelectionDashboard
        selectedReportId={selectedReportId}
        onSelectReport={handleSelectReport}
      />

      {currentReport && (
        <Card sx={{ boxShadow: 3, animation: 'fadeIn 0.5s' }}>
          <CardContent>
            <Typography variant="h6" color="primary" gutterBottom>
              搜索條件: {currentReport.title}
            </Typography>
            <Divider sx={{ mb: 3 }} />
            
            <Grid container spacing={3}>
              {currentReport.fields.map((field) => {
                const options = field.dynamicOptions 
                  ? (dynamicOptions[field.name] || [])
                  : (field.options || []);
                const currentValue = criteria[field.name] || '';
                const valueForSelect = field.multiple 
                  ? (currentValue ? currentValue.split(',').map(v => v.trim()).filter(v => v) : [])
                  : currentValue;

                // Use larger grid size for 成品/半成品生產分析報告
                const gridSize = currentReport.id === 'rep-005' ? { xs: 12, sm: 12, md: 6 } : { xs: 12, sm: 6 };

                const disabledByCheckedCheckbox = currentReport.fields.some((f) => {
                  if (f.type !== 'checkbox' || criteria[f.name] !== 'true') return false;
                  return f.disablesFieldsWhenChecked?.includes(field.name) ?? false;
                });
                const disabledRep012Status =
                  currentReport.id === 'rep-012' &&
                  field.name === 'status' &&
                  rep012MultiRound;

                if (field.type === 'checkbox') {
                  return (
                    <Grid item {...gridSize} key={field.name}>
                      <FormControlLabel
                        control={
                          <Checkbox
                            checked={criteria[field.name] === 'true'}
                            onChange={(e) =>
                              handleFieldChange(field.name, e.target.checked ? 'true' : '')
                            }
                          />
                        }
                        label={field.label}
                      />
                    </Grid>
                  );
                }

                // Use Autocomplete for fields that allow input
                if (field.type === 'select' && field.allowInput) {
                  const autocompleteValue = field.multiple 
                    ? (Array.isArray(valueForSelect) ? valueForSelect : [])
                    : (valueForSelect || null);
                  
                  return (
                    <Grid item {...gridSize} key={field.name}>
                      <Autocomplete
                        multiple={field.multiple || false}
                        freeSolo
                        options={options.map(opt => opt.value)}
                        value={autocompleteValue}
                        onChange={(event, newValue, reason) => {
                          if (field.multiple) {
                            // Handle multiple selection - newValue is an array
                            let values: string[] = [];
                            if (Array.isArray(newValue)) {
                              values = newValue
                                .map(v => typeof v === 'string' ? v.trim() : String(v).trim())
                                .filter(v => v !== '');
                            }
                            handleFieldChange(field.name, values);
                          } else {
                            // Handle single selection - newValue can be string or null
                            const value = typeof newValue === 'string' ? newValue.trim() : (newValue || '');
                            handleFieldChange(field.name, value);
                          }
                        }}
                        onKeyDown={(event) => {
                          // Allow Enter key to add custom value in multiple mode
                          if (field.multiple && event.key === 'Enter') {
                            const target = event.target as HTMLInputElement;
                            if (target && target.value && target.value.trim()) {
                              const currentValues = Array.isArray(autocompleteValue) ? autocompleteValue : [];
                              const newValue = target.value.trim();
                              if (!currentValues.includes(newValue)) {
                                handleFieldChange(field.name, [...currentValues, newValue]);
                                // Clear the input
                                setTimeout(() => {
                                  if (target) target.value = '';
                                }, 0);
                              }
                            }
                          }
                        }}
                        renderInput={(params) => (
                          <TextField
                            {...params}
                            fullWidth
                            label={field.label}
                            placeholder={field.placeholder || "選擇或輸入物料編號"}
                            sx={currentReport.id === 'rep-005' ? {
                              '& .MuiOutlinedInput-root': {
                                minHeight: '64px',
                                fontSize: '1rem'
                              },
                              '& .MuiInputLabel-root': {
                                fontSize: '1rem'
                              }
                            } : {}}
                          />
                        )}
                        renderTags={(value, getTagProps) =>
                          value.map((option, index) => {
                            // Find the label for the option if it exists in options
                            const optionObj = options.find(opt => opt.value === option);
                            const displayLabel = optionObj ? optionObj.label : String(option);
                            return (
                              <Chip
                                variant="outlined"
                                label={displayLabel}
                                {...getTagProps({ index })}
                                key={`${option}-${index}`}
                              />
                            );
                          })
                        }
                        getOptionLabel={(option) => {
                          // Find the label for the option if it exists in options
                          const optionObj = options.find(opt => opt.value === option);
                          return optionObj ? optionObj.label : String(option);
                        }}
                      />
                    </Grid>
                  );
                }

                // Regular TextField for other fields
                return (
                  <Grid item {...gridSize} key={field.name}>
                  <TextField
                    fullWidth
                    label={field.label}
                    type={field.type}
                    placeholder={field.placeholder}
                    disabled={disabledByCheckedCheckbox || disabledRep012Status}
                    InputLabelProps={field.type === 'date' ? { shrink: true } : {}}
                      sx={currentReport.id === 'rep-005' ? {
                        '& .MuiOutlinedInput-root': {
                          minHeight: '64px',
                          fontSize: '1rem'
                        },
                        '& .MuiInputLabel-root': {
                          fontSize: '1rem'
                        }
                      } : {}}
                      onChange={(e) => {
                        if (field.multiple) {
                          const value = typeof e.target.value === 'string' 
                            ? e.target.value.split(',')
                            : e.target.value;
                          
                          // Special handling for stockCategory
                          if (field.name === 'stockCategory' && Array.isArray(value)) {
                            const currentValues = (criteria[field.name] || '').split(',').map(v => v.trim()).filter(v => v);
                            const newValues = value.map(v => String(v).trim()).filter(v => v);
                            
                            const wasOnlyAll = currentValues.length === 1 && currentValues[0] === 'All';
                            const hasAll = newValues.includes('All');
                            const hasOthers = newValues.some(v => v !== 'All');
                            
                            if (hasAll && hasOthers) {
                              // User selected "All" along with other options
                              // If previously only "All" was selected, user is trying to switch - remove "All" and keep others
                              if (wasOnlyAll) {
                                const filteredValue = newValues.filter(v => v !== 'All');
                                handleFieldChange(field.name, filteredValue);
                              } else {
                                // User added "All" to existing selections - keep only "All"
                                handleFieldChange(field.name, ['All']);
                              }
                            } else if (hasAll && !hasOthers) {
                              // Only "All" is selected
                              handleFieldChange(field.name, ['All']);
                            } else if (!hasAll && hasOthers) {
                              // Other options selected without "All"
                              handleFieldChange(field.name, newValues);
                            } else {
                              // Empty selection
                              handleFieldChange(field.name, []);
                            }
                          } else {
                            handleFieldChange(field.name, value);
                          }
                        } else {
                          handleFieldChange(field.name, e.target.value);
                        }
                      }}
                      value={valueForSelect}
                    select={field.type === 'select'}
                      SelectProps={field.multiple ? {
                        multiple: true,
                        renderValue: (selected: any) => {
                          if (Array.isArray(selected)) {
                            return selected
                              .map((v) => {
                                const opt = options.find((o) => o.value === v);
                                return opt?.label ?? String(v);
                              })
                              .join(', ');
                          }
                          return selected;
                        }
                      } : {}}
                  >
                      {field.type === 'select' && options.map((opt) => (
                      <MenuItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </MenuItem>
                    ))}
                  </TextField>
                </Grid>
                );
              })}
            </Grid>

            <Box sx={{ mt: 4, display: 'flex', gap: 2, justifyContent: 'flex-end' }}>
              {currentReport.id === 'rep-005' ? (
                <SemiFGProductionAnalysisReport
                  criteria={criteria}
                  requiredFieldLabels={currentReport.fields.filter(f => f.required && !criteria[f.name]).map(f => f.label)}
                  loading={loading}
                  setLoading={setLoading}
                  reportTitle={currentReport.title}
                  onExportSuccess={(format) => {
                    logFeatureUsage(
                      FEATURE_USAGE.REPORT_MANAGEMENT,
                      FEATURE_USAGE_ACTION.DOWNLOAD,
                      `${currentReport.id}:${format}`,
                    );
                  }}
                />
              ) : currentReport.id === 'rep-013' || currentReport.id === 'rep-009' || currentReport.id === 'rep-012' || currentReport.id === 'rep-004' || currentReport.id === 'rep-007' || currentReport.id === 'rep-008' || currentReport.id === 'rep-011' ? (
                <>
                  <Button
                    variant="contained"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handlePrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 PDF..." : "下載報告 (PDF)"}
                  </Button>
                  <Button
                    variant="outlined"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handleExcelPrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 Excel..." : "下載報告 (Excel)"}
                  </Button>
                </>
              ) : currentReport.id === 'rep-006' ? (
                <>
                  <Button
                    variant="contained"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handlePrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 PDF..." : "下載報告 (PDF)"}
                  </Button>
                  <Button
                    variant="outlined"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handleExcelPrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 Excel..." : "下載報告 (Excel)"}
                  </Button>
                </>
              ) : currentReport.id === 'rep-010' ? (
                <>
                  <Button
                    variant="contained"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handlePrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 PDF..." : "下載報告 (PDF)"}
                  </Button>
                  <Button
                    variant="outlined"
                    size="large"
                    startIcon={<DownloadIcon />}
                    onClick={handleExcelPrint}
                    disabled={loading}
                    sx={{ px: 4 }}
                  >
                    {loading ? "生成 Excel..." : "下載報告 (Excel)"}
                  </Button>
                </>
              ) : currentReport.responseType === 'excel' ? (
                <Button
                  variant="contained"
                  size="large"
                  startIcon={<DownloadIcon />}
                  onClick={handlePrint}
                  disabled={loading}
                  sx={{ px: 4 }}
                >
                  {loading ? "生成 Excel..." : "下載報告 (Excel)"}
                </Button>
              ) : (
                <Button
                  variant="contained"
                  size="large"
                  startIcon={<DownloadIcon />}
                  onClick={handlePrint}
                  disabled={loading}
                  sx={{ px: 4 }}
                >
                  {loading ? "生成報告..." : "下載報告 (PDF)"}
                </Button>
              )}
            </Box>
          </CardContent>
        </Card>
      )}
    </Box>
  );
}