const Country = require('../models/Country')
const Division = require('../models/Division')
const District = require('../models/District')
const Thana = require('../models/Thana')
const { validationResult } = require('express-validator')

class LocationController {
  // --- Countries ---

  static async getCountries(req, res, next) {
    try {
      const { page, limit, search, include_inactive } = req.query
      const result = await Country.findAll({ page, limit, search, include_inactive })
      res.status(200).json({ 
        status: 'success', 
        data: result.countries,
        pagination: {
          total: result.total,
          page: parseInt(page) || 1,
          limit: parseInt(limit) || 50
        }
      })
    } catch (error) {
      next(error)
    }
  }

  static async getCountryById(req, res, next) {
    try {
      const country = await Country.findById(req.params.id)
      if (!country) return res.status(404).json({ status: 'error', message: 'Country not found' })
      res.status(200).json({ status: 'success', data: country })
    } catch (error) {
      next(error)
    }
  }

  static async createCountry(req, res, next) {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(400).json({ status: 'error', errors: errors.array() })
      
      const id = await Country.create(req.body)
      const country = await Country.findById(id)
      res.status(201).json({ status: 'success', message: 'Country created', data: country })
    } catch (error) {
      next(error)
    }
  }

  static async updateCountry(req, res, next) {
    try {
      const success = await Country.update(req.params.id, req.body)
      if (!success) return res.status(404).json({ status: 'error', message: 'Country not found or no changes' })
      const country = await Country.findById(req.params.id)
      res.status(200).json({ status: 'success', message: 'Country updated', data: country })
    } catch (error) {
      next(error)
    }
  }

  static async deleteCountry(req, res, next) {
    try {
      const success = await Country.delete(req.params.id)
      if (!success) return res.status(404).json({ status: 'error', message: 'Country not found' })
      res.status(200).json({ status: 'success', message: 'Country deleted' })
    } catch (error) {
      next(error)
    }
  }

  // --- Divisions ---

  static async getDivisions(req, res, next) {
    try {
      const { page, limit, search, country_id, include_inactive } = req.query
      const result = await Division.findAll({ page, limit, search, country_id, include_inactive })
      res.status(200).json({ 
        status: 'success', 
        data: result.divisions,
        pagination: {
          total: result.total,
          page: parseInt(page) || 1,
          limit: parseInt(limit) || 50
        }
      })
    } catch (error) {
      next(error)
    }
  }

  // Get divisions by country ID (for cascading dropdowns)
  static async getDivisionsByCountry(req, res, next) {
    try {
      const { country_id } = req.params
      const divisions = await Division.findByCountryId(country_id)
      res.status(200).json({ status: 'success', data: divisions })
    } catch (error) {
      next(error)
    }
  }

  static async getDivisionById(req, res, next) {
    try {
      const division = await Division.findById(req.params.id)
      if (!division) return res.status(404).json({ status: 'error', message: 'Division not found' })
      res.status(200).json({ status: 'success', data: division })
    } catch (error) {
      next(error)
    }
  }

  static async createDivision(req, res, next) {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(400).json({ status: 'error', errors: errors.array() })
      
      const id = await Division.create(req.body)
      const division = await Division.findById(id)
      res.status(201).json({ status: 'success', message: 'Division created', data: division })
    } catch (error) {
      next(error)
    }
  }

  static async updateDivision(req, res, next) {
    try {
      const success = await Division.update(req.params.id, req.body)
      if (!success) return res.status(404).json({ status: 'error', message: 'Division not found or no changes' })
      const division = await Division.findById(req.params.id)
      res.status(200).json({ status: 'success', message: 'Division updated', data: division })
    } catch (error) {
      next(error)
    }
  }

  static async deleteDivision(req, res, next) {
    try {
      const success = await Division.delete(req.params.id)
      if (!success) return res.status(404).json({ status: 'error', message: 'Division not found' })
      res.status(200).json({ status: 'success', message: 'Division deleted' })
    } catch (error) {
      next(error)
    }
  }

  // --- Districts ---

  static async getDistricts(req, res, next) {
    try {
      const { page, limit, search, division_id, include_inactive } = req.query
      const result = await District.findAll({ page, limit, search, division_id, include_inactive })
      // District.findAll returns { districts, total }
      res.status(200).json({ 
        status: 'success', 
        data: result.districts, 
        pagination: {
          total: result.total,
          page: parseInt(page) || 1,
          limit: parseInt(limit) || 50
        }
      })
    } catch (error) {
      next(error)
    }
  }

  static async getDistrictById(req, res, next) {
    try {
      const district = await District.findById(req.params.id)
      if (!district) return res.status(404).json({ status: 'error', message: 'District not found' })
      res.status(200).json({ status: 'success', data: district })
    } catch (error) {
      next(error)
    }
  }

  static async createDistrict(req, res, next) {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(400).json({ status: 'error', errors: errors.array() })
      
      const id = await District.create(req.body)
      const district = await District.findById(id)
      res.status(201).json({ status: 'success', message: 'District created', data: district })
    } catch (error) {
      next(error)
    }
  }

  static async updateDistrict(req, res, next) {
    try {
      const success = await District.update(req.params.id, req.body)
      if (!success) return res.status(404).json({ status: 'error', message: 'District not found or no changes' })
      const district = await District.findById(req.params.id)
      res.status(200).json({ status: 'success', message: 'District updated', data: district })
    } catch (error) {
      next(error)
    }
  }

  static async deleteDistrict(req, res, next) {
    try {
      const success = await District.delete(req.params.id)
      if (!success) return res.status(404).json({ status: 'error', message: 'District not found' })
      res.status(200).json({ status: 'success', message: 'District deleted' })
    } catch (error) {
      next(error)
    }
  }

  // Get districts by division ID (for cascading dropdowns)
  static async getDistrictsByDivision(req, res, next) {
    try {
      const { division_id } = req.params
      const districts = await District.findByDivisionId(division_id)
      res.status(200).json({ status: 'success', data: districts })
    } catch (error) {
      next(error)
    }
  }

  // --- Thanas ---

  static async getThanas(req, res, next) {
    try {
      const { page, limit, search, district_id, include_inactive } = req.query
      const result = await Thana.findAll({ page, limit, search, district_id, include_inactive })
      res.status(200).json({ 
        status: 'success', 
        data: result.thanas,
        pagination: {
          total: result.total,
          page: parseInt(page) || 1,
          limit: parseInt(limit) || 50
        }
      })
    } catch (error) {
      next(error)
    }
  }

  static async getThanaById(req, res, next) {
    try {
      const thana = await Thana.findById(req.params.id)
      if (!thana) return res.status(404).json({ status: 'error', message: 'Thana not found' })
      res.status(200).json({ status: 'success', data: thana })
    } catch (error) {
      next(error)
    }
  }

  static async createThana(req, res, next) {
    try {
      const errors = validationResult(req)
      if (!errors.isEmpty()) return res.status(400).json({ status: 'error', errors: errors.array() })
      
      const id = await Thana.create(req.body)
      const thana = await Thana.findById(id)
      res.status(201).json({ status: 'success', message: 'Thana created', data: thana })
    } catch (error) {
      next(error)
    }
  }

  static async updateThana(req, res, next) {
    try {
      const success = await Thana.update(req.params.id, req.body)
      if (!success) return res.status(404).json({ status: 'error', message: 'Thana not found or no changes' })
      const thana = await Thana.findById(req.params.id)
      res.status(200).json({ status: 'success', message: 'Thana updated', data: thana })
    } catch (error) {
      next(error)
    }
  }

  static async deleteThana(req, res, next) {
    try {
      const success = await Thana.delete(req.params.id)
      if (!success) return res.status(404).json({ status: 'error', message: 'Thana not found' })
      res.status(200).json({ status: 'success', message: 'Thana deleted' })
    } catch (error) {
      next(error)
    }
  }

  // Get thanas by district ID (for cascading dropdowns)
  static async getThanasByDistrict(req, res, next) {
    try {
      const { district_id } = req.params
      const thanas = await Thana.findByDistrictId(district_id)
      res.status(200).json({ status: 'success', data: thanas })
    } catch (error) {
      next(error)
    }
  }
}

module.exports = LocationController
