import React, { useRef, useState, useEffect, useMemo, memo } from "react";
import {
    Card,
    Col,
    Container,
    Row, Button, Form,
    InputGroup,
} from "react-bootstrap";

import { Head, router, useForm } from "@inertiajs/react";
import 'react-bootstrap-typeahead/css/Typeahead.css';
import { FileText, Save, User, Landmark } from "lucide-react";
import { Cliente } from "../../../interfaces";
import BreadCrumb from "../../../Components/Common/BreadCrumb";
import FormDateInputEs from "../../../Components/Common/FormDateInputEs";
import { calendarYmdFromServer, todayLocalYmd } from "../../../utils/serverCalendarDate";
import Layout from "../../../Layouts";
import Swal from 'sweetalert2';
import axios from 'axios';
import { Typeahead } from 'react-bootstrap-typeahead';
import { Localidad } from "../Contratos/Interfaces/Interfaces";
import { useLoading } from '../../../LoadingContext';
import { refreshClientes } from '../../../services/dataService';
import estilosFoco from '../Contratos/Shared/estilosFocoAccesible.module.css';
import { programarEnfoqueCampoFormulario } from '../Contratos/utils/validacionFormulario';
import { EneonTabs } from '../Shared/Tabs';
import type { EneonTabDefinition } from '../Shared/Tabs';

const FormWizard = ({cliente}: { cliente: Cliente }) => {
  const [activeTab, setActiveTab] = useState<'basicos' | 'fiscales'>('basicos');
  const printRef = useRef<HTMLDivElement>(null);

  const [formErrors, setFormErrors] = useState<{ [key: string]: string }>({});
  const [showErrors, setShowErrors] = useState(false);
  const [disabled, setDisabled] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);
  const [isFormValid, setIsFormValid] = useState(true);
  const { showLoading, hideLoading } = useLoading();

  const handleBack = () => {
    showLoading();
    router.visit(route('clientes.index'), {
      onFinish: () => hideLoading()
    });
  };

  // Memoizar función para mejor rendimiento
  const getSelectedTypeaheadValue = useMemo(() => 
    (options: any[], value: string, labelKey: string) => {
      if (value && options.length > 0) {
          const found = options.find(opt => opt[labelKey] === value);
          return found ? [found] : [];
      }
      return [];
    }, []
  );

  const initialFecIniCli = (cliente as any)?.FecIniCli
    ? calendarYmdFromServer(String((cliente as any).FecIniCli))
    : (cliente as any)?.CodCli
      ? ''
      : todayLocalYmd();

  const { data, setData, post, put, processing, errors, clearErrors } = useForm<any>({
    RazSocCli: cliente.RazSocCli,
    NomComCli: cliente.NomComCli,
    NumCifCli: cliente.NumCifCli,
    TelFijCli: cliente.TelFijCli,
    TelMovCli: cliente.TelMovCli,
    EmaCli: cliente.EmaCli,
    EmaCliOpc: (cliente as any)?.EmaCliOpc,
    WebCli: (cliente as any)?.WebCli,
    EstCli: (cliente as any)?.EstCli,
    FecIniCli: initialFecIniCli,
    CodTipCli: (cliente as any)?.CodTipCli,
    CodSecCli: (cliente as any)?.CodSecCli,
    CodCom: (cliente as any)?.CodCom,
    CodCol: (cliente as any)?.CodCol,
    CPLocFis: (cliente as any)?.CPLocFis || null,
    CodLocFis: (cliente as any)?.CodLocFis || null,
    CodTipViaFis: (cliente as any)?.CodTipViaFis,
    NomViaDomFis: (cliente as any)?.NomViaDomFis,
    NumViaDomFis: (cliente as any)?.NumViaDomFis,
    BloDomFis: (cliente as any)?.BloDomFis,
    EscDomFis: (cliente as any)?.EscDomFis,
    PlaDomFis: (cliente as any)?.PlaDomFis,
    PueDomFis: (cliente as any)?.PueDomFis,
    CPLocSoc: cliente.CPLocSoc,
    CodLocSoc: (cliente as any)?.CodLocSoc,
    CodTipViaSoc: (cliente as any)?.CodTipViaSoc,
    NomViaDomSoc: cliente.NomViaDomSoc,
    NumViaDomSoc: cliente.NumViaDomSoc,
    BloDomSoc: (cliente as any)?.BloDomSoc,
    EscDomSoc: (cliente as any)?.EscDomSoc,
    PlaDomSoc: (cliente as any)?.PlaDomSoc,
    PueDomSoc: (cliente as any)?.PueDomSoc,
    CodTipViaSocText: '', // helpers UI (no se envían)
    CodTipViaFisText: '',
    ObsCli: (cliente as any)?.ObsCli,
    DireccionBBDD: (cliente as any)?.DireccionBBDD,
    numeroCuenta: (cliente as any)?.numeroCuenta,
    localidad: (cliente as any)?.localidad?.DesLoc || '',
    provincia: (cliente as any)?.localidad?.provincia?.DesPro || '',
  });

  // Opciones y dependientes
  const [tiposVia, setTiposVia] = useState<{ CodTipVia: number; DesTipVia: string; IniTipVia: string }[]>([]);
  
  const initialProvinciaId = (cliente as any)?.localidad?.provincia?.CodPro || '';
  const [provincias, setProvincias] = useState<any[]>([]);
  const [localidadesPorProvincia, setLocalidadesPorProvincia] = useState<any[]>([]);
  const [selectedProvinciaId, setSelectedProvinciaId] = useState<number | ''>(initialProvinciaId);

  useEffect(() => {
    axios.get(route('tipo-via.listar') as unknown as string)
      .then(res => {
        const data = res.data?.data || [];
        // Filtrar duplicados basándose en CodTipVia
        const uniqueTiposVia = data.filter((tv: any, index: number, self: any[]) =>
          index === self.findIndex((t) => t.CodTipVia === tv.CodTipVia)
        );
        setTiposVia(uniqueTiposVia);
      })
      .catch(() => {});

    axios.get(route('provincias.listar') as unknown as string)
      .then(res => {
        setProvincias(res.data?.data || []);
      })
      .catch(() => {});
  }, []);

  useEffect(() => {
    if (selectedProvinciaId) {
      axios.get(route('provincias.clave', selectedProvinciaId) as unknown as string)
        .then(res => {
          setLocalidadesPorProvincia(res.data?.data?.localidades || []);
        })
        .catch(() => {});
    } else {
      setLocalidadesPorProvincia([]);
    }
  }, [selectedProvinciaId]);


  const isCreate = !(cliente as any)?.CodCli;

  console.log(data);
  const handleTextChange = (field: string) => (
    e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    setData(field, e.target.value);
    if ((errors as any)?.[field]) {
      clearErrors(field);
    }
  };

  const handleSelectChange = (field: string, parser?: (value: string) => any) => (
    e: React.ChangeEvent<HTMLSelectElement>
  ) => {
    const value = parser ? parser(e.target.value) : e.target.value;
    setData(field, value);
    if ((errors as any)?.[field]) {
      clearErrors(field);
    }
  };

  const basicFields = [
    'NumCifCli',
    'RazSocCli',
    'NomComCli',
    'FecIniCli',
    'EstCli',
    'TelFijCli',
    'TelMovCli',
    'EmaCli',
    'EmaCliOpc',
    'WebCli',
    'ObsCli',
    'CodTipCli',
    'CodSecCli',
    'CodCom',
    'CodCol',
  ];

  const fiscalFields = [
    'CodTipViaFis',
    'NomViaDomFis',
    'NumViaDomFis',
    'BloDomFis',
    'EscDomFis',
    'PlaDomFis',
    'PueDomFis',
    'CodLocFis',
    'CPLocFis',
  ];

  useEffect(() => {
    const keys = Object.keys(errors || {});
    if (!keys.length) return;
    const hasBasic = keys.some((key) => basicFields.includes(key));
    const hasFiscal = keys.some((key) => fiscalFields.includes(key));

    if (activeTab === 'basicos' && !hasBasic && hasFiscal) {
      setActiveTab('fiscales');
    }
    if (activeTab === 'fiscales' && !hasFiscal && hasBasic) {
      setActiveTab('basicos');
    }

    programarEnfoqueCampoFormulario(keys[0]);
  }, [errors, activeTab]);

  const tabsCliente: EneonTabDefinition[] = [
    {
      id: 'basicos',
      label: 'Datos básicos',
      icon: <User size={20} />,
      variant: 'default',
      panelId: 'panel-cliente-basicos',
    },
    {
      id: 'fiscales',
      label: 'Datos fiscales',
      icon: <Landmark size={20} />,
      variant: 'default',
      panelId: 'panel-cliente-fiscales',
    },
  ];

  const guardar = () => {

    Swal.fire({
      title: isCreate ? 'Crear cliente' : 'Guardar cambios',
      text: isCreate ? `¿Deseas crear el cliente ${data.RazSocCli || '(sin nombre)'}?` : `¿Deseas guardar los cambios del cliente ${data.RazSocCli}?`,
      icon: 'question',
      showCancelButton: true,
      confirmButtonText: isCreate ? 'Sí, crear' : 'Sí, guardar',
      cancelButtonText: 'Cancelar'
    }).then(result => {
      if (result.isConfirmed) {
        setIsProcessing(true);
        showLoading();

        if (isCreate) {
          post(route('clientes.store'), {
          preserveScroll: false,
          onFinish: () => {
            setIsProcessing(false);
            hideLoading();
          },
          onSuccess: (page) => {
            // Invalidar caché frontend
            refreshClientes().catch(console.error);

            const flash: any = (page as any).props?.flash || {};
            const title = flash.message || flash.error || 'Creado';
            const icon = flash.type || (flash.error ? 'error' : 'success');
            Swal.fire({ title, icon, timer: 1500, showConfirmButton: false });
          },
          onError: () => {
            Swal.fire({ title: 'Error al crear', icon: 'error', timer: 1500, showConfirmButton: false });
          }
          });
        } else {
          put(route('clientes.update', (cliente as any).CodCli), {
            preserveScroll: false,
            onFinish: () => {
              setIsProcessing(false);
              hideLoading();
            },
            onSuccess: (page) => {
              // Invalidar caché frontend
              refreshClientes().catch(console.error);
              
              const flash: any = (page as any).props?.flash || {};
              const title = flash.message || flash.error || 'Actualizado';
              const icon = flash.type || (flash.error ? 'error' : 'success');
              Swal.fire({ title, icon, timer: 1500, showConfirmButton: false });
            },
            onError: () => {
              Swal.fire({ title: 'Error al guardar', icon: 'error', timer: 1500, showConfirmButton: false });
            }
          });
        }
      }
    });
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    guardar();
  };


  return (
    <React.Fragment>
  <Head title={`${isCreate ? 'Crear' : 'Editar'} Cliente${cliente?.RazSocCli ? `: ${cliente.RazSocCli}` : ''}`} />
      <div className="page-content">
        <Container fluid>
          <BreadCrumb title={isCreate ? "Crear" : "Editar"} pageTitle="Cliente" />
          <Row>
            <Col xl={12}>
              <Card>
                <Card.Header className="d-flex justify-content-between align-items-center bg-light">
                  <h4 className="card-title mb-0">{isCreate ? 'Nuevo Cliente' : `Cliente: ${cliente.NumCifCli || ''}`}</h4>
                  <div className="d-flex gap-2">
                    <Button
                      variant="success"
                      size="sm"
                      onClick={handleSubmit}
                      disabled={disabled || isProcessing || !isFormValid}
                    >
                      <i className="fas fa-save me-2"></i>
                      Guardar
                    </Button>
                    <Button
                      variant="secondary"
                      size="sm"
                      onClick={handleBack}
                    >
                      <FileText size={14} className="me-1" />
                      Volver
                    </Button>
                  </div>
                </Card.Header>
                <Card.Body>
                  <div className={`${estilosFoco.contenedorAccesibleContratos} formularioCliente`}>
                  <Form onSubmit={handleSubmit}>
                    <EneonTabs
                      tabs={tabsCliente}
                      activeTabId={activeTab}
                      onTabChange={(tabId) => setActiveTab(tabId as 'basicos' | 'fiscales')}
                      ariaLabel="Secciones del cliente"
                      className="mb-3"
                    />

                    {activeTab === 'basicos' && (
                      <Row className="g-4" id="panel-cliente-basicos" role="tabpanel" aria-labelledby="tab-cliente-basicos">
                        <Col xs={12}><h5 className="mb-2">Datos básicos del cliente</h5></Col>
                        <Col md={4}>
                          <Form.Group controlId="NumCifCli">
                            <Form.Label>NIF/CIF</Form.Label>
                            <Form.Control value={data.NumCifCli || ''} onChange={handleTextChange('NumCifCli')} isInvalid={!!errors.NumCifCli} />
                            <Form.Control.Feedback type="invalid">{errors.NumCifCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={4}>
                          <Form.Group controlId="RazSocCli">
                            <Form.Label>Razón Social</Form.Label>
                            <Form.Control value={data.RazSocCli || ''} onChange={handleTextChange('RazSocCli')} isInvalid={!!errors.RazSocCli} />
                            <Form.Control.Feedback type="invalid">{errors.RazSocCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>

                        <Col md={4}>
                          <Form.Group controlId="FecIniCli">
                            <Form.Label>Fecha Inicio</Form.Label>
                            <FormDateInputEs
                              id="FecIniCli"
                              value={data.FecIniCli || ''}
                              onChange={(iso) => {
                                setData('FecIniCli', iso);
                                if ((errors as any)?.FecIniCli) {
                                  clearErrors('FecIniCli');
                                }
                              }}
                              isInvalid={!!errors.FecIniCli}
                            />
                            <Form.Control.Feedback type="invalid">{errors.FecIniCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={4}>
                          <Form.Group controlId="EstCli">
                            <Form.Label>Estado</Form.Label>
                            <Form.Select value={data.EstCli ?? ''} onChange={handleSelectChange('EstCli', (value) => (value === '' ? undefined : parseInt(value)))} isInvalid={!!errors.EstCli}>
                              <option value="">Seleccione…</option>
                              <option value="1">Activo</option>
                              <option value="0">Inactivo</option>
                            </Form.Select>
                            <Form.Control.Feedback type="invalid">{errors.EstCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={4}>
                          <Form.Group controlId="TelFijCli">
                            <Form.Label>Teléfono fijo</Form.Label>
                            <Form.Control value={data.TelFijCli || ''} onChange={handleTextChange('TelFijCli')} isInvalid={!!errors.TelFijCli} />
                            <Form.Control.Feedback type="invalid">{errors.TelFijCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={4}>
                          <Form.Group controlId="TelMovCli">
                            <Form.Label>Móvil</Form.Label>
                            <Form.Control value={data.TelMovCli || ''} onChange={handleTextChange('TelMovCli')} isInvalid={!!errors.TelMovCli} />
                            <Form.Control.Feedback type="invalid">{errors.TelMovCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={6}>
                          <Form.Group controlId="EmaCli">
                            <Form.Label>Email</Form.Label>
                            <Form.Control type="email" value={data.EmaCli || ''} onChange={handleTextChange('EmaCli')} isInvalid={!!errors.EmaCli} />
                            <Form.Control.Feedback type="invalid">{errors.EmaCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={6}>
                          <Form.Group controlId="EmaCliOpc">
                            <Form.Label>Email alterno</Form.Label>
                            <Form.Control type="email" value={data.EmaCliOpc || ''} onChange={handleTextChange('EmaCliOpc')} isInvalid={!!errors.EmaCliOpc} />
                            <Form.Control.Feedback type="invalid">{errors.EmaCliOpc as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={6}>
                          <Form.Group controlId="WebCli">
                            <Form.Label>Web</Form.Label>
                            <Form.Control value={data.WebCli || ''} onChange={handleTextChange('WebCli')} isInvalid={!!errors.WebCli} />
                            <Form.Control.Feedback type="invalid">{errors.WebCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={6}>
                          <Form.Group controlId="ObsCli">
                            <Form.Label>Observaciones</Form.Label>
                            <Form.Control as="textarea" rows={3} value={data.ObsCli || ''} onChange={handleTextChange('ObsCli')} isInvalid={!!errors.ObsCli} />
                            <Form.Control.Feedback type="invalid">{errors.ObsCli as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                      </Row>
                    )}

                    {activeTab === 'fiscales' && (
                      <Row className="g-4" id="panel-cliente-fiscales" role="tabpanel" aria-labelledby="tab-cliente-fiscales">
                        <Col xs={12}><h5 className="mb-2">Datos fiscales</h5></Col>
                        <Col md={4}>
                          <Form.Group controlId="CodTipViaFis">
                            <Form.Label>Tipo de Vía</Form.Label>
                            <Form.Select value={data.CodTipViaFis || ''} onChange={handleSelectChange('CodTipViaFis', (value) => (value ? parseInt(value) : undefined))} isInvalid={!!errors.CodTipViaFis}>
                              <option value="">Seleccione…</option>
                              {tiposVia.map(tv => (
                                <option key={tv.CodTipVia} value={tv.CodTipVia}>{tv.DesTipVia}</option>
                              ))}
                            </Form.Select>
                            <Form.Control.Feedback type="invalid">{errors.CodTipViaFis as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={5}>
                          <Form.Group controlId="NomViaDomFis">
                            <Form.Label>Nombre de la vía</Form.Label>
                            <Form.Control value={data.NomViaDomFis || ''} onChange={handleTextChange('NomViaDomFis')} isInvalid={!!errors.NomViaDomFis} />
                            <Form.Control.Feedback type="invalid">{errors.NomViaDomFis as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={3}>
                          <Form.Group controlId="NumViaDomFis">
                            <Form.Label>Número</Form.Label>
                            <Form.Control value={data.NumViaDomFis || ''} onChange={handleTextChange('NumViaDomFis')} isInvalid={!!errors.NumViaDomFis} />
                            <Form.Control.Feedback type="invalid">{errors.NumViaDomFis as any}</Form.Control.Feedback>
                          </Form.Group>
                        </Col>
                        <Col md={3}><Form.Group controlId="BloDomFis"><Form.Label>Bloque</Form.Label><Form.Control maxLength={3} value={data.BloDomFis || ''} onChange={handleTextChange('BloDomFis')} isInvalid={!!errors.BloDomFis} /><Form.Control.Feedback type="invalid">{errors.BloDomFis as any}</Form.Control.Feedback></Form.Group></Col>
                        <Col md={3}><Form.Group controlId="EscDomFis"><Form.Label>Escalera</Form.Label><Form.Control value={data.EscDomFis || ''} onChange={handleTextChange('EscDomFis')} isInvalid={!!errors.EscDomFis} /><Form.Control.Feedback type="invalid">{errors.EscDomFis as any}</Form.Control.Feedback></Form.Group></Col>
                        <Col md={3}><Form.Group controlId="PlaDomFis"><Form.Label>Piso</Form.Label><Form.Control value={data.PlaDomFis || ''} onChange={handleTextChange('PlaDomFis')} isInvalid={!!errors.PlaDomFis} /><Form.Control.Feedback type="invalid">{errors.PlaDomFis as any}</Form.Control.Feedback></Form.Group></Col>
                        <Col md={3}><Form.Group controlId="PueDomFis"><Form.Label>Puerta</Form.Label><Form.Control value={data.PueDomFis || ''} onChange={handleTextChange('PueDomFis')} isInvalid={!!errors.PueDomFis} /><Form.Control.Feedback type="invalid">{errors.PueDomFis as any}</Form.Control.Feedback></Form.Group></Col>
                      {/* Provincia */}
                      <Col lg={4} md={12} sm={12}>
                          <Form.Group controlId="provincia1">
                            <Form.Label>Provincia</Form.Label>
                            <Form.Select
                              value={selectedProvinciaId}
                              onChange={(e) => {
                                const pId = e.target.value ? parseInt(e.target.value) : '';
                                setSelectedProvinciaId(pId);
                                setData((prev: any) => ({
                                  ...prev,
                                  CodLocFis: '',
                                  CPLocFis: '',
                                  localidad: '',
                                  provincia: e.target.options[e.target.selectedIndex].text !== 'Seleccione…' ? e.target.options[e.target.selectedIndex].text : ''
                                }));
                              }}
                            >
                              <option value="">Seleccione…</option>
                              {provincias.map(p => (
                                <option key={p.CodPro} value={p.CodPro}>{p.DesPro}</option>
                              ))}
                            </Form.Select>
                            <Form.Control.Feedback type="invalid">
                                {formErrors.provincia}
                            </Form.Control.Feedback>
                          </Form.Group>
                      </Col>

                      {/* Localidad */}
                      <Col lg={5} md={6} sm={12}>
                          <Form.Group controlId="localidad1">
                            <Form.Label>Localidad</Form.Label>
                            <Form.Select
                              value={data.CodLocFis || ''}
                              disabled={!selectedProvinciaId}
                              onChange={(e) => {
                                const lId = e.target.value ? parseInt(e.target.value) : '';
                                if (!lId) {
                                  setData((prev: any) => ({
                                    ...prev,
                                    CodLocFis: '',
                                    CPLocFis: '',
                                    localidad: ''
                                  }));
                                  return;
                                }
                                const loc = localidadesPorProvincia.find((l: any) => l.CodLoc === lId);
                                if (loc) {
                                  setData((prev: any) => ({
                                    ...prev,
                                    CodLocFis: loc.CodLoc,
                                    CPLocFis: loc.CPLoc,
                                    localidad: loc.DesLoc
                                  }));
                                  clearErrors('CodLocFis');
                                  clearErrors('CPLocFis');
                                }
                              }}
                              isInvalid={!!errors.CodLocFis || (showErrors && !!formErrors.localidad)}
                            >
                              <option value="">{selectedProvinciaId ? 'Seleccione…' : 'Seleccione una provincia primero'}</option>
                              {localidadesPorProvincia.map((l: any) => (
                                <option key={l.CodLoc} value={l.CodLoc}>{l.DesLoc}</option>
                              ))}
                            </Form.Select>
                            <Form.Control.Feedback type="invalid">
                                {(errors.CodLocFis as string) || formErrors.localidad}
                            </Form.Control.Feedback>
                          </Form.Group>
                      </Col>

                      {/* Código Postal */}
                      <Col lg={3} md={6} sm={12}>
                          <Form.Group controlId="codigoPostal1">
                            <Form.Label>Código Postal</Form.Label>
                            <Form.Control
                                type="text"
                                value={data.CPLocFis || ''}
                                disabled
                                placeholder="Código Postal"
                                isInvalid={!!errors.CPLocFis || (showErrors && !!formErrors.CPLocFis)}
                            />
                            <Form.Control.Feedback type="invalid">
                              {(errors.CPLocFis as string) || formErrors.CPLocFis}
                            </Form.Control.Feedback>
                          </Form.Group>
                      </Col>
                      </Row>
                    )}
                  </Form>
                  </div>
                </Card.Body>
              </Card>
            </Col>
          </Row>
        </Container>
      </div>
    </React.Fragment>
  );
};

FormWizard.layout = (page: any) => <Layout children={page} />;
export default FormWizard;
